Skip to content
This repository has been archived by the owner on Oct 9, 2020. It is now read-only.

ES6-only sfx optimization #199

Closed
guybedford opened this issue Jun 15, 2015 · 13 comments
Closed

ES6-only sfx optimization #199

guybedford opened this issue Jun 15, 2015 · 13 comments

Comments

@guybedford
Copy link
Member

When creating an sfx bundle where every module in the tree is ES6, we can then take advantage of deep static optimizations.

The way to do this would be to call directly to a compiler like https://github.com/rollup/rollup in this optimization case.

@Rich-Harris as discussed before this would be very useful to allow users to actually author and distribute standalone ES6 projects through jspm - if you have any implementation tips or advice please do share here.

/cc @amcdnl

@Rich-Harris
Copy link

Cool - happy to help with this effort wherever possible. One thing that occurs to me is that you can still take advantage of static optimisations where only part of the bundle is ES6 - e.g. where you author your own app code in ES6 but rely on external dependencies distributed in a legacy format.

My current workflow for this sort of thing is to bundle all my ES6 modules with Rollup into a single CommonJS module, then hand it off to Browserify (which for present purposes is interchangeable with JSPM). For a decent-sized and well-factored codebase this can mean fairly significant savings over converting each ES6 module to a CommonJS equivalent and Browserifying the whole lot. Being able to do this in a single step would be a huge win - I've idly wondered about teaching Rollup how to handle legacy formats, but realistically it makes much more sense for JSPM to carry that load since it already knows how.

@guybedford
Copy link
Member Author

@Rich-Harris does that mean you are mixing CommonJS and ES6 import styles in the code, or does Rollup provide the option to define an "external import boundary" for import statements to remain as ES6 import statements?

@Rich-Harris
Copy link

You can use ES6 import styles everywhere and define a boundary like so:

rollup.rollup({
  entry: 'main.js',
  external: [ 'lodash' ]
}).then( function ( bundle ) {
  var es6 = bundle.generate({ format: 'es6' });
  var cjs = bundle.generate({ format: 'cjs' });
  // etc
});

So if you had something like this...

// main.js
import fibonacci from './fibonacci';

for ( let i = 0; i < 100; i += 1 ) {
  console.log( fibonacci( i ) );
}

// fibonacci.js
import { memoize } from 'lodash';

const fibonacci = memoize( x => {
  return x < 2 ? x : fibonacci( x - 2 ) + fibonacci( x - 1 );
});

export default fibonacci;

...the CommonJS bundle would look like this:

'use strict';

var lodash = require('lodash');

const fibonacci = lodash.memoize( x => {
  return x < 2 ? x : fibonacci( x - 2 ) + fibonacci( x - 1 );
});

for ( let i = 0; i < 100; i += 1 ) {
  console.log( fibonacci( i ) );
}

You'd then pass that off to Browserify/Webpack/JSPM/whatever for the second phase of bundling.

@Rich-Harris
Copy link

(Should mention - you can generate an ES6 bundle as well, which looks identical to the above example except it continues to use the named memoize import, and skips the redundant 'use strict' pragma)

@amcdnl
Copy link

amcdnl commented Jun 15, 2015

@Rich-Harris I've been trying to get sfx builds to work on this open source library i'm trying to get into a distributable package. https://github.com/Swimlane/angular-data-table/blob/master/gulpfile.js#L120 ... my result is not pretty :S - https://github.com/Swimlane/angular-data-table/blob/master/release/data-table.js

is that like something you are doing with rollup?

@Rich-Harris
Copy link

@amcdnl yes. You can generate a bundle from the angular-data-table source code like so:

var rollup = require( 'rollup' );

rollup.rollup({
  entry: 'src/data-table.js',
  external: [ 'angular' ]
}).then( function ( bundle ) {
  bundle.write({
    dest: 'bundle.js',
    format: 'umd',
    moduleName: 'DataTable'
  });
});

Save that to make-bundle.js or wherever, then npm i rollup && node make-bundle.js, and it'll create a UMD bundle.js.

In theory the following command would do the same thing (if Rollup was installed globally), but it seems I've just found a bug relating to the moduleName option so this doesn't work right now:

rollup -i src/data-table.js -o bundle.js -f umd -e angular -n DataTable

@guybedford
Copy link
Member Author

@Rich-Harris thank you, that is absolutely amazing and will completely allow these optimizations to apply to all sfx bundles with a little bit of careful graph handling.

@Rich-Harris
Copy link

@guybedford brilliant!

@amcdnl
Copy link

amcdnl commented Jun 15, 2015

@Rich-Harris got my case working using your rollup! Thanks for the help!

@Rich-Harris
Copy link

@amcdnl nice, glad to hear it!

@guybedford
Copy link
Member Author

Some small first steps made in #205.

@amcdnl
Copy link

amcdnl commented Jun 26, 2015

@Rich-Harris I'm having issues ( probably doing something wrong ) but when I build ( using your example config ) its passing undefined to my module.

https://github.com/Swimlane/angular-data-table/blob/204b4bbcb67b194458585bba3b7e476a6eec8e35/release/data-table.js#L11

Any ideas?

@guybedford
Copy link
Member Author

Continuing to track in the PR at #205. The implementation is working, but pending progress on systemjs/systemjs#579.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants