Joe Bruno
Joe Bruno

Reputation: 427

Webpack Alias and ES6 imports / exports

This is a two part question.

I have set up a Webpack alias named controls to a particular files that houses all of my shared React components. This file is simply a index.js file that imports all of the desired components (approximately 30 shared components) and then exports them like:

export { Button, Tabs, ProgressBar, Carousel, … }

The components are from various places (libraries, mine, etc). My understanding of imports is that if I write

import { Button } from ‘controls';

anywhere in my project where I want to use Button, only Button should be pulled into my dependency tree - not every export from 'controls/index.js'.

First Question: is my understanding of the way imports / exports should be working here accurate?

Now for the problem: all of the components, whether they are used in a particular bundle or not, are being pulled into every bundle. I am pretty sure that this is happening because of my Webpack alias.

Second Question: anyone have any advice on how I can still cleanly import multiple shared components on a single line like

import { Button, Tabs, InitialsAvatar } from 'controls';

but not pull all of my controls (aka shared React components) into the dependency tree?

I have played around with Webpack's moduleDirectores and root, but these have not allowed me to import multiple components on a single line and don't allow me to use a single index.js file to house all of my shared components.

Upvotes: 1

Views: 1216

Answers (1)

Priyesh Diukar
Priyesh Diukar

Reputation: 2142

Upgrade to webpack 2+, it supports tree-shaking.

Now Webpack 2+ only marks code unused and doesn’t export it inside the module. It pulls everything and leaves unused code for minification libraries.

You can use UglifyJS with babel for this. UglifyJS doesn’t support the new language features of Javascript ES2015+ yet. You will need Babel to transpile the code to ES5 and then use UglifyJS to clean up the unused code.

You will need .babelrc file with:

We have to tell the preset (in our case babel-preset-env) to skip the module transpilation.

{
  "presets": [
    ["env", {
      "loose": true,
      "modules": false
    }]
  ]
}

and corresponding webpack config:

module: {
  rules: [
    { test: /\.js$/, loader: 'babel-loader' }
  ]
},

plugins: [
  new webpack.LoaderOptionsPlugin({
    minimize: true,
    debug: false
  }),
  new webpack.optimize.UglifyJsPlugin({
    compress: {
      warnings: true
    },
    output: {
      comments: false
    },
    sourceMap: false
  })
]

OR

Babili is a better option since Babili will remove unused code before transpilation. It is much easier to spot unused classes before downleveled to ES5. Tree-shaking will also work for class declarations, not just functions.

You will need:

npm install babili babili-webpack-plugin --save-dev

Use the following plugin in your webpack config, like so:

plugins: [
  new BabiliPlugin()
]

There is also an optimzied way to use babili as a preset. You can refer their site to use it as a preset for babel-loader.

Upvotes: 0

Related Questions