add delayed transpilation#7501
Conversation
6db915c to
283f446
Compare
|
@kellyselden should the Though I know that adds a maintenance cost too. |
lib/broccoli/amd-excluder.js
Outdated
| let source = fs.readFileSync(inputFilePath, 'utf8'); | ||
|
|
||
| // ember-data and others compile their own source | ||
| if (source.indexOf('define(') === 0) { |
There was a problem hiding this comment.
Should be fine, but I'm not 100 about potential edgecases. It would likely not be compatible JS anyway so this should be good enough to figure out if something is AMD.
On the other hand, what if the module is exported for AMD but doesn't define immediately.
There was a problem hiding this comment.
There are a lot of potential edge cases, but in reality we only have to worry about how babel formats the AMD code, which this should cover completely?
|
@rtablada I am in favor of extracting it. |
|
I'd like to see what documentation (if any) is needed for addon authors to make sure their addons work with this. Bonus points for docs on how to utilize these changes in addons. |
|
@rtablada The only thing addons have to worry about is the first bullet point
|
lib/broccoli/amd-excluder.js
Outdated
| const Funnel = require('broccoli-funnel'); | ||
| const walkSync = require('walk-sync'); | ||
|
|
||
| class AmdExcluder extends Funnel { |
There was a problem hiding this comment.
can you use https://github.com/broccolijs/broccoli-test-helper to write a few tests for this class?
There was a problem hiding this comment.
a little bit of documentation on this class might also be nice. e.g. answering the question that @rtablada raised about this being specialized to detect AMD modules compiled by Babel (5? 6? 7?)
lib/broccoli/amd-excluder.js
Outdated
| let files = walkSync(inputPath, { | ||
| directories: false, | ||
| globs: [`**/*.js`], | ||
| }); |
There was a problem hiding this comment.
does build() have to be sync? otherwise it might make sense to read and process several files in parallel 🤔
There was a problem hiding this comment.
Doesn't have to be. Which package should I use for async walking?
There was a problem hiding this comment.
I guess walkSync is okay, but the loop afterwards could possibly be concurrent
There was a problem hiding this comment.
Changed to async readFile. Was this what you were thinking?
lib/broccoli/amd-excluder.js
Outdated
|
|
||
| // ember-data and others compile their own source | ||
| if (source.indexOf('define(') === 0) { | ||
| this.exclude.push(file); |
There was a problem hiding this comment.
will this fill up this.exclude with duplicate entries on rebuilds? we might have to reset this.exclude = []; at the beginning of build() 🤔
| precompiledSource = preprocessJs(precompiledSource, '/', '/', { | ||
| annotation: `_compileAddonJs`, | ||
| registry: this.registry, | ||
| }); |
There was a problem hiding this comment.
I'm wondering if in terms of performance it would be better to teach preprocessJs() about the AMD exclusion rule 🤔 but then again that is something that can probably be refactored later...
4f09907 to
529d6af
Compare
|
wooo tests finally green. |
614ab47 to
4670071
Compare
f7dc658 to
d83a323
Compare
d83a323 to
4132594
Compare
twokul
left a comment
There was a problem hiding this comment.
Reviewed with @rwjblue (and @kellyselden / @twokul), this seems good with a couple of minor cleanup points...
tests/unit/models/addon-test.js
Outdated
| `(NOT \`devDependencies\`) in \`${addon.name}\`'s \`package.json\`.` | ||
| ); | ||
| }); | ||
| // it('should throw a useful error if a template compiler is not present -- non-pods', function() { |
lib/models/addon.js
Outdated
| `Please make sure your template precompiler (commonly \`ember-cli-htmlbars\`) is listed in \`dependencies\` ` + | ||
| `(NOT \`devDependencies\`) in \`${this.name}\`'s \`package.json\`.`); | ||
| } | ||
| // if (!registryHasPreprocessor(this.registry, 'template')) { |
lib/broccoli/ember-app.js
Outdated
| }); | ||
|
|
||
| this._cachedAddonTree = new Funnel(combinedAddonTree, { | ||
| let compiledAddonTree = this._compileAddonTree(combinedAddonTree); |
There was a problem hiding this comment.
Can we add some broccoli-debug trees for before and after? I'm mostly thinking this will be super useful for seeing where some transpilation issues might be coming from...
There was a problem hiding this comment.
I emulated the style from the assembler. @twokul you may want to verify.
lib/broccoli/ember-app.js
Outdated
| } | ||
|
|
||
| _compileAddonTemplates(tree) { | ||
| if (registryHasPreprocessor(this.registry, 'template')) { |
There was a problem hiding this comment.
I remember why I added it. Without it we get errors in the styles tests https://travis-ci.org/ember-cli/ember-cli/jobs/337422087#L805-L813 missing template preprocessor. I will add more mocking to the styles tests.
lib/broccoli/amd-excluder.js
Outdated
| let inputFilePath = path.join(inputPath, file); | ||
| return fs.readFile(inputFilePath, 'utf8').then(source => { | ||
| if (source.indexOf('define(') === 0) { | ||
| this.exclude.push(file); |
There was a problem hiding this comment.
this.exclude needs to be reset here (and we probably need to clear whatever funnel caches have been build up)
There was a problem hiding this comment.
exclude is reset and it prints to console. the code has been moved to https://github.com/ember-cli/broccoli-amd-funnel. I also added tests.
lib/broccoli/ember-app.js
Outdated
| } | ||
|
|
||
| _compileAddonJs(tree) { | ||
| let precompiledSource = new AmdExcluder(tree, { |
There was a problem hiding this comment.
lets add a flag to opt-in or out of this tree as an option to new EmberApp, the default value should be true (e.g. use the amd excluder) but ultimately we should try to change it to false once a good number of popular addons have been updated...
lib/models/addon.js
Outdated
| // treeForAddon without calling super | ||
| // they need the original params preserved because they call | ||
| // babel themselves and expect compilation the old way | ||
| this.options[emberCLIBabelConfigKey] = Object.assign({}, original, { |
There was a problem hiding this comment.
This really should be moved back to the constructor if at all possible, setting it here means that others that depend on it earlier just don't have access to the values when they expect...
There was a problem hiding this comment.
I remember why I placed it here instead of the constructor. Having it in the constructor means I need to handle the legacy /modules using broccoli-module-normalizer. Making that change now.
5f3a5f6 to
3198d21
Compare
|
so far, both @kellyselden and I, are seeing anywhere between 15-30% slowdown (depending on the application we run benchmarks against). I ran tests against here's what a flame chart w/o delayed transpilation looks like: and here's a chart w/ delayed transpilation: Note, that we started running Babel twice (essentially unnecessary work). also, order in which we process add-ons have changed (from We can optimize and don't run Babel twice but there's a gap we're still seeing: |
94063b2 to
a2bb5e3
Compare
16af76f to
1113dc8
Compare
0bee743 to
2da17aa
Compare
2cd5918 to
7801f39
Compare
7801f39 to
0aec861
Compare
|
I believe this PR is breaking things, specifically we seem to trying to transpile handlebars templates that exist |
|
@stefanpenner - This should have been fixed by #7735, no? |



I would like some feedback. Things to note:
treeForAddon/compileModuleswarning, because it is now the desired behavior.compileTemplatesno template processor warning, because it is now the desired behavior.Sample console output:
Left to do: