Библиотека ESM, созданная с помощью бросков rollup-plugin-postcss Не удается найти модуль '../node_modules/style-inject/dist/style-inject.es.js'

Мы поддерживаем внутреннюю библиотеку, которая экспортирует модули ESM с помощью Rollup. Мы только недавно перешли на использование модулей CSS, которые мы установили с помощью rollup-plugin-postcss. Мы хотим внедрить эти стили в голову, а не иметь внешний файл.

Наш собранный пакет генерирует файл 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'и 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}/`));
}

3 ответа

Решение

В библиотеке есть ошибка, из-за которой импорт является относительным, а не именем модуля.

Есть открытый PR, но похоже, что библиотека больше не поддерживается. В комментариях есть два рекомендуемых решения:

  1. Строка заменяет встроенный вывод
  2. Для этого добавьте настраиваемый подключаемый модуль накопительного пакета

Это вовсе не ошибка. Это работает правильно, потому что stylesInject — это просто функция из пакета 'styles-inject', поэтому мы можем разрешить ее объединение. Но это не в комплекте, потому что, скорее всего, у вас есть этот параметр в вашем rollup.config.js:

      external: [
    /node_modules/
]

Итак, замените его кодом ниже, и он будет работать:

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

кроме того, вы можете вместо этого написать регулярное выражение

Вам нужно сделать 2 вещи:

  • Добавлятьstyle-injectзависимость вpackage.json
          "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',
                );
            });
        },
    }
];

Использованная литература:

Другие вопросы по тегам