借助gulp自动生成ts项目的声明文件

4,015

声明(declare)文件,是对整个ts项目输出物的描述。

本篇文章主要阐述:如何借助gulp打包编译并自动生成项目声明文件。

现有项目结构

  • root
    • index.ts
    • modules
      • a.ts
      • b.ts
      • c.ts

在build工作流中,我们需要做这样几件事:

  1. 清理 dist 目录
  2. 生成 declare 文件
  3. 清理多余 js 文件
  4. 转码 ts 并打包为单独的 js 包文件,并压缩输出

下面将按照这个流程一步步实施。

安装本地依赖

除了全局 gulp / typescript 之外,本地需要安装以下几个包:

  • gulp (1 ~ 4)
  • typescript (2, 3, 4)
  • gulp-clean (1, 3)
  • gulp-typescript (2)
  • browserify (4)
  • tsify (4)
  • gulp-uglify (4)
  • vinyl-buffer (4)
  • vinyl-source-stream (4)
npm i -D gulp typescript gulp-clean gulp-typescript browserify tsify gulp-uglify vinyl-buffer vinyl-source-stream

创建工作流

0. 声明各个模块

const gulp = require('gulp')
const clean = require('gulp-clean');
const ts = require('gulp-typescript')
const uglify = require('gulp-uglify')

const browserify = require('browserify')
const tsify = require('tsify')

const buffer = require('vinyl-buffer')
const source = require('vinyl-source-stream')

1. 清理 dist 目录

gulp.task('clean', function () {
    return gulp
    .src('dist', { read: false, allowEmpty: true })
    .pipe(clean('dist'));
});

注意 allowEmpty,允许被清除目录不存在。

2. 生成 declare 文件

gulp.task('tsc', () => {
    return gulp
    .src(['./*.ts', './!(node_modules)/*.ts'])
    .pipe(ts({
        // 这里对应参数 
        // { "declaration": true }
        // /* Generates corresponding '.d.ts' file. */
        declaration: true
    }))
    .pipe(gulp.dest('dist'))
})

这里配置 ts({ declaration: true }) 后,会针对每个 ts 文件产生一个 .js.d.ts 文件。

3. 清理多余 js 文件

这里针对第二步在 dist 中产生的多余 js 文件进行清理。

gulp.task('clean-js', function () {
    return gulp
    .src('dist/**/*.js', { read: false })
    .pipe(clean('*.js'));
});

这里注意下 gulp.src('dist/**/*.js') 选取目录下所有文件的写法。

4. 转码 ts 并打包为单独的 js 包文件,并压缩输出

gulp.task('build', () => {
    return browserify({
        basedir: '.',
        debug: true,
        entries: ['index.ts'],
        cache: {},
        packageCache: {}
    }).plugin(tsify).bundle()
    .pipe(source('index.js'))
    .pipe(buffer())
    .pipe(uglify())
    .pipe(gulp.dest('dist'))
})

关于 gulp-uglify 的使用,参考了下面的地址

www.npmjs.com/package/gul…

顺序执行所有任务

gulp.task('default'
    , gulp.series(
        gulp.parallel('clean'),
        gulp.parallel('tsc'),
        gulp.parallel('clean-js'),
        gulp.parallel('build')
    )
)

在终端执行:

% gulp
[18:29:42] Using gulpfile /ts-learn/declare/gulpfile.js
[18:29:42] Starting 'default'...
[18:29:42] Starting 'clean'...
[18:29:42] Finished 'clean' after 14 ms
[18:29:42] Starting 'tsc'...
[18:29:43] Finished 'tsc' after 1.1 s
[18:29:43] Starting 'clean-js'...
[18:29:43] Finished 'clean-js' after 6.29 ms
[18:29:43] Starting 'build'...
[18:29:44] Finished 'build' after 983 ms
[18:29:44] Finished 'default' after 2.11 s

编译完成,输出的 dist 目录结构为:

  • dist
    • index.d.ts
    • index.js
    • modules
      • a.d.ts
      • b.d.ts
      • c.d.ts

创建一个 test.js 文件

const { getA } = require('./dist')

此时VSCode可以提示并定位方法和属性的位置。

在NPM包中的应用

这里 dist 的结构,可以作为NPM包发布的结构,兼顾代码的私密和文档的友好。

项目的 package.json 可以配置为:

{
    // ...
    "main": "dist/index.js",
    // ...
}

包管理会将模块调用指向发布的 index.js,并自动识别和引用并排的 index.d.ts 文件所谓架构解释文档。


就酱