浅谈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代码
Apr 22 Javascript
jQuery创建平滑的页面滚动(顶部或底部)
Feb 26 Javascript
DOM基础教程之使用DOM
Jan 19 Javascript
jquery仿百度百科底部浮动导航特效
Aug 08 Javascript
jQuery获取单击节点对象的方法
Jun 02 Javascript
JS数组去掉重复数据只保留一条的实现代码
Aug 11 Javascript
Vuejs第九篇之组件作用域及props数据传递实例详解
Sep 05 Javascript
js设置文字颜色的方法示例
Dec 30 Javascript
js+html5实现复制文字按钮
Jul 15 Javascript
微信小程序使用modal组件弹出对话框功能示例
Nov 29 Javascript
基于jQuery Ajax实现下拉框无刷新联动
Dec 06 jQuery
简单了解JavaScript sort方法
Nov 25 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 反射机制实现动态代理的代码
2008/10/22 PHP
php 操作excel文件的方法小结
2009/12/31 PHP
jQuery 表格插件整理
2010/04/27 Javascript
js日历功能对象
2012/01/12 Javascript
jquery获取tr中控件值并操作tr实现思路
2013/03/27 Javascript
js实现在字符串中提取数字
2013/11/05 Javascript
纯css下拉菜单 无需js
2016/08/15 Javascript
详解vue.js组件化开发实践
2016/12/14 Javascript
JS实现仿百度文库评分功能
2017/01/12 Javascript
详解nodejs微信公众号开发——5.素材管理接口
2017/04/11 NodeJs
AngularJS 仿微信图片手势缩放的实例
2017/09/28 Javascript
使用Ajax和Jquery配合数据库实现下拉框的二级联动的示例
2018/01/25 jQuery
JavaScript异步加载问题总结
2018/02/17 Javascript
Vue SSR 组件加载问题
2018/05/02 Javascript
webpack4 从零学习常用配置(小结)
2019/05/28 Javascript
深入理解JS异步编程-Promise
2019/06/03 Javascript
p5.js临摹动态图形实现方法详解
2019/10/23 Javascript
WEB前端性能优化的7大手段详解
2020/02/04 Javascript
浅谈vue中get请求解决传输数据是数组格式的问题
2020/08/03 Javascript
详解JavaScript中的数据类型,以及检测数据类型的方法
2020/09/17 Javascript
对于Python的框架中一些会话程序的管理
2015/04/20 Python
各个系统下的Python解释器相关安装方法
2015/10/12 Python
Python中的os.path路径模块中的操作方法总结
2016/07/07 Python
用python 批量更改图像尺寸到统一大小的方法
2018/03/31 Python
Django 实现购物车功能的示例代码
2018/10/08 Python
Pytorch实现的手写数字mnist识别功能完整示例
2019/12/13 Python
安装完Python包然后找不到模块的解决步骤
2020/02/13 Python
Python3的socket使用方法详解
2020/02/18 Python
canvas需要在标签里直接定义宽高
2014/12/17 HTML / CSS
高档奢华时装在线目的地:FORWARD by elyse walker
2017/10/16 全球购物
美国首屈一指的礼品篮供应商:GiftTree
2018/01/06 全球购物
家长会学生家长演讲稿
2013/12/29 职场文书
2015年爱国卫生工作总结
2015/04/22 职场文书
工会文体活动总结
2015/05/07 职场文书
团组织推荐意见
2015/06/05 职场文书
大学生安全教育主题班会
2015/08/12 职场文书