Original link: github.com/yinxin630/b… Technical exchange group: fiora.suisuijiang.com/
In WebPack 2, support for ES Modules was added to enable WebPack to parse unused export content and tree-shrking it out
However, webPack will keep the code that has side effects in the module
For example, there are utils/ A.js and /utils/b.js modules in the project, and unified entry is provided through utils/index.js where module B contains a print statement, which has side effects
// utils/a.js
export function a() {
console.log('aaaaaaaaaaaaa');
}
// utils/b.js
console.log('======== b.js ==========');
export function b() {
console.log('bbbbbbbbbbbbbb');
}
// utils/index.js
export * from './a';
export * from './b';
Copy the code
Add the main entry app.js and reference only module A. We expect unused module B to be tree-shaking away
// app.js
import { a } from './utils';
a();
Copy the code
Let’s take a look at the result of packaging, and be sure to package in Production mode. As a result, I removed the irrelevant WebPack startup code as shown below
// output
([
function(e, t, r) {
'use strict';
r.r(t),
console.log('======== b.js =========='),
console.log('aaaaaaaaaaaaa'); },])Copy the code
The package result does not include the B module, but the side effect code in B. js is retained, which makes sense
SideEFfects role
Modify the content of B. Js below
// utils/b.js
Object.defineProperty(Array.prototype, 'sum', {
value: function() {
return this.reduce((sum, num) = > sum += num, 0); }})export function b() {
console.log([1.2.3.4].sum());
}
Copy the code
We define a new method, SUM, on the Array prototype chain, which has side effects. I then called this method in module B, but as the maintainer of module B, I wanted sum to be “pure”, used only by me, and not dependent on its implementation
Modify package.json to add field “sideEffects”: False, this field indicates that the whole project is re-compiled with “no side effects”. Expect the sum method defined in b to be tree-shaking away if b module is not used
([
function(e, t, r) {
'use strict';
r.r(t), console.log('aaaaaaaaaaaaa'); },])Copy the code
As expected, the entire B module is tree-shaking off, including the code that contains side effects
As a result, sideEffects can optimize the packaging volume and to some extent reduce webpack source code analysis and speed up the packaging
You can try again with package results that reference b modules, set sideEffects to true, remove sideEffects, and so on
SideEffects configuration
In addition to Boolean values, sideEffects can be set to arrays, pass code files that need to keep sideEffects (e.g. “./ SRC /polyfill.js”) or pass fuzzy matching characters (e.g. “SRC /**/*.css”).
sideEffects: boolean | string[]
Copy the code
SideEffects Considerations
In real projects, “sideEffects”: false is usually not a simple option. Some sideEffects, such as introducing style files, need to be retained
Webpack considers all import ‘XXX’ statements to be imported but not used. If you incorrectly declare them as “no side effects “, they will be tree-shaking away, and since tree-shaking only works in production mode, It is possible that everything will still be fine when you develop locally and problems will not be discovered in time
These are all examples of “introduced, not used”
import './normalize.css';
import './polyfill';
import './App.less';
Copy the code
And correspondingly, this one doesn’t count
import icon from './icon.png';
function Icon() {
return (
<img src={icon} />)}Copy the code
So these files that have sideEffects, we’re going to declare them correctly, change the sideEffects value
// package.json
"sideEffects": [
"./src/**/*.css"
]
Copy the code
In use, it is important to set the sideEffects value correctly
SideEffects limitations
SideEffects configuration is file-based, so as long as you configure the file to have sideEffects, even if you only use the part of the file that doesn’t have sideEffects, the sideEffects are retained
For example, change b.js to
Object.defineProperty(Array.prototype, 'sum', {
value: function() {
return this.reduce((sum, num) = > sum += num, 0); }})export function b() {
console.log([1.2.3.4].sum());
}
export function c() {
console.log('ccccccccccccccccccc');
}
Copy the code
In app.js only c method is introduced, b method is tree-shaking, but sum method is not
Let’s talk about what side effects mean
The first time you look at the sideEffects configuration, why declare it “sideEffects free” when the code clearly has sideEffects?
Another way to think about it is that sideEffects tells webpack that the module is safe tree-shaking, without worrying about sideEffects
The latter
SideEffects has a great impact on the WebPack build process, especially for developing NPM modules. Pay special attention to the correctness of the statement