Tree Shaking概念详解
时间:2022-07-26
本文章向大家介绍Tree Shaking概念详解,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Tree Shaking 值的就是当我引入一个模块的时候,我不引入这个模块的所有代码,我只引入我需要的代码,这就需要借助 webpack 里面自带的 Tree Shaking 这个功能来帮我们实现。
官方有标准的说法:Tree-shaking的本质是消除无用的js代码。无用代码消除在广泛存在于传统的编程语言编译器中,编译器可以判断出某些代码根本不影响输出,然后消除这些代码,这个称之为DCE(dead code elimination)
在 webpack 项目中,有一个入口文件,相当于一棵树的主干,入口文件有很多依赖的模块,相当于树枝。实际情况中,虽然依赖了某个模块,但其实只使用其中的某些功能。通过 Tree-Shaking,将没有使用的模块摇掉,这样来达到删除无用代码的目的。
在production 模式下不用在webpack.config.js中配置
optimization: { usedExports: true
} 当在development模式下配置tree shaking时: webpack.config.js
//HtmlWebpackPlugin
//当我们整个打包过程结束的时候,自动生成一个html文件,
//并把打包生成的自动引入到html这个文件中;
var HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const webpack = require('webpack')
module.exports = {
//打包模式,当为‘production’,打包后的文件会被压缩,
//当为‘development’时打包后的文件不会被压缩,按照开发环境进行打包
mode: 'development', //在开发者模式中SourceMap默认已经被配置在项目里了。
// devtool: 'none', //关闭SourceMap
//cheap:在生成SourceMap的时候,可以不带列信息,只带行信息,不要包含loader里面的SourceMap的生成,
//只对业务代码进行SourceMap的生成
//module:对loader里面的代码也进行一个SourceMap的生成
//eval:eval是一种执行方式
devtool: 'cheap-module-eval-source-map', //打开SourceMap
// devtool: 'cheap-module-source-map', //要线上的代码可以映射
// 打包的入口文件
entry: './src/index2.js',
// entry: {
// main: './src/index2.js'
// },
devServer: {
contentBase: './dist', //我们要在哪一个目录下去启动这个服务器
open: true, //会自动的打开一个浏览器,然后自动访问服务器的地址(localhost:8080)
hot: true, //指是否支持热更新(hmr)
hotOnly: true, //即使不支持hmr或者hmr有问题,也不刷新浏览器
proxy: {
'/api': {
//当访问localhost:8080/api的时,它会直接帮你转发到http://localhost:3000
target: 'http://localhost:3000',
pathRewrite: { '^/api': '' }
}
}
},
module: {
rules: [{
test: /.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /.(png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
//url-loader会把图片转化成一个base64的字符串,
//然后直接放到bundle.js里,而不是单独生成一个图片文件,
//好处:不用再额外的请求图片的地址,省了一次http请求;
//缺点:如果图片特别大过大,打包生成的js文件就会很大,
//那么加载js文件的时间就会很长,所以在一开始很长的时间里,页面上什么都显示不出来;
//所以,url-loader最佳的使用方式:加一个limit
//如果图片小于limit的值就把图片变为一个base64的字符串放到打包好的js中,
//若大于limit的值,就以file-loader的生成一个图片放到dist目录下。
limit: 8192, //好处是可以对小图片的http请求数减少,提升网页加载数度
name: 'images/[name].[hash].[ext]'
}
}
},
{
test: /.(css|scss|less)$/,
//"css-loader":会帮我们分析出几个css文件之间的关系,最终把这些css文件合并成一段css;
//"style-loader":会把‘css-loader’生成的内容挂在到页面的head部分
//在webpack的配置中,loader是有先后执行顺序的,
//loader的执行顺序是从下到上,从右到左;
//“sass-loader”会先对sass代码进行翻译,翻译为css代码后给到css-loader,
//都处理好了之后再交给‘style-loader’挂在到页面上
//postcss-loader会自动添加css3的厂商前缀;比如: transform: translate(100px, 100px)
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
modules: true //使得css模块化,
}
},
'postcss-loader',
'sass-loader'
]
},
{
// 可以打包字体文件
test: /.(eot|ttf|svg)$/,
use: {
loader: 'file-loader'
}
}
]
},
// 打包的出口文件
output: {
// 打包后的文件名
// filename: 'bundle.js',
filename: '[name].js', //name就是entry值的key:'main','sub'
// 打包后的文件目录为'dist'
path: path.resolve(__dirname, 'dist'),
publicPath: '/' //表示的是我所有的打包生成的文件之间的引用前面都加一个根路径
},
//plugin可以在webpack运行到某个时刻的时候,帮你做一些事情(类似生命周期函数)
plugins: [
// CleanWebpackPlugin可以在每次打包的时候帮我们对dist目录做一个清空
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
//HtmlWebpackPlugin帮我们自动的生成一个dist目录下的html文件
template: './src/index.html'
}),
//HotModuleReplacementPlugin帮我们实现HMR
new webpack.HotModuleReplacementPlugin()
],
//在开发模式下配置 tree shakeing
optimization: {
usedExports: true
}
}
在 package.json 中配置:
{
"name": "webpack-demo",
//@babel/polyfill和css文件不使用tree shaking
"sideEffects": [
"@babel/polyfill",
"*.css"
],
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"bundle": "webpack",
"watch": "webpack --watch",
"start": "webpack-dev-server",
"server": "node server.js"
},
"author": "susie",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.5.4",
"@babel/plugin-transform-runtime": "^7.5.0",
"@babel/preset-env": "^7.5.4",
"@babel/preset-react": "^7.0.0",
"autoprefixer": "^9.6.1",
"babel-loader": "^8.0.6",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.0.0",
"file-loader": "^4.0.0",
"html-webpack-plugin": "^3.2.0",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"url-loader": "^2.0.1",
"webpack": "^4.35.3",
"webpack-cli": "^3.3.5",
"webpack-dev-server": "^3.7.2"
},
"dependencies": {
"@babel/polyfill": "^7.4.4",
"@babel/runtime": "^7.5.4",
"@babel/runtime-corejs2": "^7.5.4",
"react": "^16.8.6",
"react-dom": "^16.8.6"
}
}
如果需要对某个模块不进行Tree Shaking
"sideEffects": ["@babel/poly-fill"], //该模块不进行Tree Shaking
为什么某些引入模块不希望进行Tree Shaking呢?
下面引入的style.css模块,如果也使用tree shaking,由于css文件没有导出任何模块,那么就有可能在打包的时候该引入模块就被摇晃掉了,导致bug。
在package.json中进行配置,即匹配到的任何css文件都不进行Tree Shaking
不使用Tree Shaking打包时,可以看到打包文件中exports provided: add, mins两种方法
- [C#6] 5-自动属性增强
- React多页面应用1
- jQuery操作Select
- MSDN杂志上的Windows Phone相关文章
- WCF Data Service工具包
- WordPress 文章截断方式:有more标签的优先more标签,否则截断一定字数
- 为什么要探索宇宙
- Redis的各项功能解决了哪些问题?
- WordPress.com 宣布支持Markdown 语言
- 使用Topshelf 5步创建Windows 服务
- TGM Plugin Activation:为WordPress 主题添加“插件推荐安装”功能
- [腾讯社区开放平台]介绍开放授权协议-OAuth
- HTML5规范的本地存储
- ASP.NET Web API 处理架构
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Flutter 1.17 新 Material motion 规范的预构建动画
- Canonical通过Flutter启用Linux桌面应用程序支持
- Flutter 快捷开发 Mac Android Studio 篇
- TRTC Android端开发接入学习之互动直播(七)
- Flutter 实现酷炫的3D效果
- 【Flutter 实战】一文学会20多个动画组件
- 【Flutter 实战】动画序列、共享动画、路由动画
- 【Flutter 实战】自定义动画-涟漪和雷达扫描
- Flutter —布局系统概述
- 【Flutter 实战】全局点击空白处隐藏键盘
- 我对Flutter的第一次失望
- 【Flutter 实战】各种各样形状的组件
- 『Flutter-绘制篇』实现炫酷的雨雪特效
- 图书管理系统(Servlet+Jsp+Java+Mysql,附下载演示地址)
- Vuex 映射完全指南