使用Webpack、TypeScript和ESM构建Express服务器

7

我正在尝试使用webpack构建一个小项目node.js + ts

tsconfig.json
{
  "compilerOptions": {
    "lib": ["ESNext"],
    "target": "ES2020",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "types": ["node"],
    "allowSyntheticDefaultImports": true,
    "rootDir": "./"
  },
}

我将它添加到了package.json的行中:"type": "module"

webpack.config.ts
import * as path         from 'path';
import * as webpack      from 'webpack';
import { fileURLToPath } from 'url';

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

const PATHS = {
  entry:  path.resolve(__dirname, 'src/server/index.ts'),
  output: path.resolve(__dirname, 'dist'),
};

const config: webpack.Configuration = {
  target:  'node',
  entry:   PATHS.entry,
  output:  {
    path:     PATHS.output,
    filename: 'bundle.js',
  },
  module:  {
    rules: [
      {
        test:    /\.ts(x?)$/,
        use:     'ts-loader',
        exclude: '/node_modules/',
      },
    ],
  },
  resolve: {
    extensions: ['*', '.js', '.jsx', '.json', '.ts', '.tsx'],
  },
};

export default config;

通过运行命令"build": "webpack --config config/webpack.config.ts --mode development",我遇到了一个错误:

[webpack-cli] 加载失败 '/node_esm/webpack.config.ts' 配置 [webpack-cli] TypeError [ERR_UNKNOWN_FILE_EXTENSION]: 未知的文件扩展名 ".ts",位于 /node_esm/webpack.config.ts

我尝试在我的config.json中添加"ts-node": { "esm": true},但这并没有帮助我解决问题。我需要怎么做才能使用webpack构建应用程序呢?
  • node: v16.18.1
  • ts-loader: v9.4.2
  • typescript: v4.9.4
  • webpack: v5.75.0
  • webpack-cli: 5.0.1
更新 我尝试更改tsconfig。第一种选择是打开您的tsconfig.json文件并查找compilerOptions。将目标设置为“ES5”,将模块设置为“CommonJS”(或完全删除模块选项)。
{
  "compilerOptions": {
    "target": "ES5",
    "module": "CommonJS",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "types": ["node"],
    "allowSyntheticDefaultImports": true,
    "rootDir": "./"
  }
}

错误仍然存在。 第二个选项是为ts-node添加设置:

您可以保持tsc的"module":"ESNext",如果您使用webpack或其他构建工具,则可以为ts-node设置覆盖。

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "types": ["node"],
    "allowSyntheticDefaultImports": true,
    "rootDir": "./"
  },
  "ts-node": {
    "compilerOptions": {
      "module": "CommonJS"
    }
  }
}

同时在这一点上,我尝试添加

{
  "compilerOptions": {
    "module": "ESNext" // or ES2015, ES2020
  },
  "ts-node": {
    // Tell ts-node CLI to install the --loader automatically, explained below
    "esm": true
  }
}

正如 TypeScript 文档所述,第三个选项是安装 tsconfig-paths 包,但它也没有帮助。在所有情况下,错误仍然与之前写的一样。

package.json
{
  "name": "node_esm",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "watch": "webpack --config config/webpack.config.ts --mode development --watch",
    "build": "webpack --config config/webpack.config.ts --mode development"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cross-env": "^7.0.3",
    "express": "^4.18.2"
  },
  "devDependencies": {
    "@types/express": "^4.17.15",
    "@types/node": "^18.11.18",
    "@types/webpack": "^5.28.0",
    "circular-dependency-plugin": "^5.2.2",
    "clean-webpack-plugin": "^4.0.0",
    "nodemon": "^2.0.20",
    "ts-loader": "^9.4.2",
    "ts-node": "^10.9.1",
    "tsconfig-paths": "^4.1.2",
    "tsconfig-paths-webpack-plugin": "^4.0.0",
    "typescript": "^4.9.4",
    "webpack": "^5.75.0",
    "webpack-cli": "^5.0.1",
    "webpack-dev-server": "^4.11.1",
    "webpack-node-externals": "^3.0.0"
  }
}

1
你需要使用 ts-node 启动 webpack 构建。你有阅读过 https://webpack.js.org/configuration/configuration-languages/#typescript 吗? - morganney
你是如何启动Webpack构建的? - morganney
1
那么你没有仔细阅读文档。你没有使用 ts-node - morganney
你能提供代码存储库或创建可复现的代码库吗? - Yilmaz
@Phil "Webpack主要用于开发库,而不是应用程序。" 看起来我错误地假设了原帖作者的使用意图。 - undefined
显示剩余9条评论
1个回答

4
主要问题在于Webpack使用的是ts-node API,而不是CLI,因此您需要适当地配置节点加载器。
我使用以下配置使其正常工作。

package.json

"scripts": {
  "build": "NODE_OPTIONS='--loader ts-node/esm' webpack --mode development"
},

请查看原生ECMAScript模块的ts-node文档...

如果您没有使用我们的CLI,请将加载器标志传递给node。

如果您计划在Windows上构建此项目,您可能需要使用类似于cross-envenv-cmd的工具。


注意:我在tsconfig.json中不需要任何特殊设置。没有需要ts-node部分,因为那只适用于CLI。

啊哈,我在Webpack CLI参考文档中找到了这个故障排除指南

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for ./webpack.config.ts

You might encounter this error in the case of using native ESM in TypeScript (i.e. type: "module" in package.json).

webpack-cli supports configuration in both CommonJS and ESM format, at first it tries to load a configuration using require(), once it fails with an error code of 'ERR_REQUIRE_ESM' (a special code for this case) it would try to load the configuration using import(). However, the import() method won't work with ts-node without loader hooks enabled (described at TypeStrong/ts-node#1007).

To fix the error above use the following command:

NODE_OPTIONS="--loader ts-node/esm" npx webpack --entry ./src/index.js --mode production
那个页面的搜索引擎优化一定很差。希望在这里链接它可以稍微提升一下它的排名。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接