rollup-plugin-postcss: ESM library generated with rollup-plugin-postcss throws Cannot find module '../node_modules/style-inject/dist/style-inject.es.js'
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}/`));
}
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 4
- Comments: 15
Commits related to this issue
- #381: Added options styleInjectRelativePath to allow module import for ESM libraries — committed to mummybot/rollup-plugin-postcss by mummybot 3 years ago
I’ve fixed this for our project by doing two things:
style-inject
in the library’s dependenciesIt 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?This is not a bug at all. It works properly because stylesInject is just a function from ‘styles-inject’ package, so we can allow it to be bundled. But it is not bundled because most likely you have this setting in your rollup.config.js:
So, replace it with a code bellow and it will work:
also, you can write a regexp for it instead
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:
I’ll raise a PR shortly
If you do want to abide for the way rollup decided to implement this, you can “force” NPM to pack the nested modules by adding the folder explicitly on your
package.json
: