用 TypeScript 写 gulp 构建

我在项目中经常使用前端构建技术来生成网页需要脚本和样式表。多数时候是采用 gulp + webpack (babel-loader | ts-loader) 的方案,在 Node7 下运行甚至可以使用 async 语法——当然大部分都是配置,只在 gulpfile.js 里会有少量的脚本代码。

注:node7 在 7.6 以前需要 --harmony_async_await 来支持 async function 语法,但从 7.6 开始不再需要这个参数。

不过最近遇到一点麻烦,因为我们需要使用 gulp 来构建一堆文档。文档是用 Markdown 写的,需要构建成静态 HTML 页面。考虑过 Jekyll,但是团队里没有人用过。所以最终决定用 marked 来转换 Markdown,自己写脚本定制——gulp 里引入逻辑模块是很容易的事件,跟写 node 程序一样。

但是构建文档这个需求与之前的构建有很大不同。之前的构建几乎只需要配置,而这次需要写大量的业务代码,这就意味着产生 BUG 的风险大大增加。按惯例,业务逻辑我们通常会用 TypeScript 来写,TypeScript 的静态类型特性会在我们编写代码的时候(配合合适的编辑器,比如 VSCode)就检查不少问题出来,能大大降低产生 BUG 的风险。

我们初步的方案是,像其它前端脚本类似,用 TypeScript 写完了使用 tsc 转译成 JavaScript,再用 gulp 来运行 JavaScript 生成文档。方案虽然可行,但却将构建过程的复杂度增加了一倍。要是 Node 能直接运行 TypeScript 就好了……

用 Node 直接运行 TypeScript,有这种想法的人肯定不只我一个。而且之前也曾了解到 babel-register (或 "babel-core/register") 可以改变 Node 的 require,在加载脚本的时候先对其进行转译。既然技术上是可行的,那就是找有没有现成的实现了。

通过 typescript node 关键字找到了 npm 上的 tyepscript-node 模块,而这个模块说明文档的第一句话就写着:

DEPRECATED: Use ts-node instead.

所以我们要找的实际上是 ts-node。它的文档中还专门提到创建 gulpfile.ts 文件,然后直接运行 gulp 就行。

为了试验 gulp 直接运行 TypeScript 脚本。先建了一个临时的 Node 项目目录,安装 gulp 模块。再建立一个 gulpfile.ts 测试文件,使用 TS 支持但 Node 不运行的 import 语法

import gulp = require("gulp");

gulp.task("default", () => {
    console.log("hello, gulp with typescript");
});

然后运行(当前是Windows环境)。在没添加 ts-node 模块之前,运行结果会抛出一些错误

clipboard.png

好吧,gulp 想得还是挺周到,居然尝试了 4 个 typescript node register 模块。其中 ts-node 是首先尝试的,且当它是 gulp 推荐的。typescript-node 已经申明用 ts-node 替代了。

现在我们安装 ts-node 模块,之后再运行一次

clipboard.png

gulp 提示它使用了 ts-node 模块,不过因为没有安装 typescript 模块,所以运行失败。安装好 typescript 模块之后再试一次,

clipboard.png

运行成功。

顺便提一下,如果不是构建应用,而是 Node Web 应用,需要注册 ts-node,它的文档中提供了两个方法

require("ts-node").register({ /* options */ });

上面这种方法可以加一些选项,这些选项并不是 tsconfig.js 中的选项,而是 ts-node 自己的一些选项,具体可以参考 ts-node 的文档

而下面这种方法,似乎是一种快捷方式,但它只能使用默认选项(多数情况下默认选项足够)。

require('ts-node/register')

ts-node 会自己加载使用 tsconfig.json。

当然,直接运行 node 程序的时候,不像 gulp 内置了注册和启动过程,所以需要一个 JavaScript 的启动程序,假设是 start.js,它应该这样写

// start.js
require('ts-node/register');
require("app")

当然,还可以加一些其它逻辑在里面,比如在开发环境下注册 ts-node 运行 app.ts,而在生产环境下直接运行转译好的 app.js。


边城客栈
全栈技术专栏,公众号「边城客栈」,[链接]

一路从后端走来,终于走在了前端!

57.4k 声望
27.7k 粉丝
0 条评论
推荐阅读
树,计算父节点的值
前段时间回答了一个类似的问题,产生了写一篇博客的想法。这个问题确实存在一些常见的的应用场景,比如一个多层组织结构中,已知每个员工的绩效分,希望计算各级部门的绩效分以便对部门评优。

边城7阅读 524评论 2

封面图
2022大前端总结和2023就业分析
我在年前给掘金平台分享了《2022年热点技术盘点》的前端热点,算是系统性的梳理了一下我自己对前端一整年的总结。年后,在知乎上看到《前端的就业行情怎么样?》,下面都是各种唱衰前端的论调,什么裁员,外包化...

i5ting27阅读 2.4k评论 4

封面图
过滤/筛选树节点
又是树,是我跟树杠上了吗?—— 不,是树的问题太多了!🔗 相关文章推荐:使用递归遍历并转换树形数据(以 TypeScript 为例)从列表生成树 (JavaScript/TypeScript) 过滤和筛选是一个意思,都是 filter。对于列表来...

边城17阅读 6.8k评论 3

封面图
vue-property-decorator使用手册
@Component 装饰器可以接收一个对象作为参数,可以在对象中声明 components ,filters,directives等未提供装饰器的选项,也可以声明computed,watch等

似曾相识17阅读 29.7k评论 7

JS 函数式概念: 管道 和 组合
微信搜索 【大迁世界】, 我会第一时间和你分享前端行业趋势,学习途径等等。本文 GitHub [链接] 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

前端小智9阅读 946

迁移 Vue v2.x 版本到 Vite
人生无常,大肠包小肠~在接近年底的时候,有一个 Vue 项目,需要从中抽取 2 个模块出来。然后想着新建项目,Vue CLI 也是学,Vite 也是学,于是哼次哼次用上了 Vite,结果开始了一路的 bug 挨打之旅……警告:本文...

jsliang11阅读 1.4k

封面图
Vue3 + Vite2 + TypeScript + Pinia(Vuex)+JSX 搭建企业级开发脚手架【开箱即用】
随着Vue3的普及,已经有越来越多的项目开始使用Vue3。为了快速进入开发状态,在这里向大家推荐一套开箱即用的企业级开发脚手架,框架使用:Vue3 + Vite2 + TypeScript + JSX + Pinia(Vuex) + Antd。废话不多话,...

阳晨@11阅读 3.5k

封面图

一路从后端走来,终于走在了前端!

57.4k 声望
27.7k 粉丝
宣传栏