当前位置 主页 > 网站技术 > 代码类 >

    浅谈TypeScript 用 Webpack/ts-node 运行的配置记录

    栏目:代码类 时间:2019-10-29 21:04

    公司项目代码是用 TypeScript 写的, 中间遇到有些代码不要放到 Node 里面去跑.

    具体场景一些路由配置, 比较大的一块 JSON 数据定义在 TypeScript 里.

    我另外有增加脚本, 基于这些 JSON 数据用来生成切换路由的函数.

    这就需要运行 TypeScript 了, 而且可能包含一些额外的业务代码.

    首先 Node 运行 TypeScript 有提供 ts-node 用来处理.

    ts-node 会先编译 TypeScript 代码到 JavaScript, 再调用 Node 运行.

    不过这个办法有一些问题, 一个是 TypeScript 定义的路径配置不成功,

    另一个问题更麻烦点, 就是引用到的其他的浏览器端代码因为触发运行而引起报错.

    Webpack 打包 TypeScript Node 代码

    我先想到了一个相对省事的方案, 就是用 Webpack 对 TypeScript 进行打包.

    打包完成以后输出 JavaScript 代码. 而浏览器代码打包进去, 但不一定运行.

    由于 TypeScript 配置在 Webpack 当中引用有比较成熟的方案, 整个配置也写好:

    module.exports = {
     mode: "development",
     target: "node",
     entry: ["./example/gen-router.ts"],
     output: {
      filename: "gen-router.js",
      path: path.join(__dirname, "../", distFolder),
     },
     devtool: "none",
     module: {
      rules: [
       // 正常的 TypeScript 编译方式, 我这份是拷贝的.
       {
        test: /\.tsx?$/,
        exclude: [/node_modules/, path.join(__dirname, "scripts")],
        use: [
         { loader: "cache-loader" },
         {
          loader: "thread-loader",
          options: {
           workers: require("os").cpus().length - 1,
          },
         },
         {
          loader: "ts-loader",
          options: {
           happyPackMode: true,
           transpileOnly: true,
          },
         },
        ],
       },
      ],
     },
     // Node 模块, 写在 external 里面表明不需要进行打包. 注意 commonjs 前缀
     externals: {
      prettier: "commonjs prettier",
      "@jimengio/router-code-generator": "commonjs @jimengio/router-code-generator",
      fs: "commonjs fs",
      path: "commonjs path",
     },
     resolve: {
      extensions: [".tsx", ".ts", ".js"],
      modules: [path.join(__dirname, "example"), "node_modules"],
    
      // 引用 Plugin 用于读取 tsconfig.json 文件的配置
      plugins: [new TsconfigPathsPlugin({ configFile: path.join(__dirname, "../tsconfig.json") })],
     },
    };
    
    

    基于这个配置打包以后, TypeScript 的代码被打包好, 并且引用响应的 Node 模块.

    运行就满足需求了.

    这个方式对于其他的服务端渲染的 TypeScript 代码打包也是类似的.

    一些特殊的依赖如果不好处理, 可以放在 Webpack 当中进行打包和映射, 得到 js.

    ts-node 运行

    Webpack 配置相对直接运行 TypeScript 来说会复杂一点, 所以还是 ts-node 简单.

    在依赖少的项目当中, 我改成了用 ts-node 来进行编译运行. 配置如下

    {
     "compilerOptions": {
      "allowSyntheticDefaultImports": true,
      "experimentalDecorators": true,
      "sourceMap": true,
      "noImplicitAny": false,
      "noImplicitThis": true,
      "strictNullChecks": false,
      "moduleResolution": "node",
    
      // Node 当前还没有支持直接运行 import/export 语法, 需要编译到 CommonJS
      "module": "commonjs",
    
      "target": "es2016",
      "jsx": "react",
      "lib": ["es2016"],
      "types": ["node"],
      "baseUrl": "./example/",
      "paths": {
       "models": ["./example/models"]
      },
      "plugins": []
     }
    }