diff --git a/packages/react-scripts/config/paths.js b/packages/react-scripts/config/paths.js index abd9f72865a..7d114080f7c 100644 --- a/packages/react-scripts/config/paths.js +++ b/packages/react-scripts/config/paths.js @@ -43,6 +43,17 @@ var nodePaths = (process.env.NODE_PATH || '') var envPublicUrl = process.env.PUBLIC_URL; +function ensureSlash(path, needsSlash) { + var hasSlash = path.endsWith('/'); + if (hasSlash && !needsSlash) { + return path.substr(path, path.length - 1); + } else if (!hasSlash && needsSlash) { + return path + '/'; + } else { + return path; + } +} + function getPublicUrl(appPackageJson) { return envPublicUrl || require(appPackageJson).homepage; } @@ -55,12 +66,10 @@ function getPublicUrl(appPackageJson) { // like /todos/42/static/js/bundle.7289d.js. We have to know the root. function getServedPath(appPackageJson) { var publicUrl = getPublicUrl(appPackageJson); - if (!publicUrl) { - return '/'; - } else if (envPublicUrl) { - return publicUrl; - } - return url.parse(publicUrl).pathname; + var servedUrl = envPublicUrl || ( + publicUrl ? url.parse(publicUrl).pathname : '/' + ); + return ensureSlash(servedUrl, true); } // config after eject: we're in ./config/ diff --git a/packages/react-scripts/config/utils/ensureSlash.js b/packages/react-scripts/config/utils/ensureSlash.js deleted file mode 100644 index f4382384f7e..00000000000 --- a/packages/react-scripts/config/utils/ensureSlash.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = function ensureSlash(path, needsSlash) { - var hasSlash = path.endsWith('/'); - if (hasSlash && !needsSlash) { - return path.substr(path, path.length - 1); - } else if (!hasSlash && needsSlash) { - return path + '/'; - } else { - return path; - } -} diff --git a/packages/react-scripts/config/webpack.config.dev.js b/packages/react-scripts/config/webpack.config.dev.js index 94ce7c26ce2..2548c620884 100644 --- a/packages/react-scripts/config/webpack.config.dev.js +++ b/packages/react-scripts/config/webpack.config.dev.js @@ -15,7 +15,6 @@ var HtmlWebpackPlugin = require('html-webpack-plugin'); var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); -var ensureSlash = require('./utils/ensureSlash'); var getClientEnvironment = require('./env'); var paths = require('./paths'); @@ -30,7 +29,7 @@ var publicPath = '/'; // `publicUrl` is just like `publicPath`, but we will provide it to our app // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. // Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz. -var publicUrl = ensureSlash(paths.servedPath, false); +var publicUrl = ''; // Get environment variables to inject into our app. var env = getClientEnvironment(publicUrl); @@ -116,7 +115,7 @@ module.exports = { // ** ADDING/UPDATING LOADERS ** // The "url" loader handles all assets unless explicitly excluded. // The `exclude` list *must* be updated with every change to loader extensions. - // When adding a new loader, you must add its `test` + // When adding a new loader, you must add its `test` // as a new entry in the `exclude` list for "url" loader. // "url" loader embeds assets smaller than specified size as data URLs to avoid requests. diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index ed7683534cf..053eca67e87 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -16,7 +16,6 @@ var ExtractTextPlugin = require('extract-text-webpack-plugin'); var ManifestPlugin = require('webpack-manifest-plugin'); var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); var url = require('url'); -var ensureSlash = require('./utils/ensureSlash'); var paths = require('./paths'); var getClientEnvironment = require('./env'); @@ -27,11 +26,11 @@ var path = require('path'); // Webpack uses `publicPath` to determine where the app is being served from. // It requires a trailing slash, or the file assets will get an incorrect path. -var publicPath = ensureSlash(paths.servedPath, true); +var publicPath = paths.servedPath; // `publicUrl` is just like `publicPath`, but we will provide it to our app // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. // Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz. -var publicUrl = ensureSlash(paths.servedPath, false); +var publicUrl = publicPath.slice(0, -1); // Get environment variables to inject into our app. var env = getClientEnvironment(publicUrl); @@ -106,7 +105,7 @@ module.exports = { // ** ADDING/UPDATING LOADERS ** // The "url" loader handles all assets unless explicitly excluded. // The `exclude` list *must* be updated with every change to loader extensions. - // When adding a new loader, you must add its `test` + // When adding a new loader, you must add its `test` // as a new entry in the `exclude` list in the "url" loader. // "url" loader embeds assets smaller than specified size as data URLs to avoid requests. diff --git a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js index 414229b22ac..e7b3afe42ed 100644 --- a/packages/react-scripts/fixtures/kitchensink/integration/env.test.js +++ b/packages/react-scripts/fixtures/kitchensink/integration/env.test.js @@ -18,9 +18,10 @@ describe('Integration', () => { it('PUBLIC_URL', async () => { const doc = await initDOM('public-url') - expect(doc.getElementById('feature-public-url').textContent).to.equal('http://www.example.org/spa.') + const prefix = process.env.NODE_ENV === 'development' ? '' : 'http://www.example.org/spa'; + expect(doc.getElementById('feature-public-url').textContent).to.equal(`${prefix}.`) expect(doc.querySelector('head link[rel="shortcut icon"]').getAttribute('href')) - .to.equal('http://www.example.org/spa/favicon.ico') + .to.equal(`${prefix}/favicon.ico`) }) it('shell env variables', async () => { diff --git a/packages/react-scripts/scripts/eject.js b/packages/react-scripts/scripts/eject.js index daa5958e9f9..b8f9d313143 100644 --- a/packages/react-scripts/scripts/eject.js +++ b/packages/react-scripts/scripts/eject.js @@ -43,6 +43,12 @@ prompt( } } + var folders = [ + 'config', + path.join('config', 'jest'), + 'scripts' + ]; + var files = [ path.join('config', 'env.js'), path.join('config', 'paths.js'), @@ -51,20 +57,11 @@ prompt( path.join('config', 'webpack.config.prod.js'), path.join('config', 'jest', 'cssTransform.js'), path.join('config', 'jest', 'fileTransform.js'), - path.join('config', 'utils', 'ensureSlash.js'), path.join('scripts', 'build.js'), path.join('scripts', 'start.js'), - path.join('scripts', 'test.js'), + path.join('scripts', 'test.js') ]; - var folders = files.reduce(function(prevFolders, file) { - var dirname = path.dirname(file); - if (prevFolders.indexOf(dirname) === -1) { - return prevFolders.concat(dirname); - } - return prevFolders; - }, []); - // Ensure that the app folder is clean and we won't override any files folders.forEach(verifyAbsent); files.forEach(verifyAbsent); diff --git a/tasks/e2e-kitchensink.sh b/tasks/e2e-kitchensink.sh index 4d27b70d6a4..3c750feca53 100755 --- a/tasks/e2e-kitchensink.sh +++ b/tasks/e2e-kitchensink.sh @@ -135,7 +135,6 @@ tmp_server_log=`mktemp` PORT=3001 \ REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ NODE_PATH=src \ - PUBLIC_URL=http://www.example.org/spa/ \ nohup npm start &>$tmp_server_log & grep -q 'The app is running at:' <(tail -f $tmp_server_log) E2E_URL="http://localhost:3001" \ @@ -193,7 +192,6 @@ tmp_server_log=`mktemp` PORT=3002 \ REACT_APP_SHELL_ENV_MESSAGE=fromtheshell \ NODE_PATH=src \ - PUBLIC_URL=http://www.example.org/spa/ \ nohup npm start &>$tmp_server_log & grep -q 'The app is running at:' <(tail -f $tmp_server_log) E2E_URL="http://localhost:3002" \