在网上观看ES6的学习视频,了解如何创建一个基础的ES6工程,包括命令行的处理、创建JS编译任务、创建模板、服务任务脚本、监听测试等
记录一下,供以后自己参考
下面出现的文件,如果没有自己创建,cmd下创建命令是cd.>文件名.js
,其它像git之类的是touch 文件名.js
所有的构建脚本一定是放在tasks目录下的,即上面创建的js文件一定是在tasks目录下的
一些文件需要引入一些包,所以要安装所需要的包,命令cnpm install 包名 --save-dev
npm也行,可以一次性安装多个包,把所需要安装的包名全写在install后面即可
包安装完成后,在根目录下的package.json文件里的devDependencies参数中就能看到所安装的包的信息
1. 命令行的处理 (tasks/util/args.js文件)
需要安装 yargs
包
cnpm install yargs --save-dev
代码:
import yargs from 'yargs'; //引入这个npm包来处理命令行参数
//通过使用 yargs 这个模块来处理命令行的参数,主要是方便处理命令行参数的捕获和过滤
//引入后,定义一些基本的参数
const args = yargs
//区分线上环境还是开发环境
//通过option来提取命令行的参数,来区分命令行输入的是否有这个参数,进而来区分它是线上还是开发环境
.option('production',{
boolean: true, //表示是一个Boolean类型
default: false, /*如果在命令行中没有输入production这个项,那么参数就默认false,
就是开发环境,有的话则为线上环境*/
describe: 'min all scripts' //描述 不会被解析
})
//设置watch参数,来控制监听开发环境中修改的这些文件要不要自动编译,也通过命令行来控制
.option('watch',{
boolean: true,
default: false,
describe: 'watch all files'
})
//要不要详细地输出命令行执行的日志
.option('verbose',{
boolean: true,
default: false,
describe: 'log'
})
//处理压缩的
.option('sourcemaps',{
describe: 'force the creation of sroucemaps'
})
//设置服务器端口,来启动服务器
.option('port',{
string: true,
default: 8080,
describe: 'server port'
})
.argv //表示对输入的命令行的内容以字符串作为解析
export default args;
2. 处理js的构建脚本 (tasks/scripts.js文件)
需要安装gulp gulp-if gulp-concat webpack webpack-stream vinyl-named gulp-livereload gulp-plumber gulp-rename gulp-uglify gulp-util
这些包
cnpm install gulp gulp-if gulp-concat webpack webpack-stream vinyl-named
gulp-livereload gulp-plumber gulp-rename gulp-uglify gulp-util --save-dev
同时,还需要安装 `babel-loader、babel-core、babel-preset-env` 这三个包
cnpm install babel-loader babel-core babel-preset-env webpack --save-dev
这里安装的babel-loader包版本号高了有可能会报错,如果报错提示是版本号高了的话,输入 cnpm install babel-loader@7.1.5
降低版本号
代码:
/*
处理js的构建脚本
所有的构建脚本一定是放在tasks目录下的
*/
//引入这个脚本所依赖的包
import gulp from 'gulp';//整个项目的构建都是基于gulp的基础上的
import gulpif from 'gulp-if';//gulp语句中做if判断的
import concat from 'gulp-concat';//gulp中处理文件拼接的
import webpack from 'webpack';//引入webpack工具包
import gulpWebpack from 'webpack-stream';/*gulp处理的都是些文件流,它是基于stream的,
所以引入webpack-stream包结合它来做处理*/
import named from 'vinyl-named';//对文件重命名做标志的
import livereload from 'gulp-livereload'; //热更新包,实现文件修改以后浏览器自动刷新等
import plumber from 'gulp-plumber'; // 处理文件信息流的,防止来自 gulp 插件错误导致中断操作的插件
import rename from 'gulp-rename'; // 文件重命名
import uglify from 'gulp-uglify'; // 用来处理js,css压缩的包
import {log,colors} from 'gulp-util'; //在命令行工具输出的包
import args from './util/args';//对命令行参数进行解析的一个包(开始自己写的那个)
//创建脚本编译的任务
//task、src等是gulp提供的一个标准的API,创建一个任务
//这里的scripts是 任务的名称
//ES6的箭头函数
gulp.task('scripts',()=>{
return gulp.src(['app/js/index.js']) //打开这个文件
.pipe(plumber({ //处理常规的错误逻辑
errorHandle:function(){
}
}))
.pipe(named()) //对文件重新命名
.pipe(gulpWebpack({ /*对文件进行编译,3个参数,第一个参数是编译相应的文件,
第二个是null,第三个是对错误进行一个处理*/
module:{
loaders:[{
test:/\.js$/, //如果遇到.js文件,用babel这个loader去处理
loader:'babel-loader'//这里还需要装三个依赖包,babel-loader、babel-core、babel-preset-env
}]
}
}),null,(err,stats)=>{
log(`Finished '${colors.cyan('scripts')}'`,stats.toString({
chunks:false
}))
})
//设置文件编译完后放在哪个地方
.pipe(gulp.dest('server/public/js')) //使用gulp.dest这个命令以后,将编译好的文件写入这个路径中
//为什么要写在server目录下,是因为在server中要拿到最新的(就是编译好的)js才能在整个服务器中跑起来
//处理编译压缩的过程(三步:复制-压缩-存储)
.pipe(rename({ //可以理解成把上面生成的文件重新复制了一份
basename:'cp',
extname:'.min.js'
}))
//压缩
.pipe(uglify({compress:{properties:false},output:{'quote_keys':true}}))
//存储到这个文件夹下
.pipe(gulp.dest('server/public/js'))
/*截止现在,在server/public/js这个路径下会有两个文件,
一个是编译好了未压缩的,一个是编译好的压缩了的(文件名:cp.min.js)*/
//监听一个文件,当这个文件变化了之后自动刷新
.pipe(gulpif(args.watch,livereload()))
/*解释上面:判断args.watch这个参数,如果命令行中有watch这个选项的话,
就执行这个livereload()热更新,如果没有,就不会对文件进行监听,也不会刷新*/
// 注:这里的 watch 只是监听命令参数的 watch,并不是监听文件的变化。
})
3. 处理模板的构建脚本 (tasks/pages.js文件)
需要用到的包有gulp gulp-if gulp-livereload
,上面已经都安装过了,可以不用再安装
代码:
//处理模板(ejs)的构建脚本
import gulp from 'gulp';
import gulpif from 'gulp-if';
import livereload from 'gulp-livereload'; //热更新
import args from './util/args'; //引入命令行参数那个包
//创建一个任务
gulp.task('pages',()=>{
return gulp.src('app/**/*.ejs') //打开app这个目录下的所有.ejs文件
.pipe(gulp.dest('server')) //将这些模板文件拷贝到这个server目录下
.pipe(gulpif(args.watch,livereload())) //监听热更新 注:这里的 watch 只是监听命令参数的 watch,并不是监听文件的变化。
})
4. 处理css相关脚本 (tasks/css.js文件)
需要用到的包有 gulp gulp-if gulp-livereload
,上面已经都安装过了,可以不用再安装,下同
代码:
//css相关脚本
import gulp from 'gulp';
import gulpif from 'gulp-if';
import livereload from 'gulp-livereload';
import args from './util/args';
gulp.task('css',()=>{
return gulp.src('app/**/*.css')
.pipe(gulp.dest('server/public'))
.pipe(gulpif(args.watch,livereload()))
})
5. 服务器脚本 (tasks/server.js文件)
需要安装 gulp-live-server
包
cnpm install gulp-live-server --save-dev
代码:
//服务器脚本
import gulp from 'gulp';
import gulpif from 'gulp-if';
import liveserver from 'gulp-live-server'; //引入一个启动服务器的包
import args from './util/args';
gulp.task('serve',(cb)=>{ //cb是一个回调,serve是任务名
if(!args.watch) return cb(); //如果不是处于监听状态下,直接返回回调函数
//如果处于监听状态下,就创建一个服务器
var server = liveserver.new(['--harmony','server/bin/www']);
/* '--harmony' 在当前命令行下去执行这个harmony脚本
'server/bin/www' //最终启动的服务器脚本(?)*/
server.start(); //启动服务器
//监听server这个命令下的所有js,ejs的模板引擎(当发生改变时浏览器自动刷新,实现热更新)
gulp.watch(['server/public/**/*.js','server/views/**/*.ejs'],function(file){
server.notify.apply(server,[file]); //通知服务器,文件已发生改变,然后做相应的处理
})
//gulp.watch //对文件的监听
//第一个参数,是传入的一个数组,值的要监听的哪些路径
//监听完之后,将改动告诉给服务器,然后做出相应的动作
// 监听需要重启服务的文件
gulp.watch(['server/routes/**/*.js','server/app.js'],function(){
server.start.bind(server)() //监听到变化后,让服务重启
});
//'server/routes/**/*.js' 一些服务器的脚本文件,做接口用的
//'server/app.js' 整个服务的启动入口文件
//这两个如果发生改变,都要重新启动服务器才能生效
})
6. 当app这个原文件发生改变时,自动编译,并生成到server目录下 (tasks/browser.js文件)
需要安装 gulp-util
包
cnpm install gulp-util --save-dev
代码:
//app这个目录,是作为前端资源的原始文件的目录
//server.js自动更新的时候,处理的是server/public下的文件
import gulp from 'gulp';
import gulpif from 'gulp-if';
import gutil from 'gulp-util';
import args from './util/args';
gulp.task('browser',(cb)=>{
if(!args.watch) return cb(); //如果没有监听,返回回调
//监听app里js变化时调用scripts构建脚本(scripts.js),完成后es6转成es5或3,写到server目录下的文件里
gulp.watch('app/**/*.js',['scripts']);
//同理,监听app目录下的模板文件变化
gulp.watch('app/**/*.ejs',['pages']);
//同理,监听css
gulp.watch('app/**/*.css',['css']);
});
7. 清空指定目录的文件(tasks/clean.js文件)
需要安装 del
包
cnpm install del --save-dev
代码:
//清空指定目录下的文件
//app里的原文件是ES6的,但在server中(浏览器中)去运行,它就转换成ES5或ES3了,在这里,编译完后会有一个拷贝的过程,每次改变原文件,都会拷贝并去覆盖server里面的文件,为了安全起见,先清空目录,在拷贝进去
import gulp from 'gulp';
import del from 'del';//引入做删除动作的包
import args from './util/args';
gulp.task('clean',()=>{
return del(['server/public','server/views'])//清空这两个目录,这样每次重新拷贝过来就不会出现覆盖现象
})
8. 处理顺序问题(tasks/build.js文件)
需要安装 gulp-sequence
包
cnpm install gulp-sequence --save-dev
代码:
//作用:将所有的任务都关联起来
import gulp from 'gulp';
import gulpSequence from 'gulp-sequence';//处理包之间的顺序问题
gulp.task('build',gulpSequence('clean','css','pages','scripts',['browser','serve']));
//先是clean,清除server两个相关的目录(见clean.js),一定是放在最前面的
//紧着着,将css拷过去(css),编译模板(pages),执行脚本(scripts)
//['browser','serve'] 理解:这个数组一定是在最后的,而在数组里,browser一定是在serve前面的,serve一定是在最后面执行
9. tasks/default.js文件
在命令行中,如果输入gulp 脚本名
,它就会去执行这个脚本,eg:gulp scripts.js
执行scripts.js
但是,当只在命令行中输入gulp
时,它就会去找default.js文件并执行default任务
注:文件名可以不是default.js,但是,必须要有default这个任务!
代码:
/*
在命令行中,如果只输入gulp后面不带任何参数,就会默认去找一个default的任务
*/
import gulp from 'gulp';
gulp.task('default',['build']);
//注:文件名可以不是default.js,但是,必须要有default这个任务!
10. 根目录下的gulpfile.babel.js文件
需要安装 require-dir
包
cnpm install require-dev --save-dev
执行gulp命令,第一个去找的就是gulpfile.babel.js这个文件,通过这个文件去加载所有的脚本文件
代码:
//将所有的文件加载进来,运行,这里需要用到require-dir这个包
import requireDir from 'require-dir';
requireDir('./tasks');//将tasks这个目录加载进来运行(所有的构建脚本都是放在tasks目录下的)
11.根目录下的 .babelrc文件
需要安装 babel-preset-es2015
包
cnpm install babel-preset-es2015 --save-dev
这里只设置presets转换成es2015,如果项目要求要支持es3等,也是在这里设置
代码:
{
"presets": [
"es2015"
]
}
到此为止,脚本文件已经编写完成,通过输入gulp
来测试还有没有遗漏的包没安装,或者其它什么问题
12. 编写app/views/index.ejs文件
当html文件随便写点就行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>es6</title>
</head>
<body>
<h1>the first ES6 project!</h1>
</body>
</html>
13. 输入gulp --watch
进行监听
如果不加--watch
,那么所有的脚本就只会执行一次
在浏览器中输入 进行访问
解释:
localhost:主机名,即本机,127.0.0.1
3000: 服务器端口,因为前面服务器是用的express搭建的,而它默认的端口就是3000
出现以下画面,说明已将成功了
- 实现热更新 (server/app.js文件)
在上面的基础上,如果改变app/views/index.ejs里的内容,在浏览器里面只有手动刷新以下才会改变,那么,怎么做到修改文件,保存之后浏览器立即自动刷新显示新的改变后的内容
解决:添加一行代码 app.use(require('connect-livereload')());
注:必须写在箭头所指的第20行那排代码的后面
另外:需要安装 connect-livereload
包
cnpm install connect-livereload --save-dev