ES6基础【二】项目构建

一、基础架构


编译:将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.jsargs.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的配置,在老师源代码中,另外去看。

推荐阅读更多精彩内容

  • *node下用express框架,实现一个简单的mvc *构建工具:gulp / babel / webpack ...
    韩娜爱吃辣_前端程序媛阅读 624评论 0 1
  • 在现在的前端开发中,前后端分离、模块化开发、版本控制、文件合并与压缩、mock数据等等一些原本后端的思想开始...
    Charlot阅读 4,838评论 1 32
  • 项目构建的目录—创建文件夹 1.文件夹 app 前端代码 js class index.js 入口文件 css...
    yy不会笑阅读 159评论 0 2
  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 7,167评论 7 35
  • 今天,单位年终工作会议,全校千余名教职工齐聚,总结经验,分享成果。10年,学校发展迅猛,成果显著。相比较而言自己的...
    短发妞儿阅读 27评论 0 0