使用rollup-plugin-postcss抛出生成的ESM库找不到模块'../node_modules/style-inject/dist/style-inject.es.js'



我们正在维护一个内部库,该库使用Rollup导出ESM模块。我们最近刚刚切换到使用CSS模块,我们已经用汇总插件postpass设置了这些模块。我们希望将这些样式注入头部,而不是使用外部文件。

我们构建的捆绑包生成ESM文件,其中包含:

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

我们的消费库随后出现故障

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

我希望ESM导出到import styleInject from 'style-inject'和样式注入作为依赖项包含在package-lock.json中。使用CSS模块并为库的使用者注入头部的正确方法是什么?

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}/`));
}

库中存在一个错误,其中导入是相对的,而不是模块名称。

有一个开放的公共关系,但图书馆看起来不再维护了。评论中有两个建议的解决方案:

  1. 字符串替换生成的输出
  2. 添加一个自定义汇总插件来完成此操作

这根本不是一个bug。它工作正常,因为stylesInject只是"styles-inject"包中的一个函数,所以我们可以允许它被绑定。但它没有捆绑在一起,因为你的汇总中很可能有这个设置。config.js:

external: [
/node_modules/
]

所以,用下面的代码替换它,它就会工作:

external: (id) => {
if (/style-inject/.test(id)) return false;
if (/node_modules/.test(id)) return true;
return false;
},

此外,您可以为它编写正则表达式,而不是

您需要做两件事:

  • package.json中添加style-inject依赖项
"dependencies": {
"style-inject": "^0.3.0"
},
  • 将以下插件添加到rollup.config.js
const plugins = [
...
{
/**
* - https://github.com/egoist/rollup-plugin-postcss/issues/381#issuecomment-880771065
* - https://lightrun.com/answers/egoist-rollup-plugin-postcss-esm-library-generated-with-rollup-plugin-postcss-throws-cannot-find-module-node_modulesstyle-in
*/
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(
/..?/[^n"?:*<>|]+/style-inject/dist/style-inject.es.js/g,
'style-inject',
);
});
},
}
];

参考文献:

  • https://github.com/egoist/rollup-plugin-postcss/issues/381#issuecomment-880771065
  • https://lightrun.com/answers/egoist-rollup-plugin-postcss-esm-library-generated-with-rollup-plugin-postcss-throws-cannot-find-module-node_modulesstyle-in

最新更新