简体   繁体   中英

Using Babel with a single output file and ES6 modules

Here's my gulp task to compile my ES6 code into a single ES5 file. I use classes and modules ( import , export ) in ES6.

  gulp.src(paths.scripts)
        .pipe(sourcemaps.init())
        .pipe(babel({
          presets: ['es2015']
         }))
        .pipe(concat('all.js'))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./www/js'));

However, because Babel compiles ES6 import directives into require commands, and require will attempt to request a file, the request files are failing because all the ES5 code is concatted into one file, all.js.

The result is a bunch of "Error: Cannot find module" errors. How can I compile modules that work when they're all saved in a single file?

You're not the first one with the need of transpiling JSX/ES6 to ES5 with Babel but without using CommonJS modules and hence Browserify/Webpack. Unfortunately it turns out this is not possible at the time ( 1 , 2 , 3 ), and it looks like it won't be possible ever. You're pretty much forced to use these tools if you want to use ES6 transpiled with Babel, but you won't have the chance to use the resulting code with other concatenated/inline JavaScript (because of all those require() calls rather than global variables on window ). It's a pity Babel doesn't allow to change this behaviour.

You will probably need Browserify to make it work with gulp:

    browserify('./js/script.js', { debug: true })
      .add(require.resolve('babel-polyfill'))
      .transform(babelify.configure({presets: ['es2015']}))
      .bundle()
      .on('error', util.log.bind(util, 'Browserify Error'))
      .pipe(source('all.js'))
      .pipe(buffer())
      .pipe(sourcemaps.init({loadMaps: true}))
      .pipe(uglify({ mangle: false }))
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('./www/js'));

for example: https://github.com/glued/harp-babel/blob/babel-gulp-v6/gulpfile.babel.js

There's a way to handle this without using import at all and using gulp-include instead.

So what you do is you use gulp-include to tell gulp how to include files.

Then in your js files you can do something like this:

//=require views/_*.js
//=require views/*.js

So imagine I have a class called BaseView and I put it in a file called _baseView.js. Then I have another class called HomeView in a file valled homeView.js.

HomeView inherits BaseView

So _baseView.js needs to be loaded first.

The line of the require comments above ensures that happens by importing all views that start with _ first and then it imports the rest "note: it won't import the same file more than once, that's what require does vs include. require will pull in a file one time only and ignore future calls to the same file. Include will pull in the file as many times as the include is used.

So what I do is I create 1 single class, called something like "main.js" and in that class I put all the //=require comments to pull in all my code.

Then in my gulp task, the only source script I need is main.js, gulp-include handles the rest.

You can still make full use of most of ES6, just get rid of the need to use Import and Export.

Here's a really simple main.js

"use strict";

(function () {
    //=require views/_*.js
    //=require views/*.js
})();

And here's a simple gulp 4 task:

function demoScripts() {
    var ret = src([
            path.join(paths.srcDemoJs, 'main.js')
        ])
        .pipe(include({
            hardFail: true,
            includePaths: [
                paths.stage,
                path.join(paths.srcDemoJs)
            ]            
        }))
        .pipe(babel({
            presets: ['@babel/env']
        }))
        .pipe(dest(paths.dstDemo));
        return ret;
}

exports.build = demoScripts;

My gulpFile is using gulp4 and es6 because it's node, design time environment, don't care about es6 stuff there so exporting the gulp task is fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM