Gulp + browserify + 6to5 + source maps

32

我正在尝试编写一个gulp任务,使我能够在JS中使用模块(CommonJS可以),使用browserify + 6to5。我还希望源映射正常工作。

所以: 1.我使用ES6语法编写模块。 2.6to5将这些模块转换为CommonJS(或其他)语法。 3.Browserify捆绑了这些模块。 4.源映射指回原始的ES6文件。

如何编写这样的任务?

编辑:这是我到目前为止的内容:

gulp任务

gulp.task('browserify', function() {
    var source = require('vinyl-source-stream');
    var browserify = require('browserify');
    var to5ify = require('6to5ify');

    browserify({
        debug: true
    })
    .transform(to5ify)
    .require('./app/webroot/js/modules/main.js', {
        entry: true
    })
    .bundle()
    .on('error', function(err) {
        console.log('Error: ' + err.message);
    })
    .pipe(source('bundle.js'))
    .pipe(gulp.dest(destJs));
});

模块/A.js

function foo() {
    console.log('Hello World');

    let x = 10;

    console.log('x is', x);
}

export {
    foo
};

模块/B.js

import {
    foo
}
from './A';

function bar() {
    foo();
}

export {
    bar
};

模块/main.js

import {
    bar
}
from './B';

bar();

这段代码似乎可以工作,但它没有被压缩,而且源映射是内联的(对于生产不太有效)。

2个回答

45

使用这个作为您的起点:

var gulp = require('gulp');
var gutil = require('gulp-util');
var sourcemaps = require('gulp-sourcemaps');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var browserify = require('browserify');
var to5ify = require('6to5ify');
var uglify = require('gulp-uglify');

gulp.task('default', function() {
  browserify('./src/index.js', { debug: true })
    .transform(to5ify)
    .bundle()
    .on('error', gutil.log.bind(gutil, 'Browserify Error'))
    .pipe(source('bundle.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true})) // loads map from browserify file
    .pipe(uglify())
    .pipe(sourcemaps.write('./')) // writes .map file
    .pipe(gulp.dest('./build'));
});

这个非常好用,谢谢。我注意到在Chrome开发工具中无法设置源映射文件的断点 - 这个阶段是不可能的吗? - lamplightdev
算了吧 - 我还使用了uglify来混淆变量名。 - lamplightdev
3
@lamplightdev 恩,我刚刚添加了一些调整来停止损坏名称 .pipe(uglify({ mangle: false })),它运行得很好。我还在转换之前添加了6to5填充项 .add(require.resolve('6to5/polyfill')),以获得更好的跨浏览器兼容性 :) 希望有所帮助! - Andrew Odri
有没有一种方法可以使用Grunt完成相同的操作? - moudrick
1
@lamplightdev 你也可以使用 'gulpif' 条件地禁用uglify过程。例如,您可以仅在生产配置中运行它,例如.pipe(gulpif(config.isProduction,uglify())) - ctrlplusb
对我来说,我确实得到了一个源文件,但它只指向./src/index.js,这是它唯一的["sources"](在文件开头可见),没有从那里包含的任何模块(通过require())。 - Frank N

3

我不明白为什么我们必须使用某些东西才能使其正常工作,所以我在此添加了自己的答案。对于那些正在寻找使用babelify的解决方案的人,我在下面提供了一个解决方案。我还认为谈论一下每行代码做什么很有好处。

对于那些想在Gulpfile中使用ES6的人,可以看看这里,但是从Gulp 3.9开始,如果将文件重命名为Gulpfile.babel.js,则Gulp支持它。

需要注意的一件大事是,您需要使用vinyl-source-stream与Browserify一起使用,以将输出转换为Gulp可以理解的内容。从那里开始,许多gulp插件需要vinyl缓冲区,这就是为什么我们要缓冲源流的原因。

对于那些不熟悉sourcemaps的人,它们本质上是一种将缩小的捆绑文件映射到主源文件的方式。ChromeFirefox支持它,因此当您进行调试时,可以查看您的ES6代码以及出错的位置。

import gulp          from 'gulp';
import uglify        from 'gulp-uglify';
import sourcemaps    from 'gulp-sourcemaps';
import source        from 'vinyl-source-stream';
import buffer        from 'vinyl-buffer';
import browserify    from 'browserify';
import babel         from 'babelify';

gulp.task('scripts', () => {
  let bundler = browserify({
    entries: ['./js/main.es6.js'], // main js file and files you wish to bundle
    debug: true,
    extensions: [' ', 'js', 'jsx']
  }).transform(babel.configure({
    presets: ["es2015"] //sets the preset to transpile to es2015 (you can also just define a .babelrc instead)
  }));

  // bundler is simply browserify with all presets set
  bundler.bundle()
    .on('error', function(err) { console.error(err); this.emit('end'); })
    .pipe(source('main.es6.js')) // main source file
    .pipe(buffer())
    .pipe(sourcemaps.init({ loadMaps: true })) // create sourcemap before running edit commands so we know which file to reference
      .pipe(uglify()) //minify file
      .pipe(rename("main-min.js")) // rename file
    .pipe(sourcemaps.write('./', {sourceRoot: './js'})) // sourcemap gets written and references wherever sourceRoot is specified to be
    .pipe(gulp.dest('./build/js'));
});

其他有用的阅读材料:

使用 Gulp 和 Browserify 的 gulp-y 方式


我正在尝试按照您的建议操作,但一直没有成功。我的ES6总是被转换为我不想要的ES5。我需要您建议的相同内容,在ES6中进行调试。您能帮我解决这个问题吗? - Miloš Đošović

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接