ECMAScript 6 入门

从2015年发布,具有新特性:

更多的原生方法、默认参数、字符串模板、解构赋值、箭头函数、Set和Map、异步操作、类与对象、模块化

越来越多库和框架使用ES6

1 项目构建

1.1 构建介绍

1.1.1 基础架构
  1. 业务逻辑包括有页面(HTML和CSS)、交互(javascript)
  2. 自动构建包括有编译(ES6到ES5或者ES3)、辅助(自动刷新、文件合并、资源压缩)
  3. 服务接口包括有数据(模拟或者真实)、接口(后端服务器)
1.1.2 自动化(gulp)
gulp中文 gulp
1.1.3 编译工具(babel、webpack)
babel webpack
1.1.4 代码实现

前端工程(ES6)创建,目录结构、自动构建、服务器搭建完成

1.2 目录创建

首先安装好相应的nodejs,npm在国内可以使用cnpm代替,这里采用express框架

命令行(windows git bash)

创建目标结构、文件

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
~/ $ mkdir es6
~/es6 $ cd es6
~/es6 $ mkdir app
~/es6 $ mkdir server
~/es6 $ mkdir tasks
~/es6 $ cd app
~/es6/app $ mkdir css
~/es6/app $ mkdir js
~/es6/app $ mkdir views
~/es6/app $ mkdir js/class
~/es6/app $ touch js/class/test.js
~/es6/app $ touch js/index.js
~/es6/app $ touch views/error.ejs
~/es6/app $ touch views/index.ejs
~/es6/app $ cd ../server/
~/es6/server $ npm install express --save
~/es6/server $ express -e .
~/es6/server $ npm install
~/es6/server $ cd ../tasks/
~/es6/tasks $ mkdir util
~/es6/tasks $ touch util/args.js
~/es6/tasks $ cd ../
~/es6 $ npm init
~/es6 $ touch .babelrc
~/es6 $ touch gulpfile.babel.js

1.3 创建编译任务

./es6/tasks/util/args.js

创建配置命令行处理文件

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
import yargs from 'yargs';
const args = yargs
.option('production',{
boolean: true,
default: false,
describe: 'min all scripts'
})
.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 sourcemaps'
})
.option('port',{
string: true,
default: 8080,
describe: 'server port'
})
.argv
export default args;

命令行创建任务配置文件

1
~/es6 $ touch tasks/scripts.js

./es6/tasks/scripts.js

引入所需模块

1
2
3
4
5
6
7
8
9
10
11
12
import gulp from 'gulp';
import gulpif from 'gulp-if';
import concat from 'gulp-concat'; // 连接
import webpack from 'webpack';
import gulpWebpack from 'webpack-stream';
import named from 'vinyl-named'; // 重命名
import livereload from 'gulp-livereload';
import plumber from 'gulp-plumber';
import rename from 'gulp-rename'; // 备份
import uglify from 'gulp-uglify'; // 压缩
import {log,colors} from 'gulp-util';
import args from './util/args'; // 对命令行参数解析

命令行安装所需模块

1
~/es6 $ npm install gulp gulp-if gulp-concat webpack webpack-stream vinyl-named gulp-livereload gulp-plumber gulp-rename gulp-uglify gulp-util yargs babel-loader babel-core babel-preset-env --save-dev

./es6/tasks/scripts.js

配置自动化、编译等任务

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
gulp.task('scripts',()=>{
return gulp.src(['app/js/index.js'])
.pipe(plumber({
errorHandle:function(){
}
}))
.pipe(named())
.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'))
.pipe(gulpif(args.watch,livereload()))
})

1.4 创建模板、服务任务脚本

命令行创建模板、样式、服务器等任务文件

1
2
3
~/es6 $ touch tasks/pages.js
~/es6 $ touch tasks/css.js
~/es6 $ touch tasks/server.js

./es6/tasks/pages.js

模板任务配置

1
2
3
4
5
6
7
8
9
10
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')
.pipe(gulp.dest('server'))
.pipe(gulpif(args.watch,livereload()))
})

./es6/tasks/css.js

样式任务配置

1
2
3
4
5
6
7
8
9
10
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()))
})

./es6/tasks/server.js

服务器任务配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import gulp from 'gulp';
import gulpif from 'gulp-if';
import liveserver from 'gulp-live-server'; // 启动服务器
import args from './util/args';
gulp.task('server',(cb)=>{
if (!args.watch) return cb(); // 如果是监听状态,直接返回
// 在当前命令中,启动server/bin/www下脚本
var server = liveserver.new(['--harmony','server/bin/www']);
server.start();
// 监听指定路径下文件,执行相应任务
gulp.watch(['server/public/**/*.js','server/views/**/*.ejs'],function (file) {
server.notify.apply(server,[file]); // 任务-通知服务器
});
gulp.watch(['server/routes/**/*.js','server/app.js'],function () {
server.start.bind(server)(); // 任务-重启服务器
});
})

1.5 文件自动监听,项目构建测试

命令行创建浏览器、清空、搭建、默认等任务文件

1
2
3
4
~/es6 $ touch tasks/browser.js
~/es6 $ touch tasks/clean.js
~/es6 $ touch tasks/build.js
~/es6 $ touch tasks/default.js

./es6/tasks/browser.js

浏览器任务配置

1
2
3
4
5
6
7
8
9
10
11
12
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();
gulp.watch('app/**/*.js',['scripts']);
gulp.watch('app/**/*.ejs',['pages']);
gulp.watch('app/**/*.css',['css']);
})

./es6/tasks/clean.js

清空任务配置

1
2
3
4
5
6
7
import gulp from 'gulp';
import del from 'del'; // 删除
import args from './util/args';
gulp.task('clean',()=>{
return del(['server/public','server/views'])
})

./es6/tasks/build.js

搭建任务配置

1
2
3
4
import gulp from 'gulp';
import gulpSequence from 'gulp-sequence'; // 顺序
gulp.task('build',gulpSequence('clean','css','pages','scripts',['browser','server']))

./es6/tasks/default.js

默认任务配置

1
2
3
import gulp from 'gulp';
gulp.task('default',['build'])

./es6/gulpfile.babel.js

1
2
3
import requireDir from 'require-dir';
requireDir('./tasks')

./es6/.babelrc

配置ES6

1
2
3
4
{
"presets":["es2015"],
"plugins":["transform-decorators-legacy"]
}

./es6/server/app.js

1
2
3
app.use(express.static(path.join(__dirname, 'public')));
// 插入语句 -- 添加热更新功能
app.use(require('connect-livereload')());

命令行安装所需模块

1
~/es6 $ npm install gulp-live-server del gulp-util gulp-sequence require-dir babel-preset-es2015 connect-livereload --save-dev

命令行执行gulp

1
2
~/es6 $ gulp
~/es6 $ gulp watch

对源码中模板进行编辑,浏览器(localhost:3000,express默认端口)自动实时更新

./es6/app/views/index.ejs

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>title</title>
</head>
<body>
<script src='/js/index.js' charset='utf-8'></script>
</body>
</html>

./es6/app/js/index.js

1
2
3
4
5
6
7
8
9
class Test{
constructor(){
this.msg = 'Hello World'
}
}
let test = new Test();
document.body.innerHTML = test.msg;

在浏览器页面显示“Hello World”

1.6 依赖文件

经过上面操作,需要依赖的包可以得到,以后可以根据依赖文件一次性配置好依赖

./es6/package.json

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
{
"name": "es6",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.24.0",
"babel-loader": "^6.4.1",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-polyfill": "^6.23.0",
"babel-preset-env": "^1.2.2",
"babel-preset-es2015": "^6.24.0",
"connect-livereload": "^0.6.0",
"del": "^2.2.2",
"gulp": "^3.9.1",
"gulp-concat": "^2.6.1",
"gulp-if": "^2.0.2",
"gulp-live-server": "0.0.30",
"gulp-livereload": "^3.8.1",
"gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-sequence": "^0.4.6",
"gulp-uglify": "^2.1.0",
"gulp-util": "^3.0.8",
"jquery": "^3.2.1",
"require-dir": "^0.3.1",
"vinyl-named": "^1.1.0",
"webpack": "^2.2.1",
"webpack-stream": "^3.2.0",
"yargs": "^7.0.2"
}
}

2 ES6 语法

3 实战项目