Gulp 自动化构建的一些过程,以及其他插件的结合使用等
起步
导出
项目根目录创建gulpfile.js
:
1 2 3 4 5 6
| function defaultTask(cb) { console.log("success"); cb(); }
exports.default = defaultTask;
|
gulp 命令:
1 2 3 4 5
| ➜ gulp-project git:(master) ✗ gulp [17:06:29] Using gulpfile ~/Documents/GitHub/gulp-project/gulpfile.js [17:06:29] Starting 'default'... success [17:06:29] Finished 'default' after 2.67 ms
|
Gulpfile 分割
Node 的模块解析功能允许你将 gulpfile.js’ 文件替换为同样命名为 gulpfile.js 的目录,该目录中包含了一个名为 index.js 的文件,该文件被当作 gulpfile.js 使用。并且,该目录中还可以包含各个独立的任务(task)模块。 — 官方文档
创建 gulpfile.js
目录,gulpfile.js
目录下新建 index.js
组合任务
- series() 允许将多个独立的任务组合为一个更大的操作
- 对于希望以最大并发来运行的任务(tasks),可以使用 parallel() 方法将它们组合起来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| const { series, parallel } = require("gulp");
function clean(cb) { cb(); }
function cssTranspile(cb) { cb(); }
function cssMinify(cb) { cb(); }
function jsTranspile(cb) { cb(); }
function jsBundle(cb) { cb(); }
function jsMinify(cb) { cb(); }
function publish(cb) { cb(); }
function build(cb) { cb(); }
exports.default = series( clean, parallel(cssTranspile, series(jsTranspile, jsBundle)), parallel(cssMinify, jsMinify), publish );
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| [16:50:36] Starting 'default'... [16:50:36] Starting 'clean'... [16:50:36] Finished 'clean' after 606 μs [16:50:36] Starting 'cssTranspile'... [16:50:36] Finished 'cssTranspile' after 199 μs [16:50:36] Starting 'jsTranspile'... [16:50:36] Finished 'jsTranspile' after 131 μs [16:50:36] Starting 'jsBundle'... [16:50:36] Finished 'jsBundle' after 125 μs [16:50:36] Starting 'cssMinify'... [16:50:36] Starting 'jsMinify'... [16:50:36] Finished 'cssMinify' after 183 μs [16:50:36] Finished 'jsMinify' after 218 μs [16:50:36] Starting 'publish'... [16:50:36] Finished 'publish' after 115 μs [16:50:36] Finished 'default' after 4.55 ms
|
当一个组合操作执行时,这个组合中的每一个任务每次被调用时都会被执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const { series, parallel } = require("gulp");
const clean = function(cb) { cb(); };
const css = series(clean, function(cb) { cb(); });
const javascript = series(clean, function(cb) { cb(); });
exports.default = parallel(css, javascript);
|
输出:
1 2 3 4 5 6 7 8 9 10
| [17:02:45] Starting 'default'... [17:02:45] Starting 'clean'... [17:02:45] Starting 'clean'... [17:02:45] Finished 'clean' after 850 μs [17:02:45] Starting '<anonymous>'... [17:02:45] Finished 'clean' after 2.04 ms [17:02:45] Starting '<anonymous>'... [17:02:45] Finished '<anonymous>' after 563 μs [17:02:45] Finished '<anonymous>' after 438 μs [17:02:45] Finished 'default' after 7.67 ms
|
重构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const { series, parallel } = require("gulp");
const clean = function(cb) { cb(); };
const css = function(cb) { cb(); };
const javascript = function(cb) { cb(); };
exports.default = series(clean, parallel(css, javascript));
|
再次输出:
1 2 3 4 5 6 7 8
| [17:04:48] Starting 'default'... [17:04:48] Starting 'clean'... [17:04:48] Finished 'clean' after 546 μs [17:04:48] Starting 'css'... [17:04:48] Starting 'javascript'... [17:04:48] Finished 'css' after 242 μs [17:04:48] Finished 'javascript' after 285 μs [17:04:48] Finished 'default' after 3.4 ms
|
异步执行
Node 库以多种方式处理异步功能。最常见的模式是 error-first callbacks,但是你还可能会遇到 streams、promises、event emitters、child processes, 或 observables。gulp 任务(task)规范化了所有这些类型的异步功能。 — 官方文档
1 2 3 4 5 6 7
| const { src, dest } = require("gulp");
function streamTask() { return src("*.js").pipe(dest("output")); }
exports.default = streamTask;
|
然后发现,根目录下会看到 output 目录,及根目录下所有以 *js
结尾的文件,包括目录。
1 2 3 4 5
| function promiseTask() { return Promise.resolve("the value is ignored"); }
exports.default = promiseTask;
|
返回 event emitter
1 2 3 4 5 6 7 8 9
| const { EventEmitter } = require("events");
function eventEmitterTask() { const emitter = new EventEmitter(); setTimeout(() => emitter.emit("finish"), 250); return emitter; }
exports.default = eventEmitterTask;
|
使用 callback
1 2 3 4 5 6
| function callbackTask(cb) { cb(); }
exports.default = callbackTask;
|
使用 async/await
1 2 3 4 5 6 7 8 9
| const fs = require("fs");
async function asyncAwaitTask() { const { version } = fs.readFileSync("package.json"); console.log("version"); await Promise.resolve("some result"); }
exports.default = asyncAwaitTask;
|
使用插件
1 2 3 4 5 6 7 8 9 10
| const { src, dest } = require("gulp"); const uglify = require("gulp-uglify"); const rename = require("gulp-rename");
exports.default = function() { return src("src/assets/**/*.js") .pipe(uglify()) .pipe(rename({ extname: ".min.js" })) .pipe(dest("output/")); };
|
browsersync
下载:
1
| npm install browser-sync gulp --save-dev
|
使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const { task, watch } = require("gulp"); const browserSync = require("browser-sync").create(); const reload = browserSync.reload; const serve = function(cb) { browserSync.init({ server: { baseDir: "./src", https: true, directory: true }, port: 8080, notify: false });
watch("src/*.html").on("change", reload); };
task(serve);
|
本地使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| const { src, dest, watch, series, parallel } = require("gulp"); const uglify = require("gulp-uglify"); const rename = require("gulp-rename"); const browserSync = require("browser-sync").create(); const reload = browserSync.reload; const jsWatcher = watch("src/**/*.js"); const cssWatcher = watch("src/**/*.css"); const htmlWatcher = watch("src/**/*.html");
const clean = function(cb) { cb(); };
const css = function(cb) { cb(); };
const javascript = function(cb) { cb(); };
const serve = function(cb) { browserSync.init({ server: { baseDir: "./src", directory: true }, port: 8080, notify: false }); };
jsWatcher.on("change", function(path, stats) { console.log(`File ${path} was changed`); });
cssWatcher.on("change", function(path, stats) { console.log(`File ${path} was changed`); });
htmlWatcher.on("change", function(path, stats) { console.log(`File ${path} was changed`); reload(); });
exports.build = function() { return src("src/assets/**/*.js") .pipe(uglify()) .pipe(rename({ extname: ".min.js" })) .pipe(dest("output/")); };
exports.serve = serve;
exports.default = series(clean, parallel(css, javascript));
|
然后在根目录下的package.json
,修改:
1 2 3 4 5
| "scripts": { "dev": "gulp", "build": "gulp build", "serve": "gulp serve" },
|
启动:
Gulp + SASS
-如何安装 Sass
1
| npm install node-sass gulp-sass --save-dev
|
gulpfile.js
文件主要配置如下:
1 2 3 4 5 6 7 8 9 10 11
| const { src, dest, watch } = require("gulp"); const sass = require("gulp-sass"); sass.compiler = require("node-sass");
function scss() { return src(scssGlobSrc) .pipe(sass({ outputStyle: "expanded" }).on("error", sass.logError)) .pipe(dest("dist/sass")); }
exports.scss = scss;
|
启动:gulp scss
。
Gulp + Browsersync
下载:
1
| npm install browser-sync gulp --save-dev
|
使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const { task, watch } = require("gulp"); const browserSync = require("browser-sync").create(); const reload = browserSync.reload;
const serve = function(cb) { browserSync.init({ server: { baseDir: "./src", https: true, directory: true }, port: 8080, notify: false });
watch("src/*.html").on("change", reload); };
exports.serve = serve;
|
运行:
Gulp + TypeScript
根目录下初始化:tsc --init
。
安装依赖:
1
| npm i -D typescript gulp-typescript
|
配置:
1 2 3 4 5 6 7 8 9 10 11
| const ts = require("gulp-typescript"); const tsProject = ts.createProject("tsconfig.json");
function typescript() { return tsProject .src() .pipe(tsProject()) .js.pipe(dest("dist/ts")); }
exports.typescript = typescript;
|
src 目录下新建文件 main.ts
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Student { fullName: string; constructor(public firstName: string, public lastName: string) { this.fullName = `${firstName} ${lastName} `; } }
interface Person { firstName: string; lastName: string; }
function greeter(person: Person) { console.log(`hello, ${person.firstName} ${person.lastName}`); }
let user = new Student("Yang", "Tao");
greeter(user); console.log(user.fullName);
|
运行:
Riot