Reputation: 427
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
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