ES6 - gulp 构建运行环境 - 最详细篇章
Posted 黑木令
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6 - gulp 构建运行环境 - 最详细篇章相关的知识,希望对你有一定的参考价值。
这篇文章主要讲解–构建脚本编码:
首先我们下来看下配置文件的整体目录: 配置文件一共是 9 个。 各个文件所对应的功能下面有具体且详细的解释 。
如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aSOTJYCx-1640682047531)(/Users/ouetsu/Documents/i-es6/ES6-基础-彩票demo/b-项目构建/imgs/02-02.png)]
1. 定义参数: 对命令行参数解析
1.1 配置文件在 tasks/util/args.js 文件中
1. 引入 'yargs'
1. 处理命令行参数 npm 包: import yargs from 'yargs'
2. 为了识别在命令行输入的 命令。
2. 定义基本参数:
1. 区分开发环境与线上环境
1. option: 用来配置参数, 用来区分命令行输入的是否有这个参数, 进而用来区分线上与开发环境 。
1.2 代码如下:
/**
定义参数: 对命令行参数解析
1. 区分开发环境和线上环境
*/
import yargs from 'yargs';
const args = yargs
// option: 用来配置参数, 用来区分命令行输入的是否有这个参数, 进而用来区分线上环境与开发环境 。
.option('production',
boolean: true, // 说明这个 production 选项是 bool 类型
default: false, // 设置 production 选项的默认值 (也就是命令行中没有输入 production 这个选项, 默认为 false, 开发环境 。 )
describe: '信息描述' // 描述信息, 机器一般不会去识别
) // 我们敲命令行时, 会有选项部分: gulp -production -> -production 就是他的选项部分 。
// 输入的参数, 是否用来监听开发环境中文件的修改, 并自动编译。
.option('watch',
boolean: true,
default: false,
describe: '信息描述'
)
// 是否要详细的输出命令行执行的日志
.option('verbos',
boolean: true,
default: false,
describe: '信息描述: 日志输出'
)
// 关于映射的内容
.option('sourcemaps',
describe: '信息描述: 强制生成 sourcemaps'
)
// 启动服务器的端口号设置
.option('port',
string: true, // 默认是字符串类型
default: 8080, // 默认端口号
describe: '信息描述: 设置端口号'
)
.argv // 标识对输入的命令行内容以字符串的形式解析
export default args
2. 对 .JS 做处理 (tasks/scripts.js)
1. 需要引入的包:
1. 'gulp' // gulp 处理的都是文件流, 它是基于 stream 的 。
2. 'gulp-if' // gulpif 是在 gulp 的语句做 if 判断的 。
3. 'gulp-concat' // 在 gulp 语句中处理文件拼接的 。
4. 'webpack' // 项目打包的过程是用的是 webpack 。
5. "webpack-stream"; // webpack 的处理是结合 webpack-stream 一起来做处理的 。
6. 'vinyl-named' // 对文件重命名的做标志的
7. gulp-livereload // 热更新包
8. gulp-plumber // 处理文件信息流的包
9. gulp-rename // 文件重命名的包
9. gulp-uglify // 处理 JS / CSS 压缩的一个包
10. gulp-util // 在命令行工具输出的包
11. args.js // 上面写好的对命令行参数解析
2. 安装上面所需的包 <如果自己配置时, 注意插件版本>
1. cnpm install gulp@3.9.1 gulp-if@2.0.2 gulp-concat@2.6.1 webpack@2.2.1 webpack-stream@3.2.0 vinyl-named@1.1.0 gulp-livereload@3.8.1 gulp-plumber@1.1.0 gulp-rename@1.1.0 gulp-uglify@2.1.0 gulp-util@3.0.8 yargs@7.0.2 --save-dev
1. --save-dev: 表示除了需要将这些包安装以外, 还要在 package.json 这个文件中创建一个安装包依赖的一些字段 。
代码如下:
// 创建构建脚本: 对 JS 做处理 。
/**
1. 引入 npm 包
1. gulp
*/
import gulp from 'gulp' // gulp 处理的都是文件流, 它是基于 stream 的 。
import gulpif from 'gulp-if' // gulpif 是在 gulp 的语句做 if 判断的 。
import concat from 'gulp-concat' // 在 gulp 语句中处理文件拼接的 。
import webpack from 'webpack' // 项目打包的过程是用的是 webpack 。
import gulpwebpack from "webpack-stream"; // webpack 的处理是结合 webpack-stream 一起来做处理的 。
import named from 'vinyl-named' // 对文件重命名的做标志的
/**
2. 浏览器在文件修改之后自动刷新的功能: 我们需要热更新的一个包
*/
import livereload from 'gulp-livereload'
/**
3. 处理文件信息流的包:
*/
import plumber from 'gulp-plumber'
/**
4. 对文件重命名的一个包
*/
import rename from 'gulp-rename'
/**
5. 压缩 JS 使用的包: 用来处理 JS / CSS 压缩的一个包
*/
import uglify from 'gulp-uglify'
/**
6. 在命令行工具输出的包:
*/
import logo, colors from 'gulp-util'
/**
7.
对命令行参数解析
*/
import args from './util/args.js'
/**
--save-dev: 标识文件除了安装以外, 还要在 package.json 文件中创建一个安装包依赖的一些字段
*/
/**
1. 创建 gulp 脚本编译任务
1. task 是 gulp 的一个 API , 用来创建任务
2. scripts 是 创建任务的名称
*/
gulp.task('scripts', () =>
// 任务执行的主题
return gulp.src(['app/js/index.js']) // app/js/index.js 打开当前目录
// 改变默认处理错误的机制, 集中处理脚本编译过程中出现的错误 。
.pipe(plumber(
errorHandler:function()
))
// 对文件重新命名
.pipe(named())
// 对 JS 进行编译 (这个时候借用 webpack 的功能)
.pipe(gulpwebpack(
// webpack-module: 模块
module:
loaders: [
// 遇到 js 文件, 使用 babel 去处理
test: /\\.js$/,
loader: 'babel'
]
), null, (err, stats) =>
log(`finihed '$colors.cyan('scripts')'`, stats.toString(
chunks: false
))
)
// 文件存放位置的设置 (将文件放入指定的路径) (问什么将文件放在 server 文件中: 因为 server 需要拿到最新的编译好的 js 文件才能够跑起来)
.pipe(gulp.dest('server/public/js'))
// 编译压缩的功能
.pipe(rename(
// 相当于将之前的文件复制了一份, 名字为: cp.min.js
basename: 'cp',
extname: '.min.js'
))
.pipe(uglify(
// 配置如何压缩
compress:
properties: false
,
output:
'quote_keys': true
))
// 将文件真正的存储到某个地方去
.pipe(gulp.dest('server/public/js'))
// 监听文件: 使用 gulpif 去判断, 然后在执行 livereload
.pipe(gulpif(args.watch, livereload()))
)
3. 处理 .egs 模板的构建脚本 (tasks/pages.js)
/**
* 处理 .egs 模板的构建脚本:
*/
import gulp from 'gulp' // gulp 处理的都是文件流, 它是基于 stream 的 。
import gulpif from 'gulp-if' // gulpif 是在 gulp 的语句做 if 判断的 。
import livereload from 'gulp-livereload' // 热更新的一个包 。
import args from './util/args.js' // 对命令行参数解析
// 创建任务
gulp.task('pages', () =>
// gulp 的所有任务创建, 都需要打开一个文件
return gulp.src('app/**/*.ejs') // **/* : 打开 app 文件夹下的所有 .egs 文件 (app 下各个嵌套的 .egs 文件)
// 将 app 下的所有 .egs 模板文件原封不动的拷贝到一个地方
.pipe(gulp.dest('server'))
// 热更新 监听
.pipe(gulpif(args.watch, livereload()))
)
4. 处理 css 的构建脚本 (tasks/css.js)
/**
* 处理 css 的构建脚本:
*/
import gulp from 'gulp' // gulp 处理的都是文件流, 它是基于 stream 的 。
import gulpif from 'gulp-if' // gulpif 是在 gulp 的语句做 if 判断的 。
// import liveserver from 'gulp-live-server' // 能够启动服务器的包
import livereload from 'gulp-livereload' // 热更新的一个包 。
import args from './util/args.js' // 对命令行参数解析
// 创建任务
gulp.task('css', () =>
// gulp 的所有任务创建, 都需要打开一个文件
return gulp.src('app/**/*.css') // **/* : 打开 app 文件夹下的所有 .egs 文件 (app 下各个嵌套的 .egs 文件)
// 将 app 下的所有 .css 模板文件原封不动的拷贝到一个地方
.pipe(gulp.dest('server/public'))
// // 热更新 监听 (根据项目需求决定是否需要热更新 CSS)
// .pipe(gulpif(args.watch, livereload()))
)
5. 处理 服务器 的构建脚本 (tasks/server.js)
/**
* 处理 服务器 的构建脚本:
*/
import gulp from 'gulp' // gulp 处理的都是文件流, 它是基于 stream 的 。
import gulpif from 'gulp-if' // gulpif 是在 gulp 的语句做 if 判断的 。
import liveserver from 'gulp-live-server' // 能够启动服务器的包
import args from './util/args.js' // 对命令行参数解析
gulp.task('server', (cb) => // 箭头函数传入回调 cb
// 如果不是处于监听状态下, 我们就直接返回回调函数 cb
if(!args.watch) return cb()
// 如果是处于监听状态下, 我们就创建一个服务器
var server = liveserver.new(['--harmony', 'server/bin/www']) // --harmony: 表示要在当前命令行下去执行这个脚本; server/bin/www: 这个是一个脚本 。
// 启动服务器
server.start()
// 我们构建脚本的目的不是单纯的只为了启动服务器, 而是包含了服务器下面所有的文件, 包括 CSS 、 JS 、 .egs 模板 发生改变的时候要实现热更新; 所以我们要监听 server 目录下的所有 .JS 、 .egs 模板 。
// 实现 浏览器热更新:
// gulp.watch(): 做文件监听, 监听的是一个数组, 表示需要监听那些路径
gulp.watch(['server/public/**/*.js', 'server/views/**/*.ejs'], function(file)
// 将文件改动告诉服务器(通知服务器去实现相应的功能)
server.notify.apply(server, [file])
)
// 监听需要重启服务的文件 (当服务器中的某些路由发生改变, 某些接口发生变化, 这个时候刷新浏览器是不行的, 而是需要 server 重启才能生效)
gulp.watch(['server/routes/**/*.js', 'server/app.js'], function()
server.start.bind(server)()
);
)
6. 清空任务在 (tasks/clean.js)
/**
* 清空任务在
*/
import gulp from 'gulp' // gulp 处理的都是文件流, 它是基于 stream 的 。
import del from 'del' // 删除动作的包
import args from './util/args.js' // 对命令行参数解析
// 创建任务: 清空两个目录
gulp.task('clean', () =>
// 清空 server/public 下的 js/css 。
// 清空 server/views 下的 ejs 模板 。
return del(['server/public', 'server/views'])
)
7. 实现文件自动变编译最后一个环节 (tasks/browser.js)
/**
* 实现文件自动变编译最后一个环节
*/
import gulp from 'gulp' // gulp 处理的都是文件流, 它是基于 stream 的 。
import gulpif from 'gulp-if' // gulpif 是在 gulp 的语句做 if 判断的 。
import gutil from 'gulp-util' // gulp 常用工具包: 函数集合
import liveserver from 'gulp-live-server' // 能够启动服务器的包
import args from './util/args.js' // 对命令行参数解析
// 创建任务
gulp.task('browser', (cb) =>
// 如果没有 watch 监听, 就返回回调 cb
if(!args.watch)
return cb()
// 监听 app 源目录下的 js 发生变化时的操作: 启动 tasks/scripts.js 任务脚本 (意思也就是当 app 目录下的 js 内容发生改变时, 会调用 scripts 任务脚本)
gulp.watch('app/**/*.js', ['scripts'])
// 监听 app 源目录下的 ejs 模板文件发生变化时的操作: 启动 tasks/pages.js 任务脚本
gulp.watch('app/**/*.ejs', ['pages'])
// 监听 app 源目录下的 css 发生变化时的操作: 启动 tasks/css.js 任务脚本
gulp.watch('app/**/*.css', ['css'])
/**
* 截止到上面的代码, 所有和任务相关的内容(单个任务)已经 做完了 。
* 1. 此时我们已经完成了 'browser' 与 'scripts、pages、css' 这个三个任务之间的关联关系;
* 2. 此时我们执行 browser 任务, 其实它只完成了文件的监听, 但是 启动服务 等等 我们要如何实现, 我们也不想再去单独执行一个 serveer 的命令, 然后再去执行 'browser' 这个, 这还是不能实现完全自动化 。
* 3. 我们要实现的就是将这些任务关联起来, 只执行一个命令让这些所有的脚本能够完全运行, 实现自动化 。
*
*
*
* 下面就是实现如何让这些任务自动的跑起来(即各个任务如何关联):
* 1. 在所有的任务进行自动创建的时候, 我们需要一个任务: '清空'
* 1. 清空是指清空指定文件的任务 。
* 1. app 前端原生文件存放的是 ES6 的代码, 最后到 server 目录下也就是在浏览器中运行的代码内容, server 目录下的代码已经是处理过的代码也就是 ES5/ES3 的代码;
* 2. server目录下这里有一个过程: 编译完成的代码有一个拷贝的过程 。
* 3. 当我们每次修改完成 app 目录下的内容时, 我们就需要覆盖 server 目录下对应的文件, 为了安全起见我们在每次生成重新拷贝时候我们需要把 server 目录下对应的文件清空;
* 4. 此时我们需要一个清空指定目录文件的任务 。
* 2. 清空任务在 tasks/clean.js 文件中
*/
)
8. 任务都串联起来 (tasks/build.js)
/**
* 为了把所有的任务都串联起来: 哪个任务在前那个任务在后, 谁依赖谁, 我们需要梳理清楚
*
* 下面再说 build.js 与默认的 default.js 有什么关联
*/
import gulp from 'gulp' // gulp 处理的都是文件流, 它是基于 stream 的 。
import gulpSequence from 'gulp-sequence' // 用来处理包的顺序问题
// 创建任务
// 注意: server 一定是放在最后面执行
gulp.task('build', gulpSequence('clean', 'css', 'pages', 'scripts', ['browser', 'server']))
9. 默认入口文件 (tasks/css.js)
/**
* 在执行 gulp 命令时, 如果不是 gulp XXX 文件, 那么它就会默认执行 default.js 文件
*/
import gulp from 'gulp' // gulp 处理的都是文件流, 它是基于 stream 的 。
// 创建任务
gulp.task('default', ['build'])
10. 环境配置成功之后我们运行gulp命令: gulp --watch, 就可以在我们的浏览器中正常解析 ES6 语法了 。
之前有整理过部分知识点, 现在将整理的相关内容, 验证之后慢慢分享给大家; 这个专题是 “前端ES6基础” 的相关专栏; 不积跬步,无以至千里, 戒焦戒躁 。
如果对你有所帮助,喜欢的可以点个关注; 文章会持续打磨 。
有什么想要了解的前端知识吗? 可以评论区留言, 会及时跟进分享所相关内容 。
整理知识点不易, 每次都是在工作繁忙之余夜深人静之时整理, 无论知识点是大是小, 都会验证后再分享, 以防自己发表的文章给大家造成误导 。如有问题还望不吝赐教,本人会及时更改 (本文原创, 如需转载,请注明出处) 。
以上是关于ES6 - gulp 构建运行环境 - 最详细篇章的主要内容,如果未能解决你的问题,请参考以下文章
第879期使用 Babel 和 Gulp 搭建 ES6 开发环境