typescriptnpmshared-librariesrollup

Cannot unit test proyect with my custom react library


I have created this NPM package https://www.npmjs.com/package/@applaudo/react-clapp-ui

I can install it and use it correctly in other project using create react app and it works fine, but when I try to run my unit test in the destination project I get this error from jest

 FAIL  src/components/test.test.tsx
  ● Test suite failed to run

    Cannot find module '@applaudo/react-clapp-ui' from 'src/components/test1.tsx'

    Require stack:
      src/components/test1.tsx
      src/components/test.test.tsx

      1 | import Mx from 'rc-picker/lib/locale/es_MX';
    > 2 | import { Button, Content, DatePicker, Heading, Label, useClapp } from "@applaudo/react-clapp-ui";
        | ^
      3 |
      4 |
      5 | export const Test1 = () => {

      at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:324:11)
      at Object.<anonymous> (src/components/test1.tsx:2:1)

This is my rollup.config

import commonjs from '@rollup/plugin-commonjs';
import dts from 'rollup-plugin-dts';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import pkg from './package.json';
import postcss from 'rollup-plugin-postcss';
import { RollupOptions } from 'rollup';
import { terser } from 'rollup-plugin-terser';
import typescript from '@rollup/plugin-typescript';

const dependencies = Object.keys(pkg.dependencies);
const external = [...dependencies, 'lodash', /\.css$/, /rc-util*/];

const options: RollupOptions[] = [
  {
    input: 'index.tsx',
    output: {
      name: pkg.name,
      dir: 'dist',
      format: 'es',
      sourcemap: false,
      preserveModules: true,
      exports: 'named',
      assetFileNames: '[name][extname]',
    },
    plugins: [
      // @ts-ignore
      peerDepsExternal(),
      commonjs(),
      typescript({ tsconfig: './tsconfig.json' }),
      postcss({
        minimize: true,
        extract: true,
        exec: true,
        sourceMap: true,
        use: ['sass'],
      }),
      terser(),
    ],
    external,
  },
  {
    input: 'dist/dts/index.d.ts',
    output: {
      file: 'dist/index.d.ts',
      format: 'commonjs',
    },
    external: [/\.scss$/, /\.css$/],
    plugins: [
      dts({
        compilerOptions: {
          baseUrl: 'dist/dts',
        },
      }),
    ],
  },
];

export default options;

and this is a fragment of the package.json

{
  "license": "Apache-2.0",
  "module": "dist/index.js",
  "typings": "dist/index.d.ts",
  "files": [
    "dist"
  ],
  "sideEffects": [
    "*.scss"
  ]
}

I try using formar commonjs for packagin the lib instead of es and still din't work in any of the 3 projects I have tested jest and TS using react testing library or enzyme, same error.

So I'm not sure how to pack the lib so it work with jest and also webpack (currently work with webpack)


Solution

  • Turn out that jest only support ES module export for the project you are working on, anything from the node_modules is not transpile or convert into CJS unless explicitly especify in the jest config.

    The easy solution is to add a main field in the package.json pointing to a file that export the modules as CJS wich is what jest can work with, and also having the module field with ES export so webpack can still use the treeshaking and compile time imports etc..

    {
      "module": "dist/index.js",
      "main": "lib/index.js",
      "typings": "dist/index.d.ts",
      "files": [
        "dist",
        "lib"
      ],
    }
    

    then in the rollup config just add the extra output to generat the same thing but in CJS format.