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. 最后附上完整代码,方便复用啦~

发布了114 篇原创文章 · 获赞 146 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/Sophie_U/article/details/101752438
今日推荐