-
Notifications
You must be signed in to change notification settings - Fork 64
webpack treeshaking/deadcode elimination additional features? #36
Comments
This might be off the mark but I spent most of today trying to understand why the closure compiler can't minify a webpack bundle very well. It seems to me that it's due to webpack loading modules at runtime, if you could flatten your dependencies when only ES6 imports were used (don't think it would be compatible with CommonJS) then the advanced compilation would be able to remove dead code better. i.e. instead of this var installedModules = {};
// ...
function __webpack_require__(moduleId) {
// This has side effects but with ES6 modules usually we don't care about them
// but because of this the closure compiler can't get rid of dead code
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
}
// Load entry module and return exports
__webpack_require__(__webpack_require__.s = 0); have something like this // Generate a bundle with modules already loaded, will lose record of the side
// effects caused by loading them at runtime, but for most cases that's okay
var installedModules = {
1: {
exports: { /* ... */ }
},
2: {
exports: { /* ... */ }
},
}
// Run entry module.... |
Can you explain the motivation for using webpack together with closure compiler? Closure compiler is a bundler so it should get individual ES6 JS inputs. Minifying a bundle is a bad idea because
I do think it would be interesting if webpack's code splitting for lazy loading could produce a manifest file listing the chunks and their inputs, then closure compiler could produce optimized chunks along the lines of https://github.com/cramforce/splittable |
My original thinking was that the compiler was only a code minifier. I wanted the ease of use of webpack with the power of the CC in advanced mode. After getting my sample project working with the CC it was very difficult, documentation is thin and some versions of the CC just don't work, webpack is much easier to use, there's loads of documentation and a larger community to help. But it came down to my bundle size, with CC it was 6.8 kb but with webpack it was 151kb, CC is the winner here. Webpack only does tree shaking at a surface level, i.e. the exports that aren't imported. CC removes all the dead code.
I'm probably not understanding what you mean but I think I'd want this, I don't want modules that aren't loaded in my bundle
I'm not sure what impact this has?
I guess I could map back to the unminified webpack bundle, that would probably be enough to track down bugs |
It makes sense to use webpack still, as the devserver (closure is too slow
for a good edit-refresh cycle) and for code splitting. I'm just pointing
out that the closure compiler integration should take individual ES6
sources rather than the bundle(s) as inputs.
1. closure dropping modules is important, because some modules might have
side effects on load (eg. class definitions) but you can demonstrate the
module can't be loaded at runtime (no import from there) so it can give
extra size improvements
2. losing the class structure means less efficient optimization, I'd expect
single digit percentage size increase from ES5
3. bad sourcemaps are a constant productivity drain, we try fairly hard not
to break these
I am working this week on a much easier build system for invoking closure
compiler, using http://bazel.build and
https://github.com/bazelbuild/rules_closure with TypeScript apps, maybe
that's useful for you? Follow
bazelbuild/rules_typescript#6
…On Sun, Sep 24, 2017 at 4:32 PM Alastair Taft ***@***.***> wrote:
My original thinking was that the compiler was only a code minifier. I
wanted the ease of use of webpack with the power of the CC in advanced
mode. After getting my sample project working with the CC it was very
difficult, documentation is thin and some versions of the CC just don't
work, webpack is much easier to use, there's loads of documentation and a
larger community to help.
But it came down to my bundle size, with CC it was 6.8 kb but with webpack
it was 151kb, CC is the winner here. Webpack only does tree shaking at a
surface level, i.e. the exports that aren't imported. CC removes all the
dead code.
• closure can drop whole modules if they are not imported
I'm probably not understanding what you mean but I think I'd want this, I
don't want modules that aren't loaded in my bundle
• the output bundle is ES5(?) so closure loses the class structure
I'm not sure what impact this has?
• properly composing the sourcemaps seems hard
I guess I could map back to the unminified webpack bundle, that would
probably be enough to track down bugs
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#36 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAC5I8dMk1fpzzIr8QmtCQY10kM5JboMks5sluZ5gaJpZM4K11U6>
.
|
Ah thanks, that's some very good points to consider and thanks for those links will have a read through them. |
For proper webpack support, use the https://github.com/webpack-contrib/closure-webpack-plugin plugin |
So currently, webpack imperitively builds a dependency graph, and has library specific syntax for code splitting, lazy loading, and optimizing chunks (sub-tree of modules), based on order, occurence, size, etc.
However one feature that is limiting that we believe we would love to leverage (as a library) a better tree shaking story.
Currently webpack only "marks" unused modules and exports, dependencies, etc. Would it be possible to design a future that would allow some more advanced c-c-js features like --module but instead passing the symbol/name references in the ast of the code that is not used?
--unused-symbols="name:file:line:loc" etc.
This is kind of off the top of my head but I wondered if this is something that could be considered or noteworthy. If anything just get the discussion flowing for a more powerful webpack+cc-js story.
Thanks!
The text was updated successfully, but these errors were encountered: