网站搜索

javascript - 在编译 TypeScript 时如何处理外部模块?


我对 TypeScript 很陌生,我正在尝试很多东西,并且在编译后卡在了外部模块上。

我在 Visual Studio Code 中从一个简单的 TypeScript 项目开始,目标设置为 ES2015,模块设置为 es2015(因为我想尽可能使用原生功能),我想尝试使用 Strongly Type Events (STE),它是通过 npm 安装的。

通过将模块解析更改为 node 并在 tsconfig.json 中设置 baseUrl,TypeScript 在使用非相对导入的 STE 时没有问题:

import { SimpleEventDispatcher } from "ste-simple-events";

然而,当我编译 TypeScript 时,生成的 JavaScript 文件具有完全相同的 import 语句,当加载包含该模块的 HTML 时,我收到一个找不到模块的错误。

我无法弄清楚如何解决这个问题。TypeScript 是否应该以某种方式将 import 语句改为 STE 的确切位置?也许如此,但 TypeScript 团队表示,TypeScript 编译永远不会更改 import 语句中的代码。

还是我也应该以某种方式编译外部模块,以便它们被包含在输出中?

还是应该由浏览器实现的 ES2015 标准中的默认模块解析来完成这个工作——对于它是如何工作的以及外部 ES2015 模块应该如何在 JavaScript 中导入,我完全不知道?

任何帮助或指引我走向正确方向的推动都会非常感激。

谢谢你,马里奥

答案#1

对于任何为此而挠头的 TypeScript 初学者,答案叫做 JavaScript 打包器。

由于我正在使用 ES6,我选择了 RollupJs 打包器,并结合以下插件(按此顺序使用它们):

  1. rollup-plugin-resolve - 用于解析 node_modules 的必需插件
  2. rollup-plugin-commonjs - 需要将 node_modules 中的 CommonJS 模块转译为 ES6
  3. rollup-plugin-typescript2 - 可选,你可以在打包过程中使用它,或者在运行 rollup 之前手动使用 tsc - 只要确保你使用的是版本 2(第一个版本不再维护)
  4. rollup-plugin-terser - 压缩器和混淆器

你可以通过 npm 安装所有这些:npm install rollup rollup-plugin-resolve rollup-plugin-commonjs rollup-plugin-typescript2 rollup-plugin-terser

将 rollup.config.js 添加到项目的根目录,我的文件看起来是这样的:

    import typescript from "rollup-plugin-typescript2"
    import commonjs from "rollup-plugin-commonjs";
    import resolve from "rollup-plugin-node-resolve";
    import { terser } from "rollup-plugin-terser";
    import pkg from "./package.json"

    export default {
        input: "./wwwroot/js/svgts.js",
        output: [
            {
                file: pkg.module,
                format: "esm",
            },
        ],
        external: [
            ...Object.keys(pkg.dependencies || {}),
            ...Object.keys(pkg.peerDependencies || {}),
        ], plugins: [
            resolve({
                mainFields: ["module"], // Default: ["module", "main"]
            }),

            commonjs({
                include: "node_modules/**"
            }),

            typescript({
                typescript: require("typescript"),
                tsconfig: "./tsconfig.json"
            }),

            (process.env.NODE_ENV === "production" && terser({
                mangle: { reserved: ['svg'] }
            }))
        ],
    }

Rollup 支持环境变量,我在这里使用了这行代码:process.env.NODE_ENV === "production"

这允许你在 package.json 中创建 npm 脚本,以便轻松选择是否进行压缩,例如:

"scripts": {
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "rollup": "rollup -c",
    "rollupw": "rollup -cw",
    "start": "concurrently \"npm run rollupw\" \"npm run lite\"",
    "startprod": "NODE_ENV=production concurrently \"npm run rollupw\" \"npm run lite\"",
    "production": "NODE_ENV=production npm run rollup"
  },

然后你可以在终端中运行 npm run production,例如来构建压缩的包。

你可以在每个项目的 GitHub 上找到更多详情。