简体   繁体   English

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

[英]How to deal with external modules when compiling TypeScript?

I am very new to TypeScript and I am trying out many things and got stuck with external modules after compilation. 我是TypeScript的新手,我正在尝试许多事情,并且在编译后陷入了外部模块的困境。

I started with simple TypeScript project in Visual Studio Code set to target ES2015 and module to es2015 (because I want to use native stuff as much as possible) and I wanted to try Strongly Type Events (STE) which I installed using npm. 我从Visual Studio Code中的简单TypeScript项目开始,目标是将ES2015和es2015作为目标模块(因为我想尽可能多地使用本机内容),并且我想尝试使用npm安装的Strongly Type Events(STE)。

By changing module resolution to node and setting baseUrl in tsconfig.json , TypeScript has no problem in using STE with non-relative import: 通过改变模块的分辨率node和设置baseUrltsconfig.json ,打字稿在使用STE与非亲属的进口没有任何问题:

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

However, when I compile TypeScript, resulting JavaScript file has exact same import statement and when loading html which is including this module, I get an error that module cannot be found. 但是,当我编译TypeScript时,生成的JavaScript文件具有完全相同的import语句,并且在加载包含此模块的html时,出现错误,找不到模块。

I can not figure out how to solve this. 我不知道如何解决这个问题。 Should TypeScript somehow change import statement to exact location of STE? TypeScript是否应该以某种方式将import语句更改为STE的确切位置? Perhaps, but TypeScript team says TypeScript compilation will never change code in import statements. 也许吧,但是TypeScript团队说TypeScript编译永远不会更改import语句中的代码。

Or should I somehow compile external modules as well, so that they get included in output? 还是应该以某种方式编译外部模块,以使它们包含在输出中?

Or should default module resolution in ES2015 standard implemented in browsers do the job - for which I have no idea how it works and how should external ES2015 modules be imported in JavaScript? 还是应该在浏览器中实现的ES2015标准中的默认模块分辨率来完成这项工作-我不知道它如何工作以及如何将外部ES2015模块导入JavaScript?

Any help or a nudge in the right direction would be greatly appreciated. 朝正确方向的任何帮助或推动将不胜感激。

Thanks, Mario 谢谢,马里奥

For any TypeScript beginner scratching their head over this, the answer is called JavaScript bundlers. 对于任何TypeScript初学者over之以鼻,答案就是JavaScript捆绑器。

Since I am using ES6, I opted for RollupJs bundler combined with following plugins (use them in this order): 由于我使用的是ES6,因此我选择了RollupJs捆绑程序以及以下插件(按此顺序使用):

  1. rollup-plugin-resolve - required to resolve node_modules rollup-plugin-resolve -解析node_modules所需
  2. rollup-plugin-commonjs - required to transpile CommonJS modules in node_modules to ES6 rollup-plugin-commonjs将node_modules中的CommonJS模块转换为ES6所需
  3. rollup-plugin-typescript2 - optional, you can have it in the process or you can use tsc manually before you run rollup - just make sure you use version 2 (first version is not maintained any more) rollup-plugin-typescript2可选,您可以在运行过程中使用它,也可以在运行汇总之前手动使用tsc-只需确保使用版本2(不再维护第一个版本)
  4. rollup-plugin-terser - minifier and obfuscator rollup-plugin-terser -压缩器和混淆器

You can install all of those with npm: npm install rollup rollup-plugin-resolve rollup-plugin-commonjs rollup-plugin-typescript2 rollup-plugin-terser 您可以使用npm安装所有这些工具: npm install rollup rollup-plugin-resolve rollup-plugin-commonjs rollup-plugin-typescript2 rollup-plugin-terser

Add rollup.config.js to the root of your project, mine looked like this: 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 supports environment variables which I use here with line: process.env.NODE_ENV === "production" 汇总支持在此处与行一起使用的环境变量: process.env.NODE_ENV === "production"

This allows you to create npm scripts in package.json to easily include minification or not, for example: 这使您可以在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"
  },

Then you can run in terminal npm run production for instance to build minified bundle. 然后,您可以在终端npm run productionnpm run production以构建缩小的捆绑包。

You can find more details on GitHub of each project. 您可以在每个项目的GitHub上找到更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM