Создание модуля es6 в проекте typescript с помощью webpack

#node.js #typescript #webpack #es6-modules #javascript-import

Вопрос:

Я пытаюсь использовать пакет узлов imagemin в своем проекте. Это модуль es6, и я получаю ошибку при его использовании.

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module. с «типом» как «модуль» в package.json

ReferenceError: require is not defined с «типом» как «commonjs» в package.json

Моя конфигурация веб-пакета:

 export default env => {
    return {
        mode: env.production ? 'production' : 'development',
        entry: {
            main: './src/main.ts',
            worker: './src/worker.ts'
        },
        target: ['node', 'es2019'],
        devtool: env.production ? false : 'inline-source-map',
        watch: !env.production,
        resolve: {
            extensions: ['.ts', '.js'],
            alias: {
                src: _resolve(process.cwd(), './src')
            }
        },
        module: {
            rules: [{
                test: /.ts$/,
                include: _resolve(process.cwd(), "src"),
                use: 'ts-loader',
                exclude: [/node_modules/, /.spec.ts/, /.e2e-spec.ts/]
            }],
        },
        externalsPresets: { node: true },
        externals: [nodeExternals()],
        output: {
            filename: '[name].js',
            path: OUTPUT_DIR,
            clean: !!env.production,
            devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]',
            library: {
                type: 'module'
            }
        },
        optimization: {
            minimize: false, //!!env.production
            mangleExports: true,
            minimizer: [new terserPlugin({
                terserOptions: {
                    output: {
                        comments: false
                    },
                    keep_classnames: true,
                },
                extractComments: false,
            })]
        },
        experiments: {
            outputModule: true
        }
    };
};
 

Мой tsconfig:

 {
  "compilerOptions": {
    "module": "ES2020",
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2019",
    "sourceMap": true,
    "strict": true,
    "baseUrl": ".",
    "esModuleInterop": true,
    "noImplicitAny": true,
    "moduleResolution": "node",
    "outDir": "../bin/server",
    "typeRoots": [
      "node_module/@types",
      "./typings"
    ],
    "types": [
      "node",
      "@types/jest"
    ]
  },
  "exclude": [
    "node_modules"
  ]
}
 

Когда я пытаюсь «импортировать» imagemin в один из моих файлов .ts, webpack преобразует его в «требуется». Я также пробовал использовать import() , но это тоже не работает.
Я сделал репо на github

Есть ли способ получить пакет es6 (предпочтительно) или использовать imagemin с пакетом commonjs?

Ответ №1:

Измените свой сценарий запуска

    "start": "node --experimental-modules src/index.mjs "
 

и В пакете.json Добавить

 { 
   ...
   "type": "module",
   ...
}
 

Комментарии:

1. --experimental-modules больше не требуется.

2. И заданный вопрос уже есть "type": "module" в package.json

3. с «типом» как «модуль» в файле package.json. Я получаю ошибку ReferenceError: require не определен.

4. Если у вас есть «тип: модуль» в файле package.json, ваш исходный код должен использовать import синтаксис. Когда у вас этого нет, вы должны использовать require синтаксис. Добавление 'type': 'module' к модулям package.json enables ES 6. Для получения дополнительной информации смотрите здесь

5. да, я понимаю, как работает тип в package.json, проблема в webpack. Я не могу заставить его вывести модуль es6.

Ответ №2:

Я не смог найти способ объединить формат es6 через webpack, но я смог использовать модуль es6 в системе commonjs при объединении через webpack.

 externals: [
           nodeExternals({
               allowlist: ['imagemin', 'imagemin-mozjpeg']
           }),
           async function ({ request }) {
               if (request === 'imagemin' || request === 'imagemin-mozjpeg')
                   return `import ${request}`;
           },
       ]
 

Вот как я заставил imagemin работать.