本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-05-21
安装:npm install -g gulp
在根目录创建配置文件gulpfile.js
编写测试代码:
var gulp = require('gulp');
gulp.task('default', function() {
console.log('Hello gulp');
})
// 在根目录执行gulp命令,会在当前目录搜索gulpfile.js文件,然后执行default任务
使用插件gulp-tslint
检查代码的质量:
// 安装 npm install gulp-tslint --save-dev
var tslint = require('gulp-tslint');
gulp.task('lint', function() {
return gulp.src([
'./source/ts/**/**.ts', './test/**/**.test.ts'
]).pipe(tslint())
.pipe(tslint.report('verbose'));
})
// gulp的src函数会查找./source/ts目录及其子目录下的所有ts文件
// 以及.test目录以及其子目录下的所有扩展名为.test.ts的文件
// src函数的输出流将会被pipe函数重定向tslint函数的输入
// tslint函数的输出重定向为tslint.report函数的输入
gulp.task('default', ['lint']); // 指明lint为default任务的第一个子任务
许多插件允许我们使用!
来忽略一些文件,例如!path/*.d.ts
会忽略path目录下的所有扩展名为.d.ts
的文件;
编译TypeScript代码:
// 安装gulp-typescript插件 npm install gulp-typescript --save-dev
var ts = require('gulp-typescript');
var tsProject = ts.createProject({
removeComments: true,
noImplicitAny: true,
target: 'ES3',
module: 'common.js',
declarationFiles: false
})
// gulp-typescript插件宣布通过tsconfig.json的文件进行配置
gulp.task('tsc', function() {
return gulp.src('./source/ts/**/**.ts')
.pipe(ts(tsProject))
.js.pipe(gulp.dest('./temp/source/js'));
})
// tsc任务会去查找./source/ts目录及其子目录下的ts文件将其交给编译器
// 编译器根据tsProject对象的属性为编译时的参数,将编译后的JavaScript代码保存在./temp/source/js录下
// 对于测试文件,应该有专门的编译配置
var tsTestProject = ts.createProject({
// ...
});
gulp.task('tsc-tests', function() {
return gulp.src('./test/**/**.test.ts')
.pipe(ts(tsTestProject))
.js.pipe(gulp.dest('./temp/test/'));
})
// 更新default任务
gulp.task('default', ['lint', 'tsc', 'tsc-tests']);
优化打包成高度优化的js文件,使用Browserify插件:
// 安装依赖 npm install browserify vinyl-transform gulp-uglify gulp-sourcemaps
var browserify = require('browserify'),
transform = require('vinyl-transform'),
uglify = require('gulp-uglify'),
sourcemaps = require('gulp-sourcemaps');
var browserified = transform(function (filename) {
var b = browserify({
entries: filename,
debug: true
});
return b.bundle();
})
// browserified函数用来将普通的Node.js流转换为Gulp流
gulp.task('bundle-js', function() {
return gulp.src('./temp/source/js/main.js')
.pipe(browserified)
.pipe(sourcemaps.init({ loadMaps: true}))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./dist/source/js/'))
})
// 将main.js作为入口,Browserify会从这个入口出发,追踪应用里所有的模块和依赖
// 生成一个高度优化的JavaScript文件流
// 接着使用uglify插件来最小化输出 (压缩),但是这样会让bug难以追踪
// 所以生成source map来简化追踪bug的过程
// 打包优化test代码 因为不需要优化单元测试代码的下载时间 所以不需要uglify和source map
gulp.task('bundle-test', function() {
return gulp.src('./temp/test/**/**.test.js') // 允许多个入口
.pipe(browserified)
.pipe(gulp.dest('./dist/test/'))
})
// 更新default任务
gulp.task('default', ['lint', 'tsc', 'tsc-tests', 'bundle-js', 'bundle-test']);
实际项目中,应该是编译之后直接优化打包,而不是编译之后存放在temp临时目录,然后再写任务去打包;这样分开步骤描述只是为了方便理解;、
此时执行gulp的default任务,会遇到一些问题,因为所有的子任务是并行执行的;下面学习如何控制任务的执行顺序:
// 使用回调
gulp.task('sync', function (cb) {
setTimeout(function () {
cb();
}, 100)
})
// 或者 返回一个流
gulp.task('sync', function () {
return gulp.src('js/*.js')
.pipe(concat('script/min/js'))
.pipe(uglify())
.pipe(gulp.dest('../dist/js'));
})
// 同步任务放在sync任务后面
gulp.task('secondTask', ['sync'], function() {
// 这个任务在sync任务完成前都不会执行,这个回调会在任务数组中的所有任务执行完成后执行
// 第二个参数 任务数组中还可以添加别的任务 但是里面的任务是并行执行的
})
可以使用run-sequence插件来更好的控制任务顺序
// 安装 npm install run-sequence
var runSequence = require('run-sequence');
gulp.task('default', function(sb) {
runSequence(
'lint',
['tsc', 'tsc-tests'],
['bundle-js', 'bundle-test'],
'karma',
'browser-sync',
cb
)
})
// 先执行lint,再并行执行tsc, tsc-tests,... 这样依次执行
但是,最新版的gulp已经不再支持同步任务,需要使用回调,Promise, async/await来完成相关同步操作;
单元测试:是指针对代码中的某个函数或某个部分(单元)进行的测试,通过单元测试,可以保证函数按照预期在工作;
使用自动化测试工具Karma以及测试框架Mocha、断言库Chai、数据模拟框架Sinon,可以自动在多个浏览器执行应用内的测试套件,而不必手动打开浏览器进行测试;
// 安装测试框架 npm install mocha chai sinon --save-dev
// 安装Karma相关包 npm install karma karma-mocha karma-chai karma-sinon karma-coverage karma-phantomjs-launcher gulp-karma --save-dev
// 在gulpfile.js中添加一个新任务
var karma = require('karma');
gulp.task('karma', function(cb) {
gulp.src('./dist/test/**/**.test.js')
.pipe(karma({
configFile: 'karma.conf.js',
action: 'run'
}))
.on('end', cb)
.on('error', function(err) {
throw err;
})
})
// karma.conf.js
module.exports = function(config) {
'use strict';
config({
basePath: '',
frameworks: ['mocha', 'chai', 'sinon'],
browsers: ['PhantomJs'],
reporters: ['progress', 'coverage'],
plugins: [
'karma-coverage',
'karma-mocha',
'karma-chai',
'karma-sinon',
'karma-phantomjs-launcher'
],
preprocessors: {
'./dist/test/*.test.js': ['coverage']
},
port: 9876,
colors: true,
autoWatch: false,
singleRun: false,
logLevel: config.LOG_INFO
})
}
// 这个配置文件告诉karma应用的根目录、框架(Mocha、Chai、Sinon)、浏览器(PhantomJS)、插件和需要报告的测试执行期间的信息
// PhantomJS是一个无界面的web浏览器,使用它就无须打开一个真正的web浏览器,而可以执行单元测试代码
// karma-coverage 用来检测代码中到底有百分之几的代码被测试到,即覆盖率,会在根目录生成一个coverage目录。
// 安装 browser-sync包 npm install browser-sync
// 先创建两个任务,即在修改了部分代码之后,执行测试、编译打包,然后再刷新浏览器查看效果
gulp.task('bundle', function(cb) {
runSequence('build', ['bundle-js', 'bundle-test'], cb);
})
gulp.task('test', function(cb) {
runSequence('bundle', ['karma'], cb);
})
var browserSync = require('browser-sync');
gulp.task('browser-sync', ['test'], function() {
browserSync({
server: {
baseDir: './dist'
}
});
return gulp.watch([
'./dist/source/js/**/*.js',
'./dist/source/css/**.css',
'./dist/test/**/**.test.js',
'./dist/data/**/**',
'./index.html'
], [browserSync])
})
// gulp.watch用来监控文件是否有变化,监听到变化后调用reload
// 重新执行test任务,test任务调用bundle任务,最后刷新浏览器
// 当我们执行browser-sync任务就会在默认浏览器中自动打开应用
// 默认为localhost:3000
// 同时browser-sync工具管理页面在localhost:3001上启动
// 打开3001,即可以配置远程调试参数和设备同步参数,将手机连接到本地的网络环境就能实现跨设备测试
// 能够做到在一台设备执行测试,自动在其他多台设备上重复系列动作
// 官方文档: http://www.browsersync.io/docs