Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use tree shaking in Webpack?

Tags:

I just updated to webpack 2.1.0-beta.15 with an Angular 2 (version rc.2) app (with Typescript), but I was wondering how to use the tree shaking feature. I read it should work "out of the box", but I'm still having a bundle of 1.7Mb for a very simple application, so probably I'm doing something wrong.

This is what I have so far:

tsconfig.json

{   "compilerOptions": {     "target": "es5",     "sourceMap": true,     "emitDecoratorMetadata": true,     "experimentalDecorators": true,     "removeComments": false,     "noImplicitAny": false   },   "exclude": [     "node_modules",     "typings/main",     "typings/main.d.ts"   ] } 

package.json

{   "name": "angular2-quickstart",   "version": "1.0.0",   "scripts": {     "build": "webpack --progress",     "build:prod": "webpack -p --progress --optimize-minimize",     "postinstall": "typings install",     "serve": "webpack-dev-server --inline --progress --output-public-path=/dist/"   },   "license": "ISC",   "dependencies": {     "@angular/common": "2.0.0-rc.2",     "@angular/compiler": "2.0.0-rc.2",     "@angular/core": "2.0.0-rc.2",     "@angular/forms": "0.1.0",     "@angular/http": "2.0.0-rc.2",     "@angular/platform-browser": "2.0.0-rc.2",     "@angular/platform-browser-dynamic": "2.0.0-rc.2",     "@angular/router": "2.0.0-rc.2",     "@angular/router-deprecated": "2.0.0-rc.2",     "@angular/upgrade": "2.0.0-rc.2",     "angular-pipes": "1.4.0",     "bootstrap": "3.3.6",     "core-js": "2.4.0",     "file-loader": "0.9.0",     "jquery": "2.2.3",     "lodash": "4.13.1",     "reflect-metadata": "0.1.3",     "rxjs": "5.0.0-beta.6",     "script-loader": "0.7.0",     "style-loader": "0.13.1",     "url-loader": "0.5.7",     "zone.js": "0.6.12"   },   "devDependencies": {     "concurrently": "^2.0.0",     "css-loader": "0.23.1",     "html-loader": "0.4.3",     "json-loader": "^0.5.4",     "raw-loader": "0.5.1",     "ts-loader": "0.8.2",     "typescript": "1.8.10",     "typings": "1.0.4",     "webpack": "^2.1.0-beta.15",     "webpack-dev-server": "^2.1.0-beta",   } } 

webpack.config.js

var webpack = require('webpack');  var PROD = JSON.parse(process.env.PROD_ENV || '0');  module.exports = {     entry: './app/main.ts',     output: {         path: './dist',         filename: 'app.bundle.js'     },     module: {         loaders: [         { test: /\.json$/, loader: 'json', include: [/node_modules/] },         { test: /\.ts$/, loader: 'ts' },         { test: /\.html$/, loader: 'html' },         { test: /\.css$/, loader: 'style!css' },         { test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' }         ]     },     resolve: {         extensions: ['', '.js', '.ts', '.css']     },     'htmlLoader': {         caseSensitive: true     },     plugins: PROD ? [         new webpack.optimize.UglifyJsPlugin({             compress: { warnings: false }         })     ] : [] } 

I'm using fairly standard import statements such as import {FORM_DIRECTIVES,REACTIVE_FORM_DIRECTIVES} from '@angular/forms' and trying to import only what I need (import 'rxjs/add/operator/map';) and running the build with npm run build:prod with the environment variable PROD_ENV=1.

Maybe something like jquery or lodash is causing issues (import * as $ from 'jquery' or import {orderBy} from 'lodash'), but I believe both are relatively small. According to the webpack visualizer, Jquery and Lodash account for 6.2% and 12% of the bundle size, respectively. Angular uses 49% of the bundle size.

What am I missing?

like image 963
Robert Smith Avatar asked Jul 09 '16 16:07

Robert Smith


People also ask

Does webpack have tree shaking?

In webpack, tree shaking works with both ECMAScript modules (ESM) and CommonJS, but it does not work with Asynchronous Module Definition (AMD) or Universal Module Definition (UMD).

How do you implement tree shaking?

In order to implement tree shaking in react application you will need to have a module bundler that will bundle the entire app's code. You can either use WebPack or RollUp for bundling your application.

How does a shaking tree work?

Tree shaking is a term commonly used within a JavaScript context to describe the removal of dead code. It relies on the import and export statements to detect if code modules are exported and imported for use between JavaScript files.


2 Answers

For treeshaking you have to use typescript 2

npm i typescript@next --save-dev

which supports

tsconfig.json

{   "compilerOptions": {     "module": "es6",     "target": "es5"    } } 

This is because es6 modules are statically analyzable and Webpack can determine which of your dependencies are used and which are not.

like image 145
evandertino Avatar answered Oct 18 '22 03:10

evandertino


Tree Shaking wasn't shipped with Webpack 2 and is still blocked without a clear way forward according to Core team comments in the issue. I'm afraid you may be wearing The Emperor's New Clothes.

like image 31
vhs Avatar answered Oct 18 '22 04:10

vhs