Using ES6 modules with traceur in single build file

人走茶凉 提交于 2020-01-23 10:11:18

问题


I just have a simple question cant get in any place, heve been googling for it all morning. There is no much info about traceur and when there is is not so clear, at least to me.

How should be implemented the ES6 modules when im transpiling with traceur a single output file and using it in the browser with traceur-runtime? import and export keeps getting Unexpected token.

I am using gulp-traceur and tried already all the modules options //'commonjs' //'amd', 'commonjs', 'instantiate', 'inline', 'register'.

One doubt I have is that I keep finding answers about commonjs, but my idea of using ES6 modules is to have differents sources and then from the main import them and have all this result compiled in one single file (what i mean is that I dont need async loading of the modules in the browser)

Here is the gulp task

gulp.task('scripts', function() {
      del.sync(['bin/js/main.min.js']);
      del.sync(['bin/js/main.min.js.map']);
      gulp.src(["./src/app/init.js", "./src/app/elements/circle.js", "./src/app/app.js"])
        .pipe(sourcemaps.init())
        .pipe(traceur({modules : 'inline', sourceMaps: 'inline', experimental: "true"})) //'commonjs' //'amd', 'commonjs', 'instantiate', 'inline', 'register'
          .on('error', errorParser)
        .pipe(jshint())
          .pipe(jshint.reporter('jshint-stylish'))
        .pipe(uglify({mangle: true})).on('error', errorParser)
        .pipe(concat('main.min.js'))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('bin/js'))
        .pipe(livereload({ auto: true }));
    });

The unexpected token comes from app when importing

import Circle from './elements/circle';

or

import * as Circle from './elements/circle.js';

(Tried several ways)

Also from circle.js when exporting

export default Circle; or export Circle; (also tried several ways)


回答1:


At the end I finished switching Traceur for Babel as adviced by @Jeff in his comment.

So my solution was to use Babel + Browserify + Gulp

I think the error I was getting is regarding the code is transpilled correctly but no client is able to manage modules yet so is needed something like require or commonjs to handle the modules, Themain doubt is here, because I would expect traceur to already transform the code to ES5 understandable code. But again, the lack of info doesnt point this clear (I was googling more than 6 hours)

I use a Browserify tool, babelify, that automatically translates the ES6 module syntax to browser understandable commonjs.

This made my day. Due to lack of info I took time to realize/guess that using Browserify with Traceur would work also, but after taking a look at Babel, I think has advantages over Traceur, specially no need of runtime.js on the client, and the output is more consistent and less bloated.

I paste below the gulp task I am using if it helps someone in the future:

gulp.task('scripts', function() {

  del.sync(['bin/js/main.min.js']);
  del.sync(['bin/js/main.min.js.map']);

  gulp.src(["./src/**/*.js", "!./src/lib/*.js"])
    .pipe(gp.jshint())
    .pipe(gp.jshint.reporter('jshint-stylish'));

  browserify({
    entries: './src/app/app.js',
    debug: true
  })
  .transform(babelify)
  .bundle().on('error', errorParser)

  .pipe(source('main.js'))
  .pipe(gulp.dest('./bin/js'))
    .pipe(gp.livereload({ auto: true }));

});

Let me know if you have a better approach.




回答2:


It is actually possible to load ES6 modules directly in the browser.

1) Load the transpiler libs

<!-- transpiler -->
<script type="text/javascript" src="lib/traceur.js"></script>
<script type="text/javascript" src="lib/es6-module-loader.js"></script>

2) import your coded modules, I have used System.paths here, however it is not necessary to do so, you can import with a direct relative path:

System.paths['gso/eonjs/*'] = 'dist/es6/gso/eonjs/*.js';

var Eon;
var MomentRecurRule;
var RRuleRecurRule;
var RecurRuleContainer;
System.import('gso/eonjs/EonJS').then( function( _exports ) {
    Eon = _exports;
    MomentRecurRule = Eon.MomentRecurRule;
    RRuleRecurRule = Eon.RRuleRecurRule;
    RecurRuleContainer = Eon.RecurRuleContainer;
});

Which leaves the main API and classes in the global namespace.

System.import() is asynchronous, so the code will step past to the next line before the modules have actually loaded - a loading widget would do the trick I would guess at this point.

See example-es6-modules.html for the full working example.

I'm using traceur at the moment only for historical reasons, what I am aiming to do though overall is stay as much tech. neutral as possible - so although I've used traceur, I aim to not lock myself into using traceur - the project could switch over to babel relatively easily (tactically that is the primary principle). There are lots of good reasons for coding with babel though, and I am more or less sure I will at some point make the switch for those reasons (and still be happily transpiling when everybody else has returned to normal coding with the fully supported and newly minted ES2015).



来源:https://stackoverflow.com/questions/29882004/using-es6-modules-with-traceur-in-single-build-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!