nx: Cannot load SVG in React application

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed
  • I’m reporting the issue to the correct repository (not related to Angular, AngularCLI or any dependency)

Expected Behavior

Utilize an SVG file using the <svg> tag in a React application.

Current Behavior

The application fails to compile with nx serve.

Failure Information (for bugs)

Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.

Steps to Reproduce

I personally discovered this when trying to use the Ionic React components in an Nx workspace, so will provide these steps to reproduce.

  1. Generate a new Nx workspace with a default React application
  2. yarn install @ionic/react
  3. Wrap the contents of the default app.tsx JSX with <IonApp></IonApp>
  4. nx serve

If you can provide steps to reproduce from scratch, that would be enormously appreciated (i.e. where the first step is npx create-nx-workspace@latest repro-workspace)

Context

Please provide any relevant information about your setup:

Failure Logs

ERROR in /Users/devinshoemaker/code/ionic/test-nx-ionic/node_modules/ionicons/dist/ionicons/svg/md-quote.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M96.4 416h77.1l50.9-96.6V96h-160v223.4h77.1L96.4 416zm224 0h77.1l50-96.6V96H288.4v223.4h82l-50 96.6z"/></svg>

ERROR in /Users/devinshoemaker/code/ionic/test-nx-ionic/node_modules/ionicons/dist/ionicons/svg/ios-school.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M96.9 270.3V363c0 2.9 1.5 5.5 4 7l132 75.9c5.3 3.1 12-.8 12-7v-93.8c0-2.9-1.5-5.5-4-7l-132-74.9c-5.4-2.9-12 1-12 7.1zM280.9 445.9L413 370c2.5-1.4 4-4.1 4-7v-93.7c0-6.2-6.6-10-12-7l-132 75.9c-2.5 1.4-4 4.1-4 7V439c-.1 6.1 6.6 10 11.9 6.9z"/><path d="M249 65.1L37 188.9c-5.4 3.1-5.4 10.8 0 13.9l212 117.8c4.9 2.8 11 2.8 15.9 0L453 212.9c5.3-3.1 7 .8 7 7v153.4c0 6.8 3.9 10 11 10 4.4 0 10-3.2 10-10V201.5c0-2.9-1.5-5.5-4-7L264.9 65.1c-4.9-2.8-11-2.8-15.9 0z"/></svg>

ERROR in /Users/devinshoemaker/code/ionic/test-nx-ionic/node_modules/ionicons/dist/ionicons/svg/md-arrow-round-down.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M99.4 284.9l134 138.1c5.8 6 13.7 9 22.4 9h.4c8.7 0 16.6-3 22.4-9l134-138.1c12.5-12 12.5-31.3 0-43.2-12.5-11.9-32.7-11.9-45.2 0l-79.4 83v-214c0-16.9-14.3-30.6-32-30.6-18 0-32 13.7-32 30.6v214l-79.4-83c-12.5-11.9-32.7-11.9-45.2 0s-12.5 31.2 0 43.2z"/></svg>

Other

I have found one other person that reported a similar issue, though it’s not Ionic specific. The solution proposed here involved overriding the default webpack config that Nx uses for it’s React applications, however that config did not work for me, and I am not adept enough with webpack yet to get this working. I have been inspecting the create-creact-app webpack.config.js (which is what Ionic uses in it’s generated projects) and will continue to try and get an override working, but this does seem like something that should be available out of the box. create-react-app applications are quite popular, so I imagine many people will eventually run into this issue when using React with Nx.

https://stackoverflow.com/questions/56848952/cannot-load-svg-in-nrwl-react-workspace

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 5
  • Comments: 35 (29 by maintainers)

Most upvoted comments

@devinshoemaker I had the same problem during integrating Nx and @ionic/react and I solved it by using a custom webpack config.

  • Install Ionic
$ npm i @ionic/react @ionic/react-router react-router-dom ionicons
$ npm i -D typescript@3.5
  • Install additional loaders
$ npm i -D @svgr/webpack url-loader
  • webpack.config.js
// @nrwl/react + SVG
const babelWebpackConfig = require('@nrwl/react/plugins/babel');

module.exports = config => {
  config.module.rules.push(
    {
      test: /\.svg$/,
      use: [
        '@svgr/webpack',
        'url-loader'
      ]
    }
  );
  return babelWebpackConfig(config);
};
  • workspace.json
{
  "version": 1,
  "projects": {
    "client": {
      "root": "apps/client",
      "sourceRoot": "apps/client/src",
      "projectType": "application",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@nrwl/web:build",
          "options": {
            ...
            "webpackConfig": "./webpack.config.js"
          },
  • polyfill.ts (not required in recent @ionic/react)
(window as any).process = {
  env: {}
};

Some of the solutions I found were adding a custom.d.ts file in the root of the project and including:

declare module '*.svg' {
	const content: string;
	export default content;
}

And/or using a custom webpack config with a loader for svg’s etc.

There a few solutions floating around that seem to be working for others, but nothing worked for me. I’ll be keeping an eye on this issue since I’d prefer to be able to import them directly.

No worries, we’ll make sure testing works well.

@puku0x I figured out the issue with mine. They applied the change only to the react application with their build chain. Next.js needs these steps:

Add this to your project’s tsconfig.json

+ "files": [
+    "../../node_modules/@nrwl/react/typings/image.d.ts"
+  ],

Add this to your project’s jest.config.js in the transform object.

+ '^(?!.*\\\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest'

Add this to your project’s next.config.js

+ webpack: config => {
+    // Converts SVG files into React components.
+    config.module.rules.push({
+      test: /\.svg$/,
+      issuer: {
+        test: /\.[jt]sx?$/
+      },
+      use: ['@svgr/webpack?-svgo,+titleProp,+ref![path]', 'url-loader']
+    });
+
+    return config
+  }

Install @svgr/webpack and url-loader to your devDependencies.

Everything is working for me now!

@Krasnopir Does this work for you?

const getWebpackConfig = require('@nrwl/react/plugins/webpack');

function getCustomWebpackConfig(webpackConfig) {
  const config = getWebpackConfig(webpackConfig);

  // SVG fix
  const index = config.module.rules.findIndex(rule => rule.test.test('.svg'));
  config.module.rules.splice(index, 1, {
    test: /\.svg$/,
    //issuer: {
    //  test: /\.[jt]sx?$/
    //},
    use: [
      {
        loader: 'svg-sprite-loader',
        options: {
          symbolId: '[name]'
        }
      },
      'svgo-loader'
    ]
  });

  return config;
}

module.exports = getCustomWebpackConfig;

great. it work!!! much thanks!

I’ve opened a PR, but there is one thing I want to potentially tackle before it goes out.

Closing this issue. If there are further use cases that aren’t addressed please open a new issue. 😃

Sounds good. We’ll have this in the next release.

Hmmm @puku0x I wasn’t able to get it working using that webpack config…

@jaysoo Is there documentation around what needs updated or a way to update the apps with the required config? When I run nx serve nextjs-app it gives me this error message:

ModuleParseError: Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>icn</title><path d="M18,13H13v5a1,1,0,0,1-2,0V13H6a1,1,0,0,1,0-2h5V6a1,1,0,0,1,2,0v5h5a1,1,0,0,1,0,2Z"/></svg>
    at handleParseError (/project/node_modules/webpack/lib/NormalModule.js:469:19)
    at /project/node_modules/webpack/lib/NormalModule.js:503:5
    at /project/node_modules/webpack/lib/NormalModule.js:358:12
    at /project/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/project/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at /project/node_modules/loader-runner/lib/LoaderRunner.js:205:4
    at /project/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:85:15
    at processTicksAndRejections (internal/process/task_queues.js:75:11)

@puku0x Hmm, the build already replaces process.env.NODE_ENV with production or development, but looks like ionic is looking for process.env which we don’t substitute. This can be fixed as well. 😃

@puku0x We need to update this for Next.js apps as well since it’s managed by a different loader. Should track it separately here #2350.

The issuer is supposed to to prevent SVG imports within CSS files from being processed. Are your imports from .jsx and .tsx files?

Just wanted to link the PR to this issue for easier tracking #1964

+1

In addition, as mentioned in Jest Docs, a file mock is needed to run tests.

// jest.config.js
module.exports = {
  testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
  transform: {
    '^.+\\.(ts|js|html)$': 'ts-jest',
  },
  resolver: '@nrwl/jest/plugins/resolver',
  moduleFileExtensions: ['ts', 'js', 'html'],
  coverageReporters: ['html'],
  passWithNoTests: true,
  moduleNameMapper: {
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      '<rootDir>/src/app/__mocks__/fileMock.js',
  },
};
// apps/client/src/app/__mocks__/fileMock.js
module.exports = 'test-file-stub';

@puku0x Thanks! This worked for me without the polyfill.ts (but i’m not using ionic, so maybe thats it)

I tried a couple of different webpack.config.js variations, but no worked. Thanks for yours, works like a charm!