From d7f6e29bf50cb6eedf14bed603f4ebf2ae6222ed Mon Sep 17 00:00:00 2001 From: Luca Battistini Date: Tue, 9 Aug 2022 10:20:22 +0200 Subject: [PATCH 01/11] feat(webpack): svg loader rules have been updated --- .../docs/adding-images-fonts-and-files.md | 9 ++-- package-lock.json | 50 +++++-------------- .../index.test.js | 26 +++++----- .../react-scripts/config/webpack.config.js | 43 ++++++++-------- .../src/features/webpack/SvgComponent.js | 2 +- packages/react-scripts/lib/react-app.d.ts | 13 ++--- 6 files changed, 62 insertions(+), 81 deletions(-) diff --git a/docusaurus/docs/adding-images-fonts-and-files.md b/docusaurus/docs/adding-images-fonts-and-files.md index 67cc4b53d22..c76ff5401e3 100644 --- a/docusaurus/docs/adding-images-fonts-and-files.md +++ b/docusaurus/docs/adding-images-fonts-and-files.md @@ -47,21 +47,24 @@ An alternative way of handling static assets is described in the next section. > Note: this feature is available with `react-scripts@2.0.0` and higher, and `react@16.3.0` and higher. -One way to add SVG files was described in the section above. You can also import SVGs directly as React components. You can use either of the two approaches. In your code it would look like this: +One way to add SVG files was described in the section above, but you need to add `?url` as query string to import it as URL. You can also import SVGs directly as React components. You can use either of the two approaches. In your code it would look like this: ```js -import { ReactComponent as Logo } from './logo.svg'; +import Logo from './logo.svg'; +import logo from './logo.svg?url'; function App() { return (
{/* Logo is an actual React component */} + {/* logo as url */} + logo
); } ``` -This is handy if you don't want to load SVG as a separate file. Don't forget the curly braces in the import! The `ReactComponent` import name is significant and tells Create React App that you want a React component that renders an SVG, rather than its filename. +This is handy if you don't want to load SVG as a separate file. > **Tip:** The imported SVG React Component accepts a `title` prop along with other props that a `svg` element accepts. Use this prop to add an accessible title to your svg component. diff --git a/package-lock.json b/package-lock.json index ea5b4f049f7..d485380fcc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29793,21 +29793,21 @@ } }, "packages/cra-template": { - "version": "1.1.3", + "version": "1.2.0", "license": "MIT", "engines": { "node": ">=14" } }, "packages/cra-template-typescript": { - "version": "1.1.3", + "version": "1.2.0", "license": "MIT", "engines": { "node": ">=14" } }, "packages/create-react-app": { - "version": "5.0.0", + "version": "5.0.1", "license": "MIT", "dependencies": { "chalk": "^4.1.2", @@ -29848,7 +29848,7 @@ } }, "packages/eslint-config-react-app": { - "version": "7.0.0", + "version": "7.0.1", "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", @@ -29889,7 +29889,7 @@ } }, "packages/react-dev-utils": { - "version": "12.0.0", + "version": "12.0.1", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.16.0", @@ -29911,7 +29911,7 @@ "open": "^8.4.0", "pkg-up": "^3.1.0", "prompts": "^2.4.2", - "react-error-overlay": "^6.0.10", + "react-error-overlay": "^6.0.11", "recursive-readdir": "^2.2.2", "shell-quote": "^1.7.3", "strip-ansi": "^6.0.1", @@ -29934,7 +29934,7 @@ } }, "packages/react-error-overlay": { - "version": "6.0.10", + "version": "6.0.11", "license": "MIT", "devDependencies": { "@babel/code-frame": "^7.16.0", @@ -29946,17 +29946,6 @@ "chalk": "^4.1.2", "chokidar": "^3.5.2", "cross-env": "^7.0.3", - "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.0", -<<<<<<< HEAD -======= -======= -<<<<<<< HEAD ->>>>>>> f21e2137 (Publish) -======= ->>>>>>> 9f8d75e5 (chore(lint): lint all files) ->>>>>>> fb003998 (chore(lint): lint all files) ->>>>>>> f301bfe4 (chore(lint): lint all files) "flow-bin": "^0.116.0", "html-entities": "^2.3.2", "jest": "^27.4.3", @@ -29983,7 +29972,7 @@ } }, "packages/react-scripts": { - "version": "5.0.0", + "version": "5.0.1", "license": "MIT", "dependencies": { "@babel/core": "^7.16.0", @@ -30002,7 +29991,7 @@ "dotenv": "^10.0.0", "dotenv-expand": "^5.1.0", "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.0", + "eslint-config-react-app": "^7.0.1", "eslint-webpack-plugin": "^3.1.1", "file-loader": "^6.2.0", "fs-extra": "^10.0.0", @@ -30019,7 +30008,7 @@ "postcss-preset-env": "^7.0.1", "prompts": "^2.4.2", "react-app-polyfill": "^3.0.0", - "react-dev-utils": "^12.0.0", + "react-dev-utils": "^12.0.1", "react-refresh": "^0.11.0", "resolve": "^1.20.0", "resolve-url-loader": "^4.0.0", @@ -47301,7 +47290,7 @@ "open": "^8.4.0", "pkg-up": "^3.1.0", "prompts": "^2.4.2", - "react-error-overlay": "^6.0.10", + "react-error-overlay": "^6.0.11", "recursive-readdir": "^2.2.2", "shell-quote": "^1.7.3", "strip-ansi": "^6.0.1", @@ -47337,19 +47326,6 @@ "chalk": "^4.1.2", "chokidar": "^3.5.2", "cross-env": "^7.0.3", -<<<<<<< HEAD - "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.0", -======= -<<<<<<< HEAD -======= -<<<<<<< HEAD - "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.0", -======= ->>>>>>> 9f8d75e5 (chore(lint): lint all files) ->>>>>>> fb003998 (chore(lint): lint all files) ->>>>>>> f301bfe4 (chore(lint): lint all files) "flow-bin": "^0.116.0", "html-entities": "^2.3.2", "jest": "^27.4.3", @@ -47506,7 +47482,7 @@ "dotenv": "^10.0.0", "dotenv-expand": "^5.1.0", "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.0", + "eslint-config-react-app": "^7.0.1", "eslint-webpack-plugin": "^3.1.1", "file-loader": "^6.2.0", "fs-extra": "^10.0.0", @@ -47525,7 +47501,7 @@ "prompts": "^2.4.2", "react": "^18.0.0", "react-app-polyfill": "^3.0.0", - "react-dev-utils": "^12.0.0", + "react-dev-utils": "^12.0.1", "react-dom": "^18.0.0", "react-refresh": "^0.11.0", "resolve": "^1.20.0", diff --git a/packages/babel-plugin-named-asset-import/index.test.js b/packages/babel-plugin-named-asset-import/index.test.js index fff2c28894e..14b4e61c8bd 100644 --- a/packages/babel-plugin-named-asset-import/index.test.js +++ b/packages/babel-plugin-named-asset-import/index.test.js @@ -36,16 +36,16 @@ pluginTester.default({ output: 'import { logo } from "logo.svg";', }, svgReactComponentNamedImport: { - code: 'import { ReactComponent as logo } from "logo.svg";', - output: - 'import { ReactComponent as logo } from "@svgr/webpack?-svgo!logo.svg";', + code: 'import Logo from "logo.svg";', + output: 'import Logo from "@svgr/webpack?-svgo!logo.svg";', }, svgMultipleImport: { - code: 'import logo, { logoUrl , ReactComponent as Logo } from "logo.svg";', + code: + 'import logoUrl from "logo.svg?url";\n' + + 'import Logo from "logo.svg";', output: - 'import logo from "logo.svg";\n' + - 'import { logoUrl } from "logo.svg";\n' + - 'import { ReactComponent as Logo } from "@svgr/webpack?-svgo!logo.svg";', + 'import logoUrl from "logo.svg?url";\n' + + 'import Logo from "@svgr/webpack?-svgo!logo.svg";', }, defaultExport: { code: 'export default logo;', @@ -80,19 +80,19 @@ pluginTester.default({ output: 'export * from "logo.svg";', }, svgReactComponentNamedExport: { - code: 'export { ReactComponent as Logo } from "logo.svg";', - output: - 'export { ReactComponent as Logo } from "@svgr/webpack?-svgo!logo.svg";', + code: 'export Logo from "logo.svg";', + output: 'export Logo from "@svgr/webpack?-svgo!logo.svg";', }, svgReactComponentExport: { code: 'export { ReactComponent } from "logo.svg";', output: 'export { ReactComponent } from "@svgr/webpack?-svgo!logo.svg";', }, svgMultipleExport: { - code: 'export { logoUrl , ReactComponent as Logo } from "logo.svg";', + code: + 'export logoUrl from "logo.svg?url";' + 'export Logo from "logo.svg";', output: - 'export { logoUrl } from "logo.svg";\n' + - 'export { ReactComponent as Logo } from "@svgr/webpack?-svgo!logo.svg";', + 'export logoUrl from "logo.svg?url";\n' + + 'export Logo from "@svgr/webpack?-svgo!logo.svg";', }, }, }); diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js index e465d8e7a00..e0b5751caa4 100644 --- a/packages/react-scripts/config/webpack.config.js +++ b/packages/react-scripts/config/webpack.config.js @@ -386,30 +386,31 @@ module.exports = function (webpackEnv) { }, }, { - test: /\.svg$/, - use: [ - { - loader: require.resolve('@svgr/webpack'), - options: { - prettier: false, - svgo: false, - svgoConfig: { - plugins: [{ removeViewBox: false }], - }, - titleProp: true, - ref: true, - }, - }, - { - loader: require.resolve('file-loader'), - options: { - name: 'static/media/[name].[hash].[ext]', - }, - }, - ], + test: /\.svg$/i, + issuer: { + and: [/\.(ts|tsx|js|jsx|md|mdx)$/], + }, + type: 'asset', + resourceQuery: /url/, // *.svg?url + }, + { + test: /\.svg$/i, issuer: { and: [/\.(ts|tsx|js|jsx|md|mdx)$/], }, + resourceQuery: { not: [/url/] }, // exclude react component if *.svg?url + use: { + loader: require.resolve('@svgr/webpack'), + options: { + prettier: false, + svgo: false, + svgoConfig: { + plugins: [{ removeViewBox: false }], + }, + titleProp: true, + ref: true, + }, + }, }, // Process application JS with Babel. // The preset includes JSX, Flow, TypeScript, and some ESnext features. diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.js index d7d6dafeb33..16e5e89ad6a 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.js @@ -6,7 +6,7 @@ */ import React from 'react'; -import { ReactComponent as Logo } from './assets/logo.svg'; +import Logo from './assets/logo.svg'; const SvgComponent = () => { return ; diff --git a/packages/react-scripts/lib/react-app.d.ts b/packages/react-scripts/lib/react-app.d.ts index 780c321229c..b17fa8a2c20 100644 --- a/packages/react-scripts/lib/react-app.d.ts +++ b/packages/react-scripts/lib/react-app.d.ts @@ -44,15 +44,16 @@ declare module '*.webp' { export default src; } -declare module '*.svg' { - import * as React from 'react'; +declare module '*.svg?url' { + const content: string; + export default content; +} - export const ReactComponent: React.FunctionComponent< +declare module '*.svg' { + const ReactComponent: React.FunctionComponent< React.SVGProps & { title?: string } >; - - const src: string; - export default src; + export default ReactComponent; } declare module '*.module.css' { From f8ba43cfd47da78d3f4009a695f23231db87d187 Mon Sep 17 00:00:00 2001 From: Luca Battistini Date: Tue, 9 Aug 2022 16:10:36 +0200 Subject: [PATCH 02/11] fix(test): named import and export have been handled --- .../index.test.js | 25 ++++++++++--------- .../template/src/App.tsx | 4 +-- packages/cra-template/template/src/App.js | 4 +-- .../src/features/webpack/SvgInclusion.js | 2 +- .../src/features/webpack/assets/svg.css | 2 +- .../src/index.scss | 2 +- test/fixtures/relative-paths/src/index.css | 2 +- 7 files changed, 21 insertions(+), 20 deletions(-) diff --git a/packages/babel-plugin-named-asset-import/index.test.js b/packages/babel-plugin-named-asset-import/index.test.js index 14b4e61c8bd..55e96acefa0 100644 --- a/packages/babel-plugin-named-asset-import/index.test.js +++ b/packages/babel-plugin-named-asset-import/index.test.js @@ -8,7 +8,7 @@ pluginTester.default({ pluginOptions: { loaderMap: { svg: { - ReactComponent: '@svgr/webpack?-svgo![path]', + ReactComponent: '[path]', }, }, }, @@ -28,16 +28,16 @@ pluginTester.default({ output: 'import { Url as logo1 } from "logo";', }, svgDefaultImport: { - code: 'import logo from "logo.svg";', - output: 'import logo from "logo.svg";', + code: 'import Logo from "logo.svg";', + output: 'import Logo from "logo.svg";', }, svgNamedImport: { code: 'import { logo } from "logo.svg";', output: 'import { logo } from "logo.svg";', }, svgReactComponentNamedImport: { - code: 'import Logo from "logo.svg";', - output: 'import Logo from "@svgr/webpack?-svgo!logo.svg";', + code: 'import { ReactComponent as Logo } from "logo.svg";', + output: 'import { ReactComponent as Logo } from "logo.svg";', }, svgMultipleImport: { code: @@ -45,7 +45,7 @@ pluginTester.default({ 'import Logo from "logo.svg";', output: 'import logoUrl from "logo.svg?url";\n' + - 'import Logo from "@svgr/webpack?-svgo!logo.svg";', + 'import Logo from "logo.svg";', }, defaultExport: { code: 'export default logo;', @@ -80,19 +80,20 @@ pluginTester.default({ output: 'export * from "logo.svg";', }, svgReactComponentNamedExport: { - code: 'export Logo from "logo.svg";', - output: 'export Logo from "@svgr/webpack?-svgo!logo.svg";', + code: 'export { ReactComponent as Logo } from "logo.svg";', + output: 'export { ReactComponent as Logo } from "logo.svg";', }, svgReactComponentExport: { code: 'export { ReactComponent } from "logo.svg";', - output: 'export { ReactComponent } from "@svgr/webpack?-svgo!logo.svg";', + output: 'export { ReactComponent } from "logo.svg";', }, svgMultipleExport: { code: - 'export logoUrl from "logo.svg?url";' + 'export Logo from "logo.svg";', + 'export { logoUrl } from "logo.svg?url";\n' + + 'export { ReactComponent as Logo } from "logo.svg";', output: - 'export logoUrl from "logo.svg?url";\n' + - 'export Logo from "@svgr/webpack?-svgo!logo.svg";', + 'export { logoUrl } from "logo.svg?url";\n' + + 'export { ReactComponent as Logo } from "logo.svg";', }, }, }); diff --git a/packages/cra-template-typescript/template/src/App.tsx b/packages/cra-template-typescript/template/src/App.tsx index a53698aab3c..94c986a3c93 100644 --- a/packages/cra-template-typescript/template/src/App.tsx +++ b/packages/cra-template-typescript/template/src/App.tsx @@ -1,12 +1,12 @@ import React from 'react'; -import logo from './logo.svg'; +import Logo from './logo.svg'; import './App.css'; function App() { return (
- logo +

Edit src/App.tsx and save to reload.

diff --git a/packages/cra-template/template/src/App.js b/packages/cra-template/template/src/App.js index 37845757234..f8e04508180 100644 --- a/packages/cra-template/template/src/App.js +++ b/packages/cra-template/template/src/App.js @@ -1,11 +1,11 @@ -import logo from './logo.svg'; +import Logo from './logo.svg'; import './App.css'; function App() { return (
- logo +

Edit src/App.js and save to reload.

diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js index 7ef580c0103..b12075c7352 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js @@ -6,7 +6,7 @@ */ import React from 'react'; -import logo from './assets/logo.svg'; +import logo from './assets/?url'; const SvgInclusion = () => ( logo diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/assets/svg.css b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/assets/svg.css index 383743f4bfe..a7e9ccf14e0 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/assets/svg.css +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/assets/svg.css @@ -1,3 +1,3 @@ #feature-svg-in-css { - background-image: url('./logo.svg'); + background-image: url('./logo.svg?url'); } diff --git a/test/fixtures/global-scss-asset-resolution/src/index.scss b/test/fixtures/global-scss-asset-resolution/src/index.scss index 81ade6705a1..6c0d8dfde53 100644 --- a/test/fixtures/global-scss-asset-resolution/src/index.scss +++ b/test/fixtures/global-scss-asset-resolution/src/index.scss @@ -1,5 +1,5 @@ #root { width: 300px; height: 300px; - background: url(/images/logo.svg) center/cover no-repeat; + background: url(/images/logo.svg?url) center/cover no-repeat; } diff --git a/test/fixtures/relative-paths/src/index.css b/test/fixtures/relative-paths/src/index.css index 244889b10aa..d48acce9e84 100644 --- a/test/fixtures/relative-paths/src/index.css +++ b/test/fixtures/relative-paths/src/index.css @@ -1,7 +1,7 @@ .RootSvg:before { display: block; content: ' '; - background-image: url(./logo.svg); + background-image: url(./logo.svg?url); background-size: 28px 28px; height: 28px; width: 28px; From fe38ccf6ed69562688e1593e7529c348026b5087 Mon Sep 17 00:00:00 2001 From: Luca Battistini Date: Tue, 9 Aug 2022 16:21:19 +0200 Subject: [PATCH 03/11] fix(scripts): e2e-simple.sh has been updated --- tasks/e2e-simple.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tasks/e2e-simple.sh b/tasks/e2e-simple.sh index d2858f0715f..e4727d2889b 100755 --- a/tasks/e2e-simple.sh +++ b/tasks/e2e-simple.sh @@ -102,7 +102,7 @@ npm run build exists build/*.html exists build/static/js/*.js exists build/static/css/*.css -exists build/static/media/*.svg +# TODO: 'exists build/static/media/*.svg' if size higher than IMAGE_INLINE_SIZE_LIMIT exists build/favicon.ico # Run tests with CI flag @@ -210,7 +210,7 @@ npm run build exists build/*.html exists build/static/js/*.js exists build/static/css/*.css -exists build/static/media/*.svg +# TODO: 'exists build/static/media/*.svg' if size higher than IMAGE_INLINE_SIZE_LIMIT exists build/favicon.ico # Run tests with CI flag @@ -243,7 +243,7 @@ npm run build exists build/*.html exists build/static/js/*.js exists build/static/css/*.css -exists build/static/media/*.svg +# TODO: 'exists build/static/media/*.svg' if size higher than IMAGE_INLINE_SIZE_LIMIT exists build/favicon.ico # Run tests, overriding the watch option to disable it. From 04c95c31e90be90791321c7427683c143c77810c Mon Sep 17 00:00:00 2001 From: Luca Battistini Date: Tue, 9 Aug 2022 16:34:06 +0200 Subject: [PATCH 04/11] fix(kitchensink): SVgInclusion.js has been properly updated --- .../kitchensink/template/src/features/webpack/SvgInclusion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js index b12075c7352..88de1dc3e06 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js @@ -6,7 +6,7 @@ */ import React from 'react'; -import logo from './assets/?url'; +import logo from './assets/logo.svg?url'; const SvgInclusion = () => ( logo From 92bff687c7aad0e9d263d3b53080ea1f12fc786f Mon Sep 17 00:00:00 2001 From: Luca Battistini Date: Tue, 9 Aug 2022 18:02:01 +0200 Subject: [PATCH 05/11] fix(tests): react-scripts integrations tests have been updated --- packages/react-scripts/config/jest/fileTransform.js | 1 + .../template/src/features/webpack/SvgComponent.test.js | 4 ++-- .../kitchensink/template/src/features/webpack/SvgInclusion.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/react-scripts/config/jest/fileTransform.js b/packages/react-scripts/config/jest/fileTransform.js index aab67618c38..7a3a0014b25 100644 --- a/packages/react-scripts/config/jest/fileTransform.js +++ b/packages/react-scripts/config/jest/fileTransform.js @@ -11,6 +11,7 @@ module.exports = { const assetFilename = JSON.stringify(path.basename(filename)); if (filename.match(/\.svg$/)) { + // TODO: handle svg files with '?url' query string // Based on how SVGR generates a component name: // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6 const pascalCaseFilename = camelcase(path.parse(filename).name, { diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js index 493a6bc87ba..70ad9bd4c98 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js @@ -13,14 +13,14 @@ describe('svg component', () => { it('renders without crashing', () => { const div = document.createElement('div'); ReactDOM.render(, div); - expect(div.textContent).toBe('logo.svg'); + expect(div.innerHTML).toBe(''); }); it('svg root element equals the passed ref', () => { const div = document.createElement('div'); const someRef = React.createRef(); ReactDOM.render(, div); - const svgElement = div.getElementsByTagName('svg'); + const svgElement = div.getElementsByTagName('logo.svg'); expect(svgElement).toHaveLength(1); expect(svgElement[0]).toBe(someRef.current); }); diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js index 88de1dc3e06..7ef580c0103 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js @@ -6,7 +6,7 @@ */ import React from 'react'; -import logo from './assets/logo.svg?url'; +import logo from './assets/logo.svg'; const SvgInclusion = () => ( logo From c4adb0a3796f36040cc2a3f35ee350909d51a404 Mon Sep 17 00:00:00 2001 From: Luca Battistini Date: Tue, 9 Aug 2022 18:12:46 +0200 Subject: [PATCH 06/11] fix(tests): SvgComponent missing id --- .../template/src/features/webpack/SvgComponent.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js index 70ad9bd4c98..19811ef5d75 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js @@ -13,7 +13,9 @@ describe('svg component', () => { it('renders without crashing', () => { const div = document.createElement('div'); ReactDOM.render(, div); - expect(div.innerHTML).toBe(''); + expect(div.innerHTML).toBe( + '' + ); }); it('svg root element equals the passed ref', () => { From 70e4380b57a85d2cbdb105c07e61552d9884808c Mon Sep 17 00:00:00 2001 From: Luca Battistini Date: Tue, 9 Aug 2022 18:24:54 +0200 Subject: [PATCH 07/11] fix(test): trying to fix SvgInclusion --- .../kitchensink/template/src/features/webpack/SvgInclusion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js index 7ef580c0103..88de1dc3e06 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js @@ -6,7 +6,7 @@ */ import React from 'react'; -import logo from './assets/logo.svg'; +import logo from './assets/logo.svg?url'; const SvgInclusion = () => ( logo From 288a61e040fb64e57fa7f3327da53601d86455a1 Mon Sep 17 00:00:00 2001 From: lucabattistini Date: Tue, 9 Aug 2022 23:23:25 +0200 Subject: [PATCH 08/11] test: import svg as url --- packages/react-scripts/config/jest/fileTransform.js | 10 +++++++--- .../kitchensink/template/integration/webpack.test.js | 4 ++-- .../template/src/features/webpack/SvgComponent.test.js | 4 ++-- .../react-scripts/scripts/utils/createJestConfig.js | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/react-scripts/config/jest/fileTransform.js b/packages/react-scripts/config/jest/fileTransform.js index 7a3a0014b25..9b9057b5940 100644 --- a/packages/react-scripts/config/jest/fileTransform.js +++ b/packages/react-scripts/config/jest/fileTransform.js @@ -11,17 +11,21 @@ module.exports = { const assetFilename = JSON.stringify(path.basename(filename)); if (filename.match(/\.svg$/)) { - // TODO: handle svg files with '?url' query string + + if (filename.endsWith('?url')) { + return `./${assetFilename};`; + } + // Based on how SVGR generates a component name: // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6 const pascalCaseFilename = camelcase(path.parse(filename).name, { pascalCase: true, }); - const componentName = `Svg${pascalCaseFilename}`; + const componentName = `${pascalCaseFilename}`; return `const React = require('react'); module.exports = { __esModule: true, - default: ${assetFilename}, + default: ${pascalCaseFilename}, ReactComponent: React.forwardRef(function ${componentName}(props, ref) { return { $$typeof: Symbol.for('react.element'), diff --git a/packages/react-scripts/fixtures/kitchensink/template/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/template/integration/webpack.test.js index 537c8456051..fce15dac852 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/template/integration/webpack.test.js @@ -117,8 +117,8 @@ describe('Integration', () => { it('svg inclusion', async () => { doc = await initDOM('svg-inclusion'); - expect(doc.getElementById('feature-svg-inclusion').src).toMatch( - /\/static\/media\/logo\..+\.svg$/ + expect(doc.getElementById('feature-svg-inclusion').src).toBe( + './logo.svg' ); }); diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js index 19811ef5d75..f6a1b284c72 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js @@ -14,7 +14,7 @@ describe('svg component', () => { const div = document.createElement('div'); ReactDOM.render(, div); expect(div.innerHTML).toBe( - '' + '' ); }); @@ -22,7 +22,7 @@ describe('svg component', () => { const div = document.createElement('div'); const someRef = React.createRef(); ReactDOM.render(, div); - const svgElement = div.getElementsByTagName('logo.svg'); + const svgElement = div.getElementsByTagName('Logo'); expect(svgElement).toHaveLength(1); expect(svgElement[0]).toBe(someRef.current); }); diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js index ff1c5811025..a48d1ad3512 100644 --- a/packages/react-scripts/scripts/utils/createJestConfig.js +++ b/packages/react-scripts/scripts/utils/createJestConfig.js @@ -44,7 +44,7 @@ module.exports = (resolve, rootDir, isEjecting) => { 'config/jest/babelTransform.js' ), '^.+\\.css$': resolve('config/jest/cssTransform.js'), - '^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)': resolve( + '^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)(\\?.+)?$)': resolve( 'config/jest/fileTransform.js' ), }, From a3b81b6d2829f56e55c1b8f8a01e112798da1a5f Mon Sep 17 00:00:00 2001 From: lucabattistini Date: Wed, 10 Aug 2022 09:04:15 +0200 Subject: [PATCH 09/11] test: svg transform --- my-test-app/package.json | 5 +++++ packages/react-scripts/config/jest/fileTransform.js | 5 ----- packages/react-scripts/scripts/utils/createJestConfig.js | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 my-test-app/package.json diff --git a/my-test-app/package.json b/my-test-app/package.json new file mode 100644 index 00000000000..d881daf2971 --- /dev/null +++ b/my-test-app/package.json @@ -0,0 +1,5 @@ +{ + "name": "my-test-app", + "version": "0.1.0", + "private": true +} diff --git a/packages/react-scripts/config/jest/fileTransform.js b/packages/react-scripts/config/jest/fileTransform.js index 9b9057b5940..4aba95f534d 100644 --- a/packages/react-scripts/config/jest/fileTransform.js +++ b/packages/react-scripts/config/jest/fileTransform.js @@ -11,11 +11,6 @@ module.exports = { const assetFilename = JSON.stringify(path.basename(filename)); if (filename.match(/\.svg$/)) { - - if (filename.endsWith('?url')) { - return `./${assetFilename};`; - } - // Based on how SVGR generates a component name: // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6 const pascalCaseFilename = camelcase(path.parse(filename).name, { diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js index a48d1ad3512..f8fc9b5e760 100644 --- a/packages/react-scripts/scripts/utils/createJestConfig.js +++ b/packages/react-scripts/scripts/utils/createJestConfig.js @@ -44,7 +44,7 @@ module.exports = (resolve, rootDir, isEjecting) => { 'config/jest/babelTransform.js' ), '^.+\\.css$': resolve('config/jest/cssTransform.js'), - '^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)(\\?.+)?$)': resolve( + '^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)': resolve( 'config/jest/fileTransform.js' ), }, @@ -56,6 +56,7 @@ module.exports = (resolve, rootDir, isEjecting) => { moduleNameMapper: { '^react-native$': 'react-native-web', '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy', + '^@/(.*svg)(\\?url)$': '/src/$1', ...(modules.jestAliases || {}), }, moduleFileExtensions: [...paths.moduleFileExtensions, 'node'].filter( From a514342050abc02685654d58c751ba82b480b1c2 Mon Sep 17 00:00:00 2001 From: lucabattistini Date: Wed, 10 Aug 2022 09:27:34 +0200 Subject: [PATCH 10/11] test: filetransform has been restored --- my-test-app/package.json | 5 ----- packages/react-scripts/config/jest/fileTransform.js | 2 +- .../template/src/features/webpack/SvgComponent.test.js | 4 ++-- packages/react-scripts/scripts/utils/createJestConfig.js | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) delete mode 100644 my-test-app/package.json diff --git a/my-test-app/package.json b/my-test-app/package.json deleted file mode 100644 index d881daf2971..00000000000 --- a/my-test-app/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "my-test-app", - "version": "0.1.0", - "private": true -} diff --git a/packages/react-scripts/config/jest/fileTransform.js b/packages/react-scripts/config/jest/fileTransform.js index 4aba95f534d..3facbe0a2ba 100644 --- a/packages/react-scripts/config/jest/fileTransform.js +++ b/packages/react-scripts/config/jest/fileTransform.js @@ -20,7 +20,7 @@ module.exports = { return `const React = require('react'); module.exports = { __esModule: true, - default: ${pascalCaseFilename}, + default: ${assetFilename}, ReactComponent: React.forwardRef(function ${componentName}(props, ref) { return { $$typeof: Symbol.for('react.element'), diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js index f6a1b284c72..19811ef5d75 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgComponent.test.js @@ -14,7 +14,7 @@ describe('svg component', () => { const div = document.createElement('div'); ReactDOM.render(, div); expect(div.innerHTML).toBe( - '' + '' ); }); @@ -22,7 +22,7 @@ describe('svg component', () => { const div = document.createElement('div'); const someRef = React.createRef(); ReactDOM.render(, div); - const svgElement = div.getElementsByTagName('Logo'); + const svgElement = div.getElementsByTagName('logo.svg'); expect(svgElement).toHaveLength(1); expect(svgElement[0]).toBe(someRef.current); }); diff --git a/packages/react-scripts/scripts/utils/createJestConfig.js b/packages/react-scripts/scripts/utils/createJestConfig.js index f8fc9b5e760..be6b00f3340 100644 --- a/packages/react-scripts/scripts/utils/createJestConfig.js +++ b/packages/react-scripts/scripts/utils/createJestConfig.js @@ -56,7 +56,7 @@ module.exports = (resolve, rootDir, isEjecting) => { moduleNameMapper: { '^react-native$': 'react-native-web', '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy', - '^@/(.*svg)(\\?url)$': '/src/$1', + '^@/(.*svg?url)$': '/src/$1', ...(modules.jestAliases || {}), }, moduleFileExtensions: [...paths.moduleFileExtensions, 'node'].filter( From 5d70d74d210b42aa9ef309439f71353885f31f23 Mon Sep 17 00:00:00 2001 From: lucabattistini Date: Wed, 10 Aug 2022 10:02:22 +0200 Subject: [PATCH 11/11] test: svg inclusion e2e test --- .../fixtures/kitchensink/template/integration/webpack.test.js | 4 +--- .../kitchensink/template/src/features/webpack/SvgInclusion.js | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/react-scripts/fixtures/kitchensink/template/integration/webpack.test.js b/packages/react-scripts/fixtures/kitchensink/template/integration/webpack.test.js index fce15dac852..eb2ddd51ab9 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/integration/webpack.test.js +++ b/packages/react-scripts/fixtures/kitchensink/template/integration/webpack.test.js @@ -117,9 +117,7 @@ describe('Integration', () => { it('svg inclusion', async () => { doc = await initDOM('svg-inclusion'); - expect(doc.getElementById('feature-svg-inclusion').src).toBe( - './logo.svg' - ); + expect(doc.getElementById('feature-svg-inclusion').src).toBeDefined(); }); it('svg component', async () => { diff --git a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js index 88de1dc3e06..7ef580c0103 100644 --- a/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js +++ b/packages/react-scripts/fixtures/kitchensink/template/src/features/webpack/SvgInclusion.js @@ -6,7 +6,7 @@ */ import React from 'react'; -import logo from './assets/logo.svg?url'; +import logo from './assets/logo.svg'; const SvgInclusion = () => ( logo