Gulp+Babel实现ES6项目工程构建&踩坑记录

前言

近期在开发Hybird新需求时用到了地图,而因为地图的定位地址是异步拿到结果的,而多个点与定位地址的距离计算需要等到定位结束,所以这里可以用async函数来做,但是以前项目用到gulp只停留在ES5阶段,导致ES6语法打包出来的js在部分系统低的安卓机上不支持而报错,所以这里需要babel编译

一、引入Babel进行ES6编译

项目以前用的GulpV3,也趁这次终于升级到V4了

1. 依赖安装
npm install -D gulp-babel  @babel/core @babel/preset-env
2. babel在gulp中的简单配置
const gulp = require('gulp')
const {task,dest,src} = require('gulp')
const babel = require('gulp-babel')

task('testBabel', function () {
    let step =  src('./js/*.js')
                .pipe(babel({
                    presets:['@babel/preset-env']
                }))
                .pipe(dest('./test'))
    return step;
})
3. 拿一个js来测试下
// test.js
const a = 1;
const b = 2;

let foo = function () {
   return a+b
}
async function test() {
    let c = 10;
    let d = await foo() + c
    return d;
}
test().then(res => {
    console.log(res)
})
  • 通过运行gulp testBabel可以看到test文件夹下出现了(ES6转ES5)编译后的test.js文件。
  • 出现问题:用一个html来引用刚编译后的js运行看,发现报错Uncaught ReferenceError: regeneratorRuntime is not defined
    • 原因:在test.js中引用了async函数,而这是需要ES6新API部分,babel默认情况下是只转译语法,而对新API的支持需要额外加入polyfill,现在polyfill其实有三种类型,区别可以看这篇文
    • 解决:
    • npm install -D @babel/plugin-transform-runtime,
    • npm install -S @babel/runtime
task('test', function () {
    let step =  src('./js/*.js')
                .pipe(babel({
                    presets: ['@babel/preset-env'],
                    plugins: ['@babel/plugin-transform-runtime']
                }))
                .pipe(dest('./test'))
    return step;
})
4. 再次测试,发现这次报错不一样了,Uncaught ReferenceError: require is not defined.
  • 原因:babel编译后的代码是遵循commonJS的模块化规范的,所以这里还需要引用一个模块化bundler。
  • 解决:引入 browserify
npm install -D browserify vinyl-buffer vinyl-source-stream
const gulp = require('gulp')
const {task,dest,src,series} = require('gulp')
const babel = require('gulp-babel')
const browserify = require('browserify')
const buffer = require('vinyl-buffer')
const stream = require('vinyl-source-stream')

task('test', function () {
    let step =  src('./js/*.js')
                .pipe(babel({
                    presets: ['@babel/preset-env'],
                    plugins: ['@babel/plugin-transform-runtime']
                }))
                .pipe(dest('./test'))
    return step;
})
task('browserify', function (cb) {
    return browserify({
        entries: './test/test.js',
        debug: true
    })
        .bundle()
        .on('error', function (error) {
            console.log(error.toString())
        })
        .pipe(stream('test.js'))
        .pipe(buffer())
        .pipe(dest('./test/testBundle'));
    cb() //这一句其实是因为V4不再支持同步任务,所以需要以这种方式或者其他API中提到的方式
})

exports.build = series('test','browserify') //series是gulpV4中新方法,按顺序执行
5. 再次执行,浏览器终于不报错啦~~
  • 但实际项目中,往往用到gulp也不是单文件入口编译,所以在browserify的文件入口entry处可以通过编写读文件脚本的方式来对一个文件夹下的js进行模块化打包
  • 例:
let enviroment = process.env.NODE_ENV || 'development'
const folder = {
    src:'src/',
    dist:'webapp/',
    temp:'./.tmp/'
}
// 文件读取
const es = require('event-stream')
const fs = require('fs')
const join = require('path').join
function findSync(startPath){
    let result = []
    function finder(path){
        let files = fs.readdirSync(path)
        files.forEach(val=>{
            let fPath = join(path,val)
            let stats = fs.statSync(fPath)
            if(stats.isDirectory()) finder(fPath)
            if(stats.isFile()) result.push({path:'./'+fPath,name:val})
        })
    }
    finder(startPath)
    let res = result.map(item=>{
        item.path = item.path.replace(/\\/g,'/')
        return item
    })
    return res
}
// 模块化打包
task('browserify',function(cb){
    let files = findSync(folder.temp+'js')
    var task = files.map(entry=>{
        return browserify({
            entries:entry.path,
            debug:true
        })
            .bundle()
            .on('error',function(error){
                console.log(error.toString())
            })
            .pipe(stream(entry.name))
            .pipe(buffer())
            .pipe(dest(folder.dist+'js'))
    })
     es.merge.apply(null,task)
    cb()  
})

二、整体Gulp工程构建

1. 一些常用gulp插件
  • gulp-htmlclean:HTML代码压缩
  • gulp-rev,gulp-rev-collector:为资源加MD5后缀(防浏览器缓存)
  • gulp-useref:对HTML引用的资源进行合并(通过特定标签注释)
  • gulp-clean-css:CSS代码压缩
  • gulp-uglify:JS压缩
  • gulp-imagemin:图片压缩
  • gulp-less:less预编译
  • gulp-connect:本地网络服务
  • gulp-postcss&autoprefixer:CSS自动前缀补全
  • gulp-clean:文件清理

2. 最后附上完整代码,方便复用啦~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sophie_U

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值