如何添加外部参数在webpack配置中有明确的说明

vsdwdz23  于 2023-08-06  发布在  Webpack
关注(0)|答案(1)|浏览(104)

我正在尝试使用webpack构建项目。这是我的webpack配置文件。

import * as path                from 'path';
import * as webpack             from 'webpack';
import { fileURLToPath }        from 'url';
import nodeExternals            from 'webpack-node-externals';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const input  = path.resolve(__dirname, '../src/server');
const output = path.resolve(__dirname, '../server');

const config: webpack.Configuration = {
  entry:       {
    server: path.resolve(input, './index.ts'),
  },
  experiments: {
    outputModule: true,
  },
  externals:   [
    nodeExternals(),
  ],
  module:      {
    rules: [
      {
        exclude: /node_modules/,
        loader:  'ts-loader',
        options: {
          transpileOnly: true,
        },
        test:    /\.ts(x?)$/,
      },
    ],
  },
  name:        'server',
  output:      {
    filename:    '[name].js',
    path:        output,
    publicPath:  '/node/',
    chunkFormat: 'module',
  },
  resolve:     {
    extensions: ['*', '.js', '.jsx', '.json', '.ts', '.tsx'],
  },
  target:      'node',
};

export default config;

字符串
当我运行bundle时,我得到一个错误。
modules.exports = require(“express”);^
参考错误:require未在ES模块作用域中定义,您可以使用import代替此文件被视为ES模块,因为它具有'.js'文件扩展名并且'/test/package.json'包含“type”:要将其视为CommonJS脚本,请将其重命名为使用'.cjs'文件扩展名。
在我看到的包裹里

/***/ ((module) => {

module.exports = require("express");

/***/ }),


我期望得到这样的东西

/***/ ((module) => {

module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("http");

/***/ }),


我试着将这段代码添加到config中,但没有用

externals:   [
    nodeExternals(),
    'express',
]


server.ts

import express from 'express';

const app = express();

app.get('/', (request, response) => {
  response.send('Hi there');
});

app.listen(3000, () => {
  console.log('Listen on the port 3000...');
});

nzkunb0c

nzkunb0c1#

简短回答:对于从webpack-node-externals包导入的函数,将importType选项设置为module
与以下配置等效:

externals: [
  function ({ context, request }: any, callback: any) {
    if (/^express$/.test(request)) {
      return callback(null, 'module ' + request);
    }
    callback();
  },
],

字符串
将外部对象的默认类型指定为“模块”。Webpack将为模块中使用的外部元素生成类似import * as X from '...'的代码。
查看更多externals/#function
工作示例:
项目结构:

$ tree -L 2 -I node_modules
.
├── dist
│   └── main.js
├── package-lock.json
├── package.json
├── src
│   └── server.ts
├── tsconfig.json
└── webpack.config.ts

2 directories, 6 files


src/server.ts

import express from 'express';

const app = express();

app.get('/', (request, response) => {
    response.send('Hi there');
});

app.listen(3000, () => {
    console.log('Listen on the port 3000...');
});


webpack.config.ts

import path from 'path';
import { fileURLToPath } from 'url';
import webpack from 'webpack';
import nodeExternals from 'webpack-node-externals';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

const config: webpack.Configuration = {
    mode: 'production',
    entry: path.resolve(__dirname, './src/server.ts'),
    externalsPresets: { node: true },
    //@ts-ignore
    externals: [nodeExternals({ importType: 'module' })],
    experiments: {
        outputModule: true,
    },
    module: {
        rules: [
            {
                loader: 'ts-loader',
                options: {
                    transpileOnly: true,
                },
                test: /\.ts(x?)$/,
            },
        ],
    },
    output: {
        filename: '[name].js',
        clean: true,
    },
    resolve: {
        extensions: ['*', '.js', '.jsx', '.json', '.ts', '.tsx'],
    },
};

export default config;


tsconfig.json

{
    "compilerOptions": {
        "target": "ESNext",
        "module": "ESNext",
        "allowSyntheticDefaultImports": true,
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true
    }
}


package.json

{
    "version": "1.0.0",
    "scripts": {
        "build": "node --loader ts-node/esm node_modules/.bin/webpack-cli"
    },
    "type": "module",
    "devDependencies": {
        "@types/express": "^4.17.17",
        "@types/webpack": "^5.28.1",
        "@types/webpack-node-externals": "^3.0.0",
        "ts-loader": "^9.4.4",
        "ts-node": "^10.9.1",
        "typescript": "^5.1.6",
        "webpack": "^5.80.0",
        "webpack-cli": "^5.0.2",
        "webpack-node-externals": "^3.0.0"
    },
    "dependencies": {
        "express": "^4.18.2"
    }
}


建置记录档:

$ npm run build

> @1.0.0 build /home/lindu/workspace/webpack-samples/webpack-v5/stackoverflow/75306952
> node --loader ts-node/esm node_modules/.bin/webpack-cli

(node:31537) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:31537) ExperimentalWarning: --experimental-loader is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
asset main.js 363 bytes [emitted] [javascript module] [minimized] (name: main)
runtime modules 396 bytes 2 modules
orphan modules 42 bytes [orphan] 1 module
./src/server.ts + 1 modules 245 bytes [not cacheable] [built] [code generated]
webpack 5.88.2 compiled successfully in 293 ms


产出
dist/main.js

import * as e from 'express';
var t = {
    d: (e, o) => {
        for (var r in o) t.o(o, r) && !t.o(e, r) && Object.defineProperty(e, r, { enumerable: !0, get: o[r] });
    },
    o: (e, t) => Object.prototype.hasOwnProperty.call(e, t),
};
const o = (0, ((r = { default: () => e.default }), (a = {}), t.d(a, r), a).default)();
var r, a;
o.get('/', (e, t) => {
    t.send('Hi there');
}),
    o.listen(3e3, () => {
        console.log('Listen on the port 3000...');
    });


运行:

$ node dist/main.js 
Listen on the port 3000...


节点版本:v14.21.3

相关问题