gulp构建es6项目

项目构建介绍

ES6 项目构建

  • 基础架构
  • 任务自动化(gulp)
  • 编译工具(babel、webpack)
  • 代码实现

基础架构

1536973449110.png

编译 es5 es3(适用于ie8)

任务自动化(gulp)

什么是任务自动化

减少人工操作,自动监听操作与响应。

什么是gulp

自动化构建工具。

gulp的作用

完工自动化,背后用 nodejs 做开发,提供了很多插件,完成不同任务。

了解如何使用gulp完成任务自动化

gulp中文文档、api、插件

编译工具(babel、webpack)

什么是babel、webpack

babel:js 的编译器

webpack:解决模块化的工具

babel的核心用法

解决兼容性问题、编译,如何和 gulp 结合。

了解webpack及webpack-stream的作用

webpack-stream 是 webpack 对 gulp 的支持,gulp 是通过 stream (二进制的流)的方式进行操作。

代码实现

创建一个ES6前端工程

完成目录结构、自动构建、服务器搭建

项目目录创建

代码地址

根目录 es6-lottery,创建3部分:前端、服务端、工具。

app/ 前端代码

  • app/css/样式
  • app/js/ js
    • app/js/class/
      • app/js/class/test.js 初始化类文件
      • app/js/class/index.js 入口文件
  • app/views/ 模板 html
  • app/views/error.ejs 初始化模板文件,错误文件(ejs,服务器代码通过express做,其使用的模板引擎是 ejs 模板引擎)
  • app/views/index.ejs 入口文件

server/ 服务器

  • server/下,命令行 express -e . express脚手架在当前目录使用 ejs 模板引擎, npm install

tasks/ 工具

tasks/util/ 常见脚本

tasks/util/args.js 初始化脚本文件

package.json 命令行 npm init ,配置依赖包

.babelrc babel 编译配置文件

gulpfile.babel.js gulp 配置文件,脚本使用了 es6 语法 需要加上 babel

命令行处理,创建JS编译任务脚本

命令行处理

命令行参数解析

// tasks/util/args.js
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',{ // 资源映射,强制生成 sourcemaps
    describe:'force the creation of sroucemaps'
  })

  .option('port',{ // 服务器端口
    string:true,
    default:8080,
    describe:'server port'
  })

  .argv // 命令行以字符串进行解析

export default args;

js 处理脚本

创建 /tasks/script.js

import gulp from 'gulp';
import gulpif from 'gulp-if'; // gulp if 判断
import concat from 'gulp-concat'; // gulp 文件拼接
import webpack from 'webpack'; // 打包
import gulpWebpack from 'webpack-stream'; // gulp 基于 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'; // js,css 压缩
import {log,colors} from 'gulp-util'; // 命令行输出,log 和 color 的输出
import args from './util/args'; // 命令行参数解析

gulp.task('scripts',()=>{ // 创建脚本命令
  return gulp.src(['app/js/index.js']) // 打开文件
    .pipe(plumber({ 
      errorHandle:function(){ // 处理错误,结合 webpack

      }
    }))
    .pipe(named()) // 文件重命名
    .pipe(gulpWebpack({ // 编译,结合 webpack
      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())) // 监听文件变化
})

创建模板、服务任务脚本

模板处理脚本

创建 /tasks/pages.js

import gulp from 'gulp';
import gulpif from 'gulp-if';
import livereload from 'gulp-livereload';
import args from './util/args';

gulp.task('pages',()=>{ // 创建 pages 任务
  return gulp.src('app/**/*.ejs') // 打开文件,app 下的所有 ejs 文件
    .pipe(gulp.dest('server')) // 拷贝
    .pipe(gulpif(args.watch,livereload())) // 监听 热更新
})

css 处理脚本

创建 /tasks/css.js

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'))
})

服务器任务脚本

// tasks/server.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)=>{ // 创建 serve 任务
  if(!args.watch) return cb(); // 如果不监听,返回 cb

  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]); // 通知服务器做处理
  }) // 监听 server/ 下的 js 和 ejs 文件

  gulp.watch(['server/routes/**/*.js','server/app.js'],function(){
    server.start.bind(server)() 
  }); // 监听路由和应用接口变化
})

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

监听 js css ejs 变化,对应执行响应脚本文件

// tasks/browser.js
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();
  gulp.watch('app/**/*.js',['scripts']); // app/中 js发生变化,执行 script 脚本
  gulp.watch('app/**/*.ejs',['pages']);
  gulp.watch('app/**/*.css',['css']);
});

每次清空生成文件

// tasks/clean.js
import gulp from 'gulp';
import del from 'del'; // 做删除处理
import args from './util/args';

gulp.task('clean',()=>{ // 创建任务
  return del(['server/public','server/views']) // 清空两个目录
})

串联脚本

// tasks/build.js
import gulp from 'gulp';
import gulpSequence from 'gulp-sequence'; // 处理包执行顺序

gulp.task('build',gulpSequence('clean','css','pages','scripts',['browser','serve'])); // 清目录->拷css->编译模板->执行脚本->数组browser->serve

默认任务脚本

// tasks/default.js
import gulp from 'gulp';

gulp.task('default',['build']); // 命令行 gulp,自动会找 default 任务

全局安装 gulp 后,命令行执行 gulp ,会依次执行脚本。

引入 tasks 目录文件

// gulpfile.babel.js
import requireDir from 'require-dir';

requireDir('./tasks'); // 引入 tasks 目录文件,并执行

配置 .babelrc

{
  "presets":["es2015"],
  "plugins":["transform-decorators-legacy"]
}

热更新

// server/app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(require('connect-livereload')()); // 接收热更新,添加这句话,注意顺序
app.use('/', routes);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});


module.exports = app;

自动更新完成

命令行 gulp --watch 监听

localhost: 3000 打开

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容