Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

svgr + jest not configured #4850

Closed
cyrus-za opened this issue Feb 20, 2021 · 11 comments
Closed

svgr + jest not configured #4850

cyrus-za opened this issue Feb 20, 2021 · 11 comments
Labels
outdated scope: testing tools Issues related to Cypress / Jest / Playwright / Vitest support in Nx stale type: bug

Comments

@cyrus-za
Copy link

cyrus-za commented Feb 20, 2021

Current Behavior

@nrwl/next/plugins/with-nx allows us to use svgr to import svg's. When running unit tests on components (inside libs), however, this does not go via next.config.js so we need to manually setup jest to handle svgr for each and every library's jest.config.js

Expected Behavior

I expect some sort of jest config baked into the generator

Steps to Reproduce

  1. Setup any new libary e.g. nx g @nrwl/react:lib myLib
  2. Save some random svg in libs/my-lib/assets/my-svg.svg
  3. Open the generated my-lib.tsx file and import the svg
  4. Run nx myLib:test and see how jest falls over

Failure Logs

● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    jestjs.io/docs/en/configuration.html

Environment

Node : 14.14.0
  OS   : darwin x64
  pnpm : 5.14.3
  
  nx : Not Found
  @nrwl/angular : Not Found
  @nrwl/cli : 11.3.0
  @nrwl/cypress : 11.3.0
  @nrwl/devkit : 11.3.0
  @nrwl/eslint-plugin-nx : 11.3.0
  @nrwl/express : Not Found
  @nrwl/jest : 11.3.0
  @nrwl/linter : 11.3.0
  @nrwl/nest : Not Found
  @nrwl/next : 11.3.0
  @nrwl/node : 11.3.0
  @nrwl/react : 11.3.0
  @nrwl/schematics : Not Found
  @nrwl/tao : 11.3.0
  @nrwl/web : 11.3.0
  @nrwl/workspace : 11.3.0
  typescript : 4.1.3
@vsavkin vsavkin added the scope: testing tools Issues related to Cypress / Jest / Playwright / Vitest support in Nx label Feb 22, 2021
@quolpr
Copy link

quolpr commented Feb 24, 2021

Actually, jest misses a lot of other loaders' support. Here is my modified jest.config.js in each app/lib dir:

module.exports = {
  displayName: 'core',
  preset: '../../jest.preset.js',
  transform: {
    '^.+\\.[tj]sx?$': [
      'babel-jest',
      { cwd: __dirname, configFile: './babel-jest.config.json' },
    ],
    '.+\\.(png|jpg|gif|ttf|woff|woff2|mp4)$': '<rootDir>/../../jest/stub.js',
    '^.+\\.(css|less|scss|sass)$': '<rootDir>/../../jest/stub.js',
    '^.+\\.svg$': '<rootDir>/../../jest/svgTransformer.js',
  },
  moduleNameMapper: {
    '^.+\\.(css|less|sass|scss)$': '<rootDir>/../../jest/fileMock.js',
    '^.+\\.(png|jpg|gif|ttf|woff|woff2|mp4)$':
      '<rootDir>/../../jest/fileMock.js',
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx']
};

<rootDir>/jest/stub.js:

module.exports = {
  process: function () {
    return {
      code: 'module.exports = ""',
    };
  },
};

<rootDir>/jest/svgTransformer.js:

const path = require('path');
const camelcase = require('camelcase');

// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html

module.exports = {
  process(src, filename) {
    const assetFilename = JSON.stringify(path.basename(filename));

    if (filename.match(/\.svg$/)) {
      // 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}`;
      return `const React = require('react');
      module.exports = {
        __esModule: true,
        default: ${assetFilename},
        ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
          return {
            $$typeof: Symbol.for('react.element'),
            type: 'svg',
            ref: ref,
            key: null,
            props: Object.assign({}, props, {
              children: ${assetFilename}
            })
          };
        }),
      };`;
    }

    return `module.exports = ${assetFilename};`;
  },
};

<rootDir>/jest/fileMock.js:

module.exports = '';

Hope it will help 🙏️

@cyrus-za
Copy link
Author

cyrus-za commented Mar 4, 2021

Thanks @quolpr but we got a lot of libs. Not ideal to need to manually modify each of them and to try and get everyone in the team to remember to manually change it when creating a new lib. Best to have it as part of nx, or to have some script in tools/scripts dir

If nx team doesn't respond soon, I'll probably end up making a script for it

@github-actions
Copy link

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs.
If we missed this issue please reply to keep it active.
Thanks for being a part of the Nx community! 🙏

@cyrus-za
Copy link
Author

cyrus-za commented May 6, 2021

This is still an isssue...

@cyrus-za cyrus-za mentioned this issue Jun 8, 2021
@Lonli-Lokli
Copy link

@vsavkin Can you please reopen it?

@aamir-mns
Copy link

Actually, jest misses a lot of other loaders' support. Here is my modified jest.config.js in each app/lib dir:
.....
Hope it will help 🙏️

this worked for me although this should be default behaviour from NX

@timbakkum
Copy link

timbakkum commented Nov 2, 2021

there is svgr (and also font) support it seems in the gatsby jest setup, but not for default react libs. Would be nice to have an overview in the docs of what is supported where (with webpack, jest, rollup, babel) and what is the best way to customize without overriding defaults. Now the only way is to look at the source files of the nx presets.

@Lonli-Lokli
Copy link

Lonli-Lokli commented Dec 10, 2021

For those who interested in workaround:

  1. edit root jest.preset.js
module.exports = {
    ...nxPreset,
    moduleNameMapper: {
     '\\.svg': '<rootDir>/../../testing/svgrMock.js'
    }
};

Please note two /.. after root dir. Due to #8029 all libs folders are using their src as rootDir

  1. add /testing/svgrMock.js
    module.exports = { ReactComponent: 'IconMock' }

@StephenStrickland
Copy link

StephenStrickland commented Mar 17, 2022

@Lonli-Lokli I've tried your approach and still cannot get around the error:

 // error TS2307: Cannot find module './brand-icon.svg' or its corresponding type declarations.
 import { ReactComponent as BrandIcon} from './brand-icon.svg';

@Lonli-Lokli
Copy link

I've answered in linked topic.

@github-actions
Copy link

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated scope: testing tools Issues related to Cypress / Jest / Playwright / Vitest support in Nx stale type: bug
Projects
None yet
Development

No branches or pull requests

7 participants