|

Gulp:处理 Js 和 TypeScript 文件

TypeScript 作为 JavaScript 的超集,目前也在前后端广泛使用,TypeScript 之于 JavaScript 就好像 Less 之于 CSS。TypeScript 本身并不是一门独立的语言,它基于 JavaScript ,又高于 JavaScript ,主要用来解决一些 JavaScript 开发过程中不易解决的问题,而最重要的一点,就是解决 JavaScript 类型定义问题。

本篇主要以 TypeScript 为例,基于 Gulp 流程化工具,搭建 TypeScript 和 Js 的自动化工程。

搭建过程

Gulp提供的基于 的概念,可以说是指明了各种道路,基于这些流节点,可以有很多种方法来构建项目,这里我也已构建 js 为例,罗列两种方法。

方法1:基于 gulp-typescript 和 babel 的构建

假设 src/main.ts 的内容如下:

/**
 * @name        延时函数
 * @param   ms  延时毫秒数
 * @returns     Promise,resolve返回相对真实的延时毫秒数
 */
delay (ms: number) : Promise<number> {
  let start: any;
  return new Promise((resole) => {
    start = Date.now();
    setTimeout(() => {
        resole(Date.now() - start);
    }, ms);
  });
}

delay(1000).then(duration => console.log(`delay for ${duration} ms`));

很明显,这段 TypeScript 代码在浏览器上没法运行,需要对其进行转码,最后我们需要一段 ES5 语法的代码,因为目前只有 ES5 语法的代码才能在各种浏览器里顺利运行。

这里使用 gulp-typescript 插件现将 TypeScript 代码转换成 JavaScript 代码,再讲转换后的代码通过 gulp-babel 转换成 ES5 语法的代码,然后交给 gulp 的 dest 函数输出。

const { task, src, dest, series } = require("gulp");
const babel = require("gulp-babel");
const uglify = require("gulp-uglify");
const rename = require("gulp-rename");
const ts = require("gulp-typescript");
const tsproj = ts.createProject();

/*
task("build:less", () => {
  ...
})
*/

task("build:ts", () => {
  return src("src/js/*.ts")
    .pipe(tsproj())
    .pipe(babel({
      presets: ["@babel/env"]
    }))
    .pipe(uglify())
    .pipe(rename({ extname: ".min.js" }))
    .pipe(dest("build/js"))
});

exports.default = series("build:less", "build:ts");

流程中的 uglify 用于对转码后的 js 文件进行压缩,rename 用于将文件重命名。最后可以使用 watch 对 .ts 文件进行监听,文件修改保存后完成自动转码。

watch("src/js/*.ts", series("build:ts"));

以上是一个基于 gulp-typescript 和 babel 的转码过程,在这个过程中 gulp-typescript 用于将 TypeScipt 转码成 js 代码,babel 用于将 js 代码中ES5以上的语法进行降维,以便浏览器可以顺利运行。

方法2:基于Browserify的构建

除此使用 gulp-typescript 和 babel 以外,还可以用 browserify 工具进行转码和打包,直接构建成浏览器可以运行的 js 代码。

const { task, src, dest, series } = require("gulp");
const browserify = require("browserify");
const tsify = reqiure("tsify");
const source = require("vinyl-source-stream");
const rename = require("gulp-rename");
const buffer = require("vinyl-buffer");

/*
task("build:less", () => {
  ...
})
*/

task("build:ts", () => {
  return browserify("src/main.ts")
    .plugin(tsify)
    .bundle()
    .pipe(source("bundle.js"))
    .pipe(buffer())
    .pipe(uglify())
    .pipe(rename({ extname: ".min.js"}))
    .pipe(dest("build/js"));
});

watch("src/js/*.ts", series("build:ts"));

exports.default = series("build:less", "build:ts");

这个流程中,browserify 通过使用 tsify 插件解析 TypeScript ,由于 browserify 的特性,此时转码后的文件已经可以在浏览器运行,不过我后续还是增加了一些操作,在流程中可以看出。转码为 js 后,使用 vinyl-source-stream 插件将文件流转为 vinyl 流,然后使用 gulp-buffer 插件转为 uglify 可以支持的流,进而由 uglify 进行压缩,之后使用 gulp-rename 插件将文件重新命名为 .min.js ,然后使用 gulp 的 dest 函数输出到指定目录中,最后通过 watch 对 .ts 文件监听,以便能自动转码,整个过程一气呵成。

可以看出,通过 gulp 的构建对程序员是非常友好的,用户可以知道每一步应该做什么以及该怎么做。

Source Map

Source Map 的目的在上一篇转码 Less 的文章中已经介绍,主要是为了将浏览器中实际运行的脚本映射到我们开发过程中编辑的脚本,以便实现高效的调试。

这里依然使用 gulp-sourcemaps 插件来做源码的资源映射,以使用 babel 的方式举例。

...

const sourcemaps = require("gulp-sourcemaps");

task("build:ts", () => {
  return src("src/js/*.ts")
    .pipe(sourcemaps.init())
    .pipe(tsproj())
    .pipe(babel({
      presets: ["@babel/env"]
    }))
    .pipe(uglify())
    .pipe(rename({ extname: ".min.js" }))
    .pipe(sourcemaps.write("."))
    .pipe(dest("build/js"))
});

watch("src/js/*.ts", series("build:ts"));

exports.default = series("build:less", "build:ts");

执行转码编译后,处理生成目标 .min.js 文件外,还会生成一个 .map 的文件。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注