question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ESM library generated with rollup-plugin-postcss throws Cannot find module '../node_modules/style-inject/dist/style-inject.es.js'

See original GitHub issue

Apologies if this is more of a usage question than a bug, I have posted here at Stackoverflow.

We are maintaining an internal library which is exporting ESM modules using Rollup. We have just recently switched to using CSS modules, which we have set with rollup-plugin-postcss. We want to inject these styles into the head rather than have an external file.

Our built bundle generates the ESM file with:

import styleInject from '../node_modules/style-inject/dist/style-inject.es.js';

Our consuming library then fails with

 Uncaught Error: Cannot find module '../node_modules/style-inject/dist/style-inject.es.js'

I would expect the ESM export to import styleInject from 'style-inject' and style-inject to be included in the package-lock.json as a dependency. Even manually adding the dependency as part of our library which then includes it in the consuming app doesn’t allow it to resolve. What is the correct way of using CSS Modules and injecting into the head for the consumer of a library?

rollup.config.js

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import babel from '@rollup/plugin-babel';
import json from '@rollup/plugin-json';
import postcss from 'rollup-plugin-postcss';
import pkg from './package.json';
import fg from 'fast-glob';
import path from 'path';

export default [
  {
    input: 'src/index.js',
    external: external(),
    output: [
      {
        name: '@my/packageName',
        file: pkg.module,
        format: 'es',
        sourcemap: true,
      },
    ],
    plugins: [
      {
        name: 'watch-external',
        async buildStart() {
          const files = await fg(['src/index.d.ts', 'playground/**/*']);
          for (let file of files) {
            this.addWatchFile(path.resolve(file));
          }
        },
      },
      json(),
      postcss({
        modules: true,
      }),
      babel({
        exclude: /node_modules/,
        babelHelpers: 'runtime',
        babelrc: false,
        presets: [
          [
            '@babel/preset-env',
            {
              modules: false,
              useBuiltIns: 'entry',
              corejs: 3,
              targets: {
                ie: 11,
              },
            },
          ],
          '@babel/preset-react',
        ],
        plugins: [
          '@babel/plugin-transform-runtime',
          '@babel/plugin-proposal-class-properties',
          '@babel/plugin-proposal-export-namespace-from',
        ],
      }),
      commonjs(),
    ],
  },
];

function external() {
  const { dependencies = {}, peerDependencies = {} } = pkg;

  const externals = [
    ...Object.keys(dependencies),
    ...Object.keys(peerDependencies),
  ];

  return id =>
    // match 'lodash' and 'lodash/fp/isEqual' for example
    externals.some(dep => id === dep || id.startsWith(`${dep}/`));
}

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:3
  • Comments:7

github_iconTop GitHub Comments

6reactions
mummybotcommented, Jun 16, 2021

I’ve fixed this for our project by doing two things:

  1. Including style-inject in the library’s dependencies
  2. String replacing the built .esm file: ‘…/node_modules/style-inject/dist/style-inject.es.js’ to ‘style-inject’.

It works, but this seems like a hack for what should just work out of the box. Is there a reason for the relative import path to style-inject? If so, can we make it configurable?

3reactions
dandrewgarvincommented, Jul 15, 2021

We are experiencing this issue as well, and have probably a very similar solution to @mummybot. For anybody else that encounters this problem while it remains unsolved in this plugin, here was the custom inline-plugin we built:

// rollup.config.js
export default {
  // other rollup configurations...

  plugins: [
    // other rollup plugins...

    postcss(),

    {
        name: 'Custom Rollup Plugin`',

        generateBundle: (options, bundle) => {
          Object.entries(bundle).forEach(entry => {

            // early return if the file we're currently looking at doesn't need to be acted upon by this plugin
            if (!entry[0].match(/.*(.scss.js)$/)) {
              return;
            }

            // this line only runs for .scss.js files, which were generated by the postcss plugin.
            // depending on the use-case, the relative path to style-inject might need to change
            bundle[entry[0]].code = entry[1].code.replace(
              '../../node_modules/style-inject/dist/style-inject.es.js',
              'style-inject',
            );
          });
        },
      }
  ]
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

1 - Stack Overflow
ESM library generated with rollup-plugin-postcss throws Cannot find module '../node_modules/style-inject/dist/style-inject.es.js' ; id => ; dep => ...
Read more >
cannot find module [Node npm Error Solved] - freeCodeCamp
I'm getting the error because I'm trying to import the freeCodeCamp icon from the react-icons package, which I don't have installed. import { ......
Read more >
Documentation - ECMAScript Modules in Node.js - TypeScript
js has been working to support running ECMAScript modules (ESM). This has been a very difficult feature to support, since the foundation of...
Read more >
rollup.js
Importing CommonJS · Publishing ES Modules ... Imported values cannot be reassigned, though imported objects and arrays can be mutated (and the exporting ......
Read more >
How we employed the new ECMAScript Module Support in ...
Why use ECMAScript modules (import) instead of CommonJS (require)?. The most obvious difference between ESM and CommonJS is the use of import ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found