1.创建项目骨架
新建三个文件夹,分别命名为 app,server,tasks。其中 app 里面放置我们写的 js 代码和视图(HTML)代码,error.ejs 指向出错界面,index.ejs 是默认页面。server 放置服务端代码。tasks 中放置构建工具的任务,util 下的 args.js 是处理命令行参数的一个文件。
2. 使用express脚手架创建服务端代码
进入 server 文件夹,一句命令 express -e .
,-e 代表使用 ejs 模板引擎。ejs 是嵌入式 JavaScript 模板,文件以 .ejs 结尾。
输入这句命令后(首先要 npm install express)会提示 npm install 安装所需的依赖,安装完成后,server 文件夹下目录结构增加了这么多:
3.在 tasks 文件夹下创建构建工具
util/args.js
/**
* 对命令行参数进行解析
*/
// node.js 命令行框架
import yargs from 'yargs';
const args = yargs
.option('production', {
// 生产环境,默认关闭
boolean: true,
default: false,
describe: 'min all scripts'
})
.option('watch', {
// 监听开发环境中的文件,自动更新
boolean: true,
default: false,
describe: 'min all files'
})
.option('verbose', {
// 输出命令行执行日志
boolean: true,
default: false,
describe: 'log'
})
.option('sourcemaps', {
// 压缩
describe: 'force the creation of sourcemaps'
})
.option('port', {
// 服务器端口
string: true,
default: 8080,
describe: 'server port'
})
.argv;
export default args;
创建 scripts.js、pages.js、css.js、server.js
/**
* gulp 自动化配置
* 处理 js 代码
*/
import gulp from 'gulp';
// gulp 判断语句
import gulpif from 'gulp-if';
// 字符串拼接
import concat from 'gulp-concat';
// 构建
import webpack from 'webpack';
// 基于流的构建
import gulpWebpack from 'webpack-stream';
// 处理文件信息流
import plumber from 'gulp-plumber';
// 文件命名
import named from 'vinyl-named';
// 文件重命名
import rename from 'gulp-rename';
// 浏览器热更新
import livereload from 'gulp-livereload';
// css、js压缩
import uglify from 'gulp-uglify';
// 命令行输出
import { log, colors } from 'gulp-util';
// 对命令行参数进行解析
import args from './util/args';
// 使用 gulp 创建一个任务
gulp.task('scripts', () => {
return gulp.src('app/js/*.js')
// 错误日志检查处理
.pipe(plumber({
errorHandle: function() {
}
}))
// 文件命名
.pipe(named())
// 遇到 js 文件时,用 babel 处理
// npm install babel-loader babel-core babel-preset-env --save-dev
.pipe(gulpWebpack({
module: {
loaders: [{
test: /\.js$/,
loader: 'babel'
}]
}
}), null, (err, stats) => {
log(`Finished '${colors.cyan('scripts')}'`, stats.toString({
chunks: false
}));
})
// 文件存放路径
.pipe(gulp.dest('server/public/js'))
// 备份并重命名
.pipe(rename({
basename: 'cp',
extname: '.min.js'
}))
// 压缩
.pipe(uglify({
compress: {
properties: false
},
output: {
'quote_keys': true
}
}))
// 文件存放路径
.pipe(gulp.dest('server/public/js'))
// 热更新,若命令行中有 watch 这个参数才执行
.pipe(gulpif(args.watch, livereload()));
});
/**
* gulp 自动化配置
* 处理模板 views 信息
*/
import gulp from 'gulp';
// gulp 判断语句
import gulpif from 'gulp-if';
// 浏览器热更新
import livereload from 'gulp-livereload';
// 对命令行参数进行解析
import args from './util/args';
// 使用 gulp 创建一个任务
gulp.task('pages', () => {
return gulp.src('app/**/*.ejs')
// 文件存放路径
.pipe(gulp.dest('server'))
// 热更新,若命令行中有 watch 这个参数才执行
.pipe(gulpif(args.watch, livereload()));
});
/**
* gulp 自动化配置
* 处理 css 文件
*/
import gulp from 'gulp';
// gulp 判断语句
import gulpif from 'gulp-if';
// 浏览器热更新
import livereload from 'gulp-livereload';
// 对命令行参数进行解析
import args from './util/args';
// 使用 gulp 创建一个任务
gulp.task('styles', () => {
return gulp.src('app/**/*.css')
// 文件存放路径
.pipe(gulp.dest('server/public'))
// 热更新,若命令行中有 watch 这个参数才执行
.pipe(gulpif(args.watch, livereload()));
});
/**
* gulp 自动化配置
* 处理服务器的脚本
*/
import gulp from 'gulp';
// gulp 判断语句
import gulpif from 'gulp-if';
// 启动服务器
import liveserver from 'gulp-live-server';
// 对命令行参数进行解析
import args from './util/args';
// 使用 gulp 创建一个任务
gulp.task('serve', (cb) => {
// 若命令行不处于监听状态,返回
// if (!args.watch) {
// return cb();
// }
// 创建一个服务器并启动
var server = liveserver.new(['--harmony', 'server/bin/www']);
server.start();
// 热更新
gulp.watch(['server/public/**/*.js', 'server/public/**/*.css', 'server/views/*.ejs'], (file) => {
server.notify.apply(server, [file]);
});
// 需要重启服务器才能更新
gulp.watch(['server/routes/**/*.js', 'server/app.js'], () => {
server.start.bind(server)();
});
});
要热更新 (控制台输入 gulp --watch
实时监控文件变化),还必须在服务器代码上加 app.use(require('connect-livereload')))
这句代码。位置在
server/app.js:
app.use()使用的中间件的顺序不能随意放,划线部分的代码必须放在那,即在监听根目录下的文件变化。
创建 browser.js
/**
* gulp 自动化配置
* 浏览器热更新监听
* 当 app/js 变化时,启动 task/scripts.js
* 当 app/css 变化时,启动 task/styles.js
* 当 app/views 变化时,启动 task/pages.js
*/
import gulp from 'gulp';
// gulp 判断语句
import gulpif from 'gulp-if';
// 浏览器热更新
import livereload from 'gulp-livereload';
// 命令行输出
import util from 'gulp-util';
// 对命令行参数进行解析
import args from './util/args';
// 使用 gulp 创建一个任务
gulp.task('browser', (cb) => {
if (!args.watch) {
return cb();
}
// 热更新
gulp.watch(['app/**/*.js'], ['scripts']);
gulp.watch(['app/**/*.css'], ['styles']);
gulp.watch(['app/**/*.ejs'], ['pages']);
});
clean.js
/**
* gulp 自动化配置
* 清空指定文件夹里的文件
*/
import gulp from 'gulp';
// 删除命令
import del from 'del';
// 对命令行参数进行解析
import args from './util/args';
// 使用 gulp 创建一个任务
gulp.task('clean', () => {
return del(['server/public', 'server/views']);
});
创建 build.js,按顺序依次执行各任务
/**
* gulp 自动化配置
* 设置 gulp task 的顺序
*/
import gulp from 'gulp';
// 删除命令
import gulpSequence from 'gulp-sequence';
// 设置 gulp task 的顺序
// 使用 gulp 创建一个任务
gulp.task('build', gulpSequence('clean', 'styles', 'pages', 'scripts', ['browser', 'serve']));
default.js
/**
* gulp 自动化配置
* 默认文件
* 执行:gulp
*/
import gulp from 'gulp';
// 使用 gulp 创建一个任务
gulp.task('default', ['build']);
4. 放在项目最外面的 gulpfile.babel.js
gulpfile.babel.js(名字固定,且不为 gulpfile.js,,因为要使用 babel 转 ES6 语法.)
import requireDir from 'require-dir';
requireDir('./tasks');
最好的写法是将 tasks 下的文件全写在 gulpfile.babel.js 里,减少 js 文件有利于提升页面渲染速度,上面的分解步骤只是为了看的更容易。
5. 必不可少的 .babelrc 文件
{
// ES6 转 ES5
"presets": ["es2015"]
}
6. app/views/index.ejs 里编辑文件
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
test
</body>
</html>
在控制台输入 gulp --watch
打包文件,启动服务器,并实时监听,服务启动后,在浏览器地址栏输入 http://localhost:3000
可以看到test
字样,修改 index.ejs 里面的内容,不用刷新浏览器,gulp 会自动删除之前的打包后的文件重新编译生成新的文件并自动刷新浏览器。
网友评论