From 42026a01f79cee4fe1a38e386b2f93e4dac344db Mon Sep 17 00:00:00 2001 From: Joe Haddad Date: Fri, 28 Sep 2018 23:03:48 -0400 Subject: [PATCH] Correctly lookup assets when using a relative build directory (#5163) * Correctly lookup assets when using a relative build directory * Hah, var ... * Add e2e test for relative paths * Format svg --- fixtures/smoke/relative-paths/index.test.js | 37 +++++++++++++++++++ fixtures/smoke/relative-paths/package.json | 6 +++ .../smoke/relative-paths/public/index.html | 9 +++++ fixtures/smoke/relative-paths/src/index.css | 8 ++++ fixtures/smoke/relative-paths/src/index.js | 1 + fixtures/smoke/relative-paths/src/logo.svg | 8 ++++ package.json | 1 + .../config/webpack.config.prod.js | 11 +++++- 8 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 fixtures/smoke/relative-paths/index.test.js create mode 100644 fixtures/smoke/relative-paths/package.json create mode 100644 fixtures/smoke/relative-paths/public/index.html create mode 100644 fixtures/smoke/relative-paths/src/index.css create mode 100644 fixtures/smoke/relative-paths/src/index.js create mode 100644 fixtures/smoke/relative-paths/src/logo.svg diff --git a/fixtures/smoke/relative-paths/index.test.js b/fixtures/smoke/relative-paths/index.test.js new file mode 100644 index 00000000..1f367f64 --- /dev/null +++ b/fixtures/smoke/relative-paths/index.test.js @@ -0,0 +1,37 @@ +const fs = require('fs-extra'); +const globby = require('globby'); +const path = require('path'); +const { + bootstrap, + isSuccessfulDevelopment, + isSuccessfulProduction, +} = require('../../utils'); +beforeEach(async () => { + await bootstrap({ directory: global.testDirectory, template: __dirname }); +}); + +describe('relative paths', () => { + // TODO: enable when development relative paths are supported + xit('builds in development', async () => { + await isSuccessfulDevelopment({ directory: global.testDirectory }); + }); + it('builds in production', async () => { + await isSuccessfulProduction({ directory: global.testDirectory }); + + const buildDir = path.join(global.testDirectory, 'build'); + const cssFile = path.join( + buildDir, + globby.sync('**/*.css', { cwd: buildDir }).pop() + ); + const svgFile = path.join( + buildDir, + globby.sync('**/*.svg', { cwd: buildDir }).pop() + ); + const desiredPath = /url\((.+?)\)/ + .exec(fs.readFileSync(cssFile, 'utf8')) + .pop(); + expect(path.resolve(path.join(path.dirname(cssFile), desiredPath))).toBe( + path.resolve(svgFile) + ); + }); +}); diff --git a/fixtures/smoke/relative-paths/package.json b/fixtures/smoke/relative-paths/package.json new file mode 100644 index 00000000..3ed0e3e4 --- /dev/null +++ b/fixtures/smoke/relative-paths/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "react-scripts": "latest" + }, + "homepage": "." +} diff --git a/fixtures/smoke/relative-paths/public/index.html b/fixtures/smoke/relative-paths/public/index.html new file mode 100644 index 00000000..86010b24 --- /dev/null +++ b/fixtures/smoke/relative-paths/public/index.html @@ -0,0 +1,9 @@ + + + + React App + + +
+ + diff --git a/fixtures/smoke/relative-paths/src/index.css b/fixtures/smoke/relative-paths/src/index.css new file mode 100644 index 00000000..244889b1 --- /dev/null +++ b/fixtures/smoke/relative-paths/src/index.css @@ -0,0 +1,8 @@ +.RootSvg:before { + display: block; + content: ' '; + background-image: url(./logo.svg); + background-size: 28px 28px; + height: 28px; + width: 28px; +} diff --git a/fixtures/smoke/relative-paths/src/index.js b/fixtures/smoke/relative-paths/src/index.js new file mode 100644 index 00000000..6a9a4b13 --- /dev/null +++ b/fixtures/smoke/relative-paths/src/index.js @@ -0,0 +1 @@ +import './index.css'; diff --git a/fixtures/smoke/relative-paths/src/logo.svg b/fixtures/smoke/relative-paths/src/logo.svg new file mode 100644 index 00000000..5e531566 --- /dev/null +++ b/fixtures/smoke/relative-paths/src/logo.svg @@ -0,0 +1,8 @@ + + + + + + + diff --git a/package.json b/package.json index 5acfc3a2..96d63b4f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "execa": "1.0.0", "fs-extra": "^7.0.0", "get-port": "^4.0.0", + "globby": "^8.0.1", "husky": "1.0.0-rc.15", "jest": "^23.6.0", "lerna": "2.9.1", diff --git a/packages/react-scripts/config/webpack.config.prod.js b/packages/react-scripts/config/webpack.config.prod.js index 0defc5f4..2c830fd8 100644 --- a/packages/react-scripts/config/webpack.config.prod.js +++ b/packages/react-scripts/config/webpack.config.prod.js @@ -28,6 +28,9 @@ const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier'); // 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. const publicPath = paths.servedPath; +// Some apps do not use client-side routing with pushState. +// For these, "homepage" can be set to "." to enable relative asset paths. +const shouldUseRelativeAssetPaths = publicPath === './'; // Source maps are resource heavy and can cause out of memory issue for large source files. const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; // `publicUrl` is just like `publicPath`, but we will provide it to our app @@ -52,7 +55,13 @@ const sassModuleRegex = /\.module\.(scss|sass)$/; // common function to get style loaders const getStyleLoaders = (cssOptions, preProcessor) => { const loaders = [ - MiniCssExtractPlugin.loader, + { + loader: MiniCssExtractPlugin.loader, + options: Object.assign( + {}, + shouldUseRelativeAssetPaths ? { publicPath: '../../' } : undefined + ), + }, { loader: require.resolve('css-loader'), options: cssOptions,