webpack之tree shaking

转载自品略图书馆 http://www.pinlue.com/article/2020/03/1917/3010036260828.html

 

什么是tree-shaking?

前端中的tree-shaking可以理解为通过工具"摇"我们的js文件,将其中用不到的代码"摇"掉,是一个性能优化的范畴。具体来说,在webpack项目中,

有一个入口文件,相当于一棵树的主干,入口文件有很多依赖的模块,相当于树枝。实际情况中,虽然依赖啦某个模块,但其实只使用其中的某些功能。通过

tree-shaking,将没有使用的模块摇掉,这样来达到删除无用代码的目的。

tree-shaking原理

tree-shaking原理,简单来说

tree shaking的本质是消除无用的Javascript代码

因为ES6模块的出现,ES6模块依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析

怎么使用tree-shaking?

在webpackDemo/demo下新建一个文件tree-shaking,文件目录如下

index.js内容如下

import {add} from "./math.js"console.log(mathFn)function component(){ var element = document.createElement("pre"); element.innerHTML = [ "hello webpack", "5 cubed is equal to " add(5,6) ].join("\n\n"); return element;}document.body.appendChild(component())math.js内容如下

export function add(a,b){ console.log("add"); return a b;}export function minus(a,b){ console.log("minus") return a-b}export function multiply(a,b){ console.log("mutiply"); return a*b;}export function divide(a,b){ console.log("divide"); return a/b;}tree-shaking.js内容如下

const path = require("path");const HtmlWebpackPlugin = require("html-webpack-plugin");const {CleanWebpackPlugin} = require("clean-webpack-plugin");const webpack = require("webpack");module.exports = { mode:"development", entry:path.resolve(__dirname,"src/index.js"), module:{ rules:[ { test:/\.m?js$/, exclude:/(node_modules|bower_components)/, use:{ loader:"babel-loader", options:{ presets:["@babel/preset-env"], plugins:[ "@babel/plugin-transform-runtime" ] } } } ] }, output:{ filename:"bundle.js", path:path.resolve(__dirname,"dist") }, plugins:[ new CleanWebpackPlugin(), new HtmlWebpackPlugin(),// new webpack.NamedModulesPlugin(),// new webpack.HotModuleReplacementPlugin() ], devtool:"inline-source-map",// devServer:{// contentBase:"./dist",// hot:true,// inline:true// }}package.json 内容如下

{ "name": "webpackDevServer", "sideEffects": false, "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack-dev-server --config demo/webpack-dev-server/webpack-dev-server.js", "server": "node demo/webpack-dev-middleware/server.js", "hmr": "webpack-dev-server --config demo/HMR/webpack.hmr.js", "treeShaking:dev": "webpack-dev-server --config demo/tree-shaking/tree-shaking.js", "treeShaking:build": "webpack --config demo/tree-shaking/tree-shaking.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@babel/core": "7.6.4", "@babel/plugin-transform-runtime": "^7.6.2", "@babel/preset-env": "^7.6.3", "babel-loader": "8.0.6", "clean-webpack-plugin": "3.0.0", "css-loader": "3.2.0", "express": "4.17.1", "html-webpack-plugin": "3.2.0", "style-loader": "1.0.0", "webpack": "4.41.2", "webpack-cli": "3.3.9", "webpack-dev-middleware": "3.7.2", "webpack-dev-server": "3.8.2" }}执行 npm run treeShaking:build

执行结果如下

 

 

执行后我们可以看到bundle.js文件,可以发现math.js中所有的代码都被打包了,而我们只用了文件中的add函数,我们没用到的函数不想打包到文件,这时我们可以用到tree-shaking

启用webpack

当前项目中使用的是webpack4,讲mode设置为production即可开启tree shaking

关于side effects(副作用)

副作用是指除了函数返回值以外,任何在函数调用之外观察到的应用程序状态改变。副作用包括:

改变了任何外部变量或对象属性(例如,全局变量,或者一个在父级函数作用域链上的变量)

写日志

在屏幕输出

写文件

发网络请求

触发任何外部进程

调用另一个有副作用的函数

tree shaking不能自动的识别那些代码属于side effects,因此手动指定这些代码非常重要,如果不指定可能会出现一些意想不到的问题

在webpack中,是通过packge.json的sideEffects属性来实现的

{

"name":"tree-shaking",

"sideEffects":false

}

如果所有代码都包含副作用,我们可以简单地将属性标记为false,并告知webpack,他可以安全地删除未用到的export导出

如果你的代码确实有一些副作用,那么可以改为提供一个数组

{

"name": "tree-shaking",

"sideEffects": [

"./src/common/polyfill.js"

]

}

总结

tree shaking 不支持动态导入(如CommonJS的require()语法),只支持纯静态的导入(ES6的import/export)

webpack中可以在项目package.json中添加一个"sideEffects"属性,手动指定有副作用的脚本

将mode修改,在package.json里设置sideEffects:false结果如下

 

 

我们可以看出使用了tree shaking后,代码体积变小,并且我们引用的math.js函数add被转换,其他未引用的代码并没有出现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值