一、基础架构
编译:将ES6 编译成ES5,甚至是ES3(能让一级浏览器执行)。
二、任务自动化(gulp)
- 什么是任务自动化?
让电脑自动监听,自动响应。 - 什么是gulp?
是一种前端工作流的工具。前端工作流管理,就是把前端业务中的一些工作用计算机工具自动完成。 - 如何使用gulp完成任务自动化?
先看中文文档,有哪些API和插件。
三、编译工具(babel、wbpack)
- 什么是babel?webpack?
babel是将ES6 代码编译成 ES5 代码让浏览器识别的。
webpack用于实现项目模块化。
babel的核心用法?
怎么解决兼容性问题,怎么编译?
跟gulp结合,该引用哪些包?webpack和webpack-stream 的作用?
webpack-stream 是 webpack 对gulp的支持,stream是通过二进制的流来操作
四、代码实现
1、创建一个ES6前端工程,创建三个并行的模块:1.放置前端代码(css、js、模板views)、2.服务器API代码、3.构建目录(前端代码编译、服务器定时刷新等所有构建脚本)
-
1.创建三个模块
app、server、tasks
- 2. 安装node.js
- 3. 安装express应用生成器
npm install express-generator -g
-
4.运行express
用express脚手架,-e
表示使用一级s模板引擎,.
表示在当前目录下执行
H:\imooc\es6\server>express -e .
运行之后,出现如下提示
根据提示运行:
npm install
这样就安装好了服务器代码。
5、回到构建目录tasks
tasks下要创建很多任务的DS(例如文件的合并、脚本的编译、模板的自动更新)
其中有一个需要命令行参数的,输入一段命令行工具,其执行的对象需要解析。
1、所以,先创建一个util
文件,来放置脚本。
2、然后在这个文件下,初始化一个名为args.js
的js文件6、在根目录下创建package.json文件
方法1、手动创建
方法2、自动创建:在命令行输入npm init
7、在根目录下创建一个设置babel编译工具的配置文件
.babelrc
注意:名字必须是.babelrc
,否则babel进行编译时,会自动去找这个文件,如果名字不对,就无法编译。8、创建gulp配置文件‘gulpfile.babel.js’
官网上是要求创建gulpfile.js
文件,而这里创建的是gulpfile.babel.js
,为什么多了‘babel’呢?
因为我们写的构建脚本都是使用了ES6的语法,如果不加babel的话,执行的时候会报错。
所以‘gulpfile.babel.js’名称也是固定的。
至此,所有的目录结构和基本文件初始化完成
五、对命令行参数进行处理
1、通过npm引入yargs
(处理命令行参数)
npm install yargs@7.0.2 --save
2、进入args.js
,args.js
负责处理命令行参数,引入yargs帮助识别程序。
import yargs from 'yargs'
3、.option()判断
通过.option( )
来对cmd命令进行判断,option就是选项的意思,在cmd中,-
符号就是表示选项。
import yargs from 'yargs'
const args = yargs
//区分开发环境和线上环境
.option('production',{
//判断命令行中是否有参数‘production’
boolean:true,
//默认数据类型为布尔值
default:false,
//没有匹配到production时,默认为false,开发环境
describe:'min all scripts'
//给开发者看的,机器不识别describ
}
)
//要不要监听,开发环境中修改的文件
.option('watch',{
boolean:true,
default:false,
describe:'watch all files'
})
//要不要详细输出命令行执行的日志
.option('verbose',{
boolean:true,
default:false,
describe:'log'
})
//内外映射,处理Source Map参数
//Source map就是一个信息文件,里面储存着位置信息。
有了它,出错的时候,除错工具将直接显示原始代码,
而不是转换后的代码。
.option('sourcemaps',{
describe:'force the creation of sroucemaps'
})
//设置服务器端口
.option('port',{
string:true,
default:8080,
describe:'server port'
})
//表示对输入的命令行内容以字符串形式进行解析
.argv
export default args
//最后不要忘记输出args
6、创建JS编译任务
1、在tasks
文件夹下创建scripts.js
文件
2、npm 安装包
"gulp": "^3.9.1",
"gulp-concat": "^2.6.1",
"gulp-if": "^2.0.2",
"vinyl-named": "^1.1.0",
"webpack": "^2.2.0",
"webpack-stream": "^3.2.0",
"yargs": "^7.0.2"
3、在scripts.js
引入
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处理文件流,
//所以需要gulpwebpack来处理webpack-stream
import name from 'vinyl-named'
//对文件重命名做标识
import liverreload from 'gulp-livereload'
//文件修改以后,浏览器自动刷新
import plumber from 'gulp-plumber'
//处理文件信息流
import rename from 'gulp-rename'
//对文件重命名
import uglify from 'gulp-uglify'
//处理JS、CSS压缩
import {log,colors} from 'gulp-util'
//命令行工具输出的包,色彩的输出
import args from './util/args'
//对命令行参数进行解析
7、创建模板、服务任务脚本
1、在tasks
文件夹下创建pages.js
,处理模板
gulp所有文件的创建都先要使用
gulp.src
命令打开文件
app/ **/*.ejs
表示app目录下所有的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下面所有的css文件。
.pipe(gulp.dest('server'))
.pipe(gulpif(args.watch,livereload()))
})
2、在tasks
文件夹下创建css.js
,处理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()))
})
2、在tasks
文件夹下创建server.js
,启动一个脚本作为服务器。服务器下面所有js、css、模板等文件发生改变的时候,浏览器能自动刷新 。所以要监听server文件夹下所有js和ejs模板引擎。
gulp.watch做文件的监听,第一个参数是一个数组,数组内容是要监听的文件路径 ;第二个参数是执行任务,可以是一个函数告诉服务器监听要做的动作,也可以是一个文件,如['script.js']
import gulp from 'gulp';
import gulpif from 'gulp-if';
import liveserver from 'gulp-live-server'; //启动服务器的脚本
import args from './util/args';//引进命令行参数
//创建任务
gulp.task('serve',(cb)=>{
if(!args.watch) return cb();
//判断如果不是处于监听状态下,直接返回回调函数
var server = liveserver.new(['--harmony','server/bin/www']);
//如果处于监听下,就创建一个服务器
//harmony表示要在当前命令行下去执行这个控制脚本
//‘'server/bin/www' 就是脚本位置,其实服务器启动的就是server-bin-www这个脚本
server.start(); //启动服务器
//对server下的js和ejs文件进行监听
gulp.watch(['server/public/**/*.js','server/views/**/*.ejs'],function(file){
server.notify.apply(server,[file]);//通知服务器文件已经发生了改变
})
//监听需要重启服务的文件,app.js是整个服务启动的入口文件,router 是服务器的脚本文件,做接口用,这两个文件的改变都需要重新启动服务器才能生效 gulp.watch(['server/routes/**/*.js','server/app.js'],function(){
server.start.bind(server)() });//重新启动服务器
})
8、文件自动监听,项目构建测试
在项目中,app
文件夹存放前端资源原始文件,当server需要自动更新时,处理的是public
文件夹,而script脚本是写命令去处理public的。
1、在tasks
文件夹下创建browser.js
,作为浏览器监听的文件,当app
文件夹下的内容发生改变是,自动编译更新
import gulp from 'gulp';
import gulpif from 'gulp-if';
import gutil from 'gulp-util' ; //gulp常用更新工具集合包
import args from './util/args';
gulp.task('browser',(cb)=>{
if(!args.watch) return cb(); //如果没有用watch函数做监听
gulp.watch('app/**/*.js',['scripts']);
//启动`script.js`去监听app下所有js发生的变化,
//如发生变化就运行script.js文件,
//将ES6转为ES5/ES3,然后将其写进server下的文件中
gulp.watch('app/**/*.ejs',['pages']);
gulp.watch('app/**/*.css',['css']);
});
执行了browser任务,就会自动监听app下的js、css、ejs文件,将js、css、ejs文件串联了起来。
2、每次app下文件发生变动时,在自动更新编译之前,要把之前的已经生成的老文件清空('server/public','server/views'),所以需要创建clean.js
import gulp from 'gulp';
import del from 'del';
import args from './util/args';
gulp.task('clean',()=>{
return del(['server/public','server/views'])
})
3、如何做到只用一个命令就让所有文件关联起来,执行后让所有文件自动跑起来?
创建一个把所有脚本串联起来的文件build.js
import gulp from 'gulp';
import gulpSequence from 'gulp-sequence';
gulp.task('build',gulpSequence('clean','css','pages','scripts',['browser','serve']));
//server一定要放在最后面执行
4、在cmd中项目下运行gulp
,会默认去找任务下的default.js
。
import gulp from 'gulp';
gulp.task('default',['build']);
//default.js执行包中一定要有default这个任务,不然就会报错
5、在gulpfile.babel.js
文件中
import requireDir from 'require-dir';
requireDir('./tasks');
6、执行gulp
还是报错,这是对的,因为还没有给babelrc.js
编写内容。
【babelrc.js】
{
"presets":["es2015"],
"plugins":["transform-decorators-legacy"]
}
注意:这个写法格式需要下载一个包
npm install --save-dev babel-preset-es2015
7、执行gulp --watch
,期待这次会成功了把~
其实我这里已经按照它的要求安装了
Babel-register
,但是还是有异常提示,虽然不知道为什么,但是先让我看下是否影响项目运行
让我们打开localhost:3000
,页面没有内容但也没有报错,说明没有问题!
localhost 相当于 127.0.0.1 本机地址
3000是服务器默认端口
8、但是运行后,在index.js下修改内容,却发现没有热更新,这时我们要去app.js
下添加内容app.use(require('connect-livereload')());
注意这一行内容一定要放在app.use(express.static(path.join(__dirname, 'public')));
之后,否则无法生效
此时设计到require,所以需要npm安装
require-dir
包
9、再运行gulp --watch
,发现已经能够热更新了,现在我们尝试以下es6语法是否能编译正确。
10、针对IE8的配置,在老师源代码中,另外去看。