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


Posted in Javascript onOctober 11, 2019

公司项目代码是用 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": []
 }
}

其实主要修改就 commonjs 那一行, 然后就是加上参数运行

ts-node -P tsconfig-node.json -r tsconfig-paths/register example/gen-router.ts

注意命令当中的 tsconfig-paths. 这里的 -r 是指定 register.

ts-node 是先进行编译再运行的, 但是引用的路径没有全都替换掉.

比如我在 tsconfig.json 里设置了 baseUrl 然后内部引用是简写的, a/b/c,

拿到 Node 本身去运行的时候是不知道这个 a/b/c 对应到哪里,

所以 tsconfig-paths/register 就提供 Node 运行时的方案, 动态查找依赖.

至少这样 Node register 改写以后, 查找模块就能正确进行了.

其他

另外 TypeScript 编译 import 语法时会产生一个 .default 属性.

对于 CommonJS 的模块, 这个 .default 属性是多余的. 所以引用的写法要做调整.

import * as fs from "fs";
import * as path from "path";
import * as prettier from "prettier";

这个可能跟 tsconfig.json 里其他的配置有关联, 我没继续深挖.

整体的代码参考 https://github.com/jimengio/meson-form/pull/62/files

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js中string转int把String类型转化成int类型
Aug 13 Javascript
js中confirm实现执行操作前弹出确认框的方法
Nov 01 Javascript
AngularJS初始化静态模板详解
Jan 14 Javascript
js阻止浏览器默认行为的简单实例
May 15 Javascript
jquery自适应布局的简单实例
May 28 Javascript
js H5 canvas投篮小游戏
Aug 18 Javascript
详解在WebStorm中添加Vue.js单文件组件的高亮及语法支持
Oct 21 Javascript
微信小程序配置服务器提示验证token失败的解决方法
Apr 03 Javascript
详解Vue路由自动注入实践
Apr 17 Javascript
vue2.0 获取从http接口中获取数据,组件开发,路由配置方式
Nov 04 Javascript
vue-cli3使用mock数据的方法分析
Mar 16 Javascript
Angular+Ionic使用queryParams实现跳转页传值的方法
Sep 05 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
Oct 11 #Javascript
JsonProperty 的使用方法详解
Oct 11 #Javascript
vue element upload组件 file-list的动态绑定实现
Oct 11 #Javascript
解决Idea、WebStorm下使用Vue cli脚手架项目无法使用Webpack别名的问题
Oct 11 #Javascript
微信小程序 点击切换样式scroll-view实现代码实例
Oct 11 #Javascript
vue控制多行文字展开收起的实现示例
Oct 11 #Javascript
这15个Vue指令,让你的项目开发爽到爆
Oct 11 #Javascript
You might like
php cookie 作用范围?不要在当前页面使用你的cookie
2009/03/24 PHP
destoon设置自定义搜索的方法
2014/06/21 PHP
Laravel实现表单提交
2017/05/07 PHP
Yii2.0实现的批量更新及批量插入功能示例
2019/01/29 PHP
PHP错误提示It is not safe to rely on the system……的解决方法
2019/03/25 PHP
如何用javascript判断录入的日期是否合法
2007/01/08 Javascript
Javascript 两个窗体之间传值实现代码
2009/09/25 Javascript
两个listbox实现选项的添加删除和搜索
2013/03/01 Javascript
判断某个字符在一个字符串中是否存在的js代码
2014/02/28 Javascript
JavaScript中的索引数组、关联数组和静态数组、动态数组讲解
2014/11/08 Javascript
jquery仿百度经验滑动切换浏览效果
2015/04/14 Javascript
js实现不提交表单获取单选按钮值的方法
2015/08/21 Javascript
js HTML5多媒体影音播放
2016/10/17 Javascript
在javascript中,null>=0 为真,null==0却为假,null的值详解
2017/02/22 Javascript
jQuery 表单序列化实例代码
2017/06/11 jQuery
浅谈vue中改elementUI默认样式引发的static与assets的区别
2018/02/03 Javascript
基于vue1和vue2获取dom元素的方法
2018/03/17 Javascript
JS实现字符串翻转的方法分析
2018/08/31 Javascript
小程序实现订单倒计时功能
2019/04/23 Javascript
浅谈鸿蒙 JavaScript GUI 技术栈
2020/09/17 Javascript
让python json encode datetime类型
2010/12/28 Python
Python中的ctime()方法使用教程
2015/05/22 Python
Pycharm取消py脚本中SQL识别的方法
2018/11/29 Python
Pandas之ReIndex重新索引的实现
2019/06/25 Python
python3光学字符识别模块tesserocr与pytesseract的使用详解
2020/02/26 Python
Python requests模块session代码实例
2020/04/14 Python
我们是伦敦女孩:WalG
2018/01/08 全球购物
工程项目经理岗位职责
2013/12/15 职场文书
《小白兔和小灰兔》教学反思
2014/02/18 职场文书
学校周年庆活动方案
2014/08/22 职场文书
学习普通话的体会
2014/11/07 职场文书
女儿满月酒致辞
2015/07/29 职场文书
Windows下使用Nginx+Tomcat做负载均衡的完整步骤
2021/03/31 Servers
python 实现mysql自动增删分区的方法
2021/04/01 Python
python 遍历磁盘目录的三种方法
2021/04/02 Python
微软发布Windows 11今年最大更新22H2(附 ISO 镜像官方下载)
2022/09/23 数码科技