Home > Net >  Cannot find module './public/icons/icon.svg' or its corresponding type declarations, test
Cannot find module './public/icons/icon.svg' or its corresponding type declarations, test

Time:09-30

My Next.js React app tests pass locally, but fail in Github Actions.

The next.config.js has this export to know about svg imports:

module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/i,
      issuer: /\.[jt]sx?$/,
      use: ['@svgr/webpack'],
    });

    return config;
  },
};

Then I've got some SVG icons, and I import them into the app like:

import StatusMessageErrorIcon from '../../../public/icons/Status-message-error.svg';

<StatusMessageErrorIcon fill="red" width="18" height="18" />

Everything works, the icon is shown.

Then I've got a test which renders the page with that icon, render(<Create />);

The test runs through locally, everything passes.

But running the test in a Github Action it fails with:

Test suite failed to run

src/MyForm.tsx:11:36 - error TS2307: Cannot find module '../../../public/icons/Status-message-error.svg' or its corresponding type declarations.

11 import StatusMessageErrorIcon from '../../../public/icons/Status-message-error.svg';

The Github Action is very basic:

steps:
  - uses: actions/checkout@v3

  - name: Use Node.js ${{ matrix.node-version }}
    uses: actions/setup-node@v3
    with:
      node-version: ${{ matrix.node-version }}
      cache: 'npm'

  - name: Install npm packages
    run: npm ci

  - name: Run tests
    run: npm run test

I don't get it, any ideas?

CodePudding user response:

You need to do some webpack config for the image path from public dir.

Example:

const srcPath = path.join(__dirname, '..', 'publicfolder')

const rules = []

const includePaths = [
  srcPath
]

module.exports = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/i,
      include: includePaths,
      issuer: /\.[jt]sx?$/,
      use: ['@svgr/webpack'],
    });

    return config;
  },
};

After this, you can simply import the images into your react components:

import myImage from 'publicfolder/images/Image1.png'

Use myImage like below:

<div><img src={myImage}/></div>

or if the image is imported into the local state of the component

<div><img src={this.state.myImage}/></div> 

CodePudding user response:

Right, In my case it had to do with Typescript and importing SVG into a .tsx file.

If anyone else has this problem, here's how to fix it.

Create a custom.d.ts file (at root level is fine) with the contents:

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

Then in tsconfig.json add this file to the include array like so:

{
    "include": [
        "next-env.d.ts",
        "**/*.ts",
        "**/*.tsx",
        "custom.d.ts"
    ]
}
  • Related