As the title implies, I’d like to learn more about Ember + Rollup to help shrink the builds.
Searching the web hasn’t been fruitful - I’ve only come across two Ember addons using Rollup.
As the title implies, I’d like to learn more about Ember + Rollup to help shrink the builds.
Searching the web hasn’t been fruitful - I’ve only come across two Ember addons using Rollup.
I’ve had some success using rollup for ember application, but my method is completely unsupported. Steps involved are:
["routes", "product", "/my/project/modules/products/routes/product.js"]
.import
directive for every resource.import r42 from '/my/project/modules/products/routes/product.js'
app.register
call for every resource.app.register("route:product", r42);
Ember.TEMPLATES["product-template"] = r43;
rollup
in IIFE mode on the registration file.The whole procedure, implemented in python is about 150 lines long.
Advantage: no runtime overhead, all dependencies are resolved at bundling time. That makes a smaller js bundle (no module boilerplate) that starts faster (no runtime-resolution with require).
Drawback: rollup bundling is an all-or-nothing process. Every change must regenerate the bundle from scratch. Rollup is very fast though, on my laptop from 2014, I bundle a 400-file project in about 0.5s.
Additional drawback: you’re on your own. You build your bundling system so when it breaks, you get to fix it.
@Garrick> FWIW, I converted my generator from python to node.js.
I uploaded it as a gist. It’s not “polished” as I don’t intend to release or support it in any kind of official way, but it works great on my Ember 2.14 project.
Notes:
My very simplified tree looks like this:
article-manager/
article-editor/
component.js
template.hbs
article-state/
component.js
template.hbs
controllers/
article/
edit.js
models/
article.js
routes/
article.js
article/
edit.js
templates/
article.hbs
article/edit.hbs
library/
helpers/
date.js
filesize.js
ui-listview/
component.js
template.hbs
ui-slug-field/
component.js
template.hbs
ui-splitview/
component.js
template.hbs
main/
initializers/
router.js
routes/
application.js
templates/
application.hbs
(in reality I have many more directories at topmost level: gallery, dropbox, geographic data, you name it - all of them are equals when it comes to rolling up the final application though, which also means the article editor can use the picture-picker component from the gallery module)
The generator will create a javascript file that imports all relevant files and contains a “registrations” application initialiser that registers all classes and templates. I feed it into rollup that does its magic and voila.
@spectras am I correct in grokking that this does not transpile the build? It gives you a way to bundle the entire ember application without running it through babel, minification, etc. I may explore something like this for our app because the ember build times are a bottle neck. Ideally I would break up the project into smaller ones but that seems like more work and maintenance overhead.
@efx this only generates a “master” script that imports everything else and registers classes with Ember. That’s all.
You can then give that script as the main script to rollup so it bundles everything. I know rollup supports babel and I did use its uglify plugin successfully. I don’t use transpiling though as the ES5 and ES6 features I use are mostly supported by my targets.
Just to make it less abstract, here is a sample output from my script:
import Ember from 'ember';
import r0 from '../node_modules/@private/ember/helpers/can.js';
import r1 from '../node_modules/@private/ember/helpers/date.js';
import r5 from '../node_modules/@private/ember/services/notifications.js';
import r6 from '../node_modules/@private/ember/services/permissions.js';
import r7 from '../node_modules/@private/ember/services/workers.js';
import r12 from '../main/adapters/application.js';
import r13 from '../main/controllers/application.js';
import r14 from '../main/routes/application.js';
import r15 from '../main/ui-breadcrumbs/component.js';
import r17 from '../author/author-editor/component.js';
import r20 from '../author/models/author.js';
import r21 from '../author/routes/author.js';
import {} from '../main/initializers/router.js';
Ember.Application.initializer({
name: 'registrations',
initialize: function (app) {
var t = Ember.TEMPLATES;
app.registerOptionsForType('model', {singleton: false});
app.register("helper:can", r0);
app.register("helper:date", r1);
app.register("service:notifications", r5);
app.register("service:permissions", r6);
app.register("service:workers", r7);
app.register("adapter:application", r12);
app.register("controller:application", r13);
app.register("route:application", r14);
app.register("component:ui-breadcrumbs", r15);
app.register("component:author-editor", r17);
app.register("model:author", r20);
app.register("route:author", r21);
t["application"] = Ember.HTMLBars.template({/* left out for brievity */});
t["components/author-editor"] = Ember.HTMLBars.template({/* left out for brievity */});
}
});
As you see, it’s all about emitting the proper imports and feeding the classes to Ember.
Neat! makes sense. Those build times are quite impressive. At least for testing, the application I work on supports most ES5-6 features. Using your approach here could really help our build times. If I get to it I want to try it on our application.