facebook/create-react-app

Is there a way to remove first "/" from resources url?

thevishnupradeep opened this issue ยท 15 comments

I am trying to build an electron app. I am simply pointing electron api to the build folder. But the issue is I am getting the error failed to load file:///.... error. If I understand correctly, this is because of the extra slash at the beginning of the resource links.

I just want to change links in html and other files from "/static/js/main.2a85c832.js" to "static/js/main.2a85c832.js"?
Could anyone help? Thanks

We don't currently support this, the main reason being it's a footgun for apps with client-side routing. For example, people visiting http://myapp.com/todos/42 still want to load http://myapp.com/static/js/main.123.js, not http://myapp.com/todos/42/static/js/main.123.js.

However there are valid use cases such as if you don't use client-side routing, or if you build an Electron or Cordova app. Weโ€™ll need to address this in a future release.

As a temporary hack I think you you should be able to set homepage: "" in your package.json and it will partially work. But I think something related to how Webpack handles files was broken. So weโ€™ll need to fix this.

well, my problem was fixed when I edited two lines of code in webpack.config.prod.js:
from: var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/';
to: var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '';
&
from: var publicPath = ensureSlash(homepagePathname, true);
to: var publicPath = homepagePathname;

But I am sure this is not a solution. What if we look for an "environment" option in "package.json"? If required developers can specify whether it's for web or another framework like electron?

@thevishnupradeep This works as a temporary fix but if I recall correctly it breaks other things. Iโ€™m not sure which approach exactly we will take, so Iโ€™m keeping it open.

@gaearon @thevishnupradeep I would love your thoughts on this as a possible solution:
Issue: #1095
PR: #1096

Here is what I have for my startupScript parameter inside package.json:

  "homepage": "./",
  "startScript": "./dev.js",

dev.js looks like this:

var electron = require('electron');
var proc = require('child_process');

process.env.LOAD_URL = process.env.DEV_URL;

var child = proc.spawn(electron, ['./public/main.js'], {stdio: 'inherit'});
child.on('close', function (code) {
  process.exit(code);
});

./public/main.js take directly from this example: https://github.com/electron/electron-quick-start/blob/master/main.js

With this change:

  // and load the index.html of the app.
  let loadUrl = url.format({
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  })
  if (process.env.LOAD_URL) {
    loadUrl = process.env.LOAD_URL;
  }
  mainWindow.loadURL(loadUrl);

@license2e @gaearon That works! didn't add child_process part. Just "homepage": "./", was enough. There is only one issue remaining, fonts! Even in css, the url is prepended with "/". But I think it should be something like "../media/...". Is there a solution for this?

@thevishnupradeep I am having exactly the same issue with an electron app at the moment. Adding "homepage": "./" to package.json solves the path issue but breaks client site routing... I am going back to @chentsulin's electron-react-boilerplate for now. It works great and forces you to accept just as much magic as create-react-app does ;-)

Adding "homepage": "./" to package.json solves the path issue but breaks client site routing

If you have a suggestion for how to avoid this problem but support client-side routing Iโ€™d love to know it. Itโ€™s not obvious to me.

FWIW I use ./ as the homepage for Cordova apps and have my CSS resources (fonts, etc.) stored in /public and referenced in index.html using %PUBLIC_URL%. Works perfectly. I then create a symbolic link from build -> www and Cordova is happy. I'll do pretty much anything to avoid ejecting!

Another possible workaround for now is to write a post-build step that replaces /static/ with ./static/ in all files in build folder.

"homepage:" "./" is also working for me for a non react-router application, "homepage:" "" didn't work as create-react-app assumes that means loading from root.

Now looking too on getting this set up work with react-router apps.

So I'm also trying to use CRA with Cordova and I just messed around with this, and react-router can work if you use hashHistory rather than browserHistory. (I also implemented the homepage: ./ as well when I tested it).

*Unfortunately I need to use a login redirect which receives an access token, and they do not accept fragments (#) as the redirect url.....

Although there may be other interesting solutions to this here: remix-run/react-router#2161

Timer commented

Hi there! react-scripts v0.9.0 was just released which adds support for building for relative paths. You may read how to do so here.

This should address majority of concerns, but this issue will remain open as it is for a broader topic (doing so while keeping client side routing).

I'd like to close this since the original discussion is no longer relevant ("homepage": "." works for the Electron use case). We can open a new issue to discuss different semantics and how this fits with client side routing, if somebody has any suggestions. Thanks!

I know this is closed, but:

After coming back to this and using react-router-dom's HashRouter in addition to the "homepage" : "./" trick, client side routing just works in my recent electron app. I've created this barebones electron-create-react-app boilerplate, just in case someone stumbles upon this and wants to have a look...

The solution that I found it was in path config/path.js I only changed
envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
to
envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : './');