前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >webpack中tree-shaking技术介绍

webpack中tree-shaking技术介绍

作者头像
用户1217459
发布于 2018-01-31 06:50:56
发布于 2018-01-31 06:50:56
97700
代码可运行
举报
文章被收录于专栏:Young DreamerYoung Dreamer
运行总次数:0
代码可运行

之前介绍过webpack3的新特性,里面提到webpack2支持了ES6的import和export,不需要将ES6的模块先转成CommonJS模块,然后再进行打包处理。正基于此,webpack2引入了tree-shaking技术,能够在模块的层面上做到打包后的代码只包含被引用并被执行的模块,而不被引用或不被执行的模块被删除掉,以起到减包的效果。

webpack的tree-shaking案例

下面结合实际代码来解释webpack2是如何实现tree-shaking的,示例代码可到github进行下载

示例代码结构如图:src中index.js为入口文件,module.js是测试的模块文件,dist中是产出的文件。

根据webpack官网的提示,webpack支持tree-shaking,需要修改配置文件,指定babel处理js文件时不要将ES6模块转成CommonJS模块,具体做法就是:

在.babelrc设置babel-preset-es2015的modules为fasle,表示不对ES6模块进行处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// .babelrc文件
{
  "presets": [
    ["es2015", { "modules": false }] 
  ],
  "comments": false
}

在webpack.config.js中设置babel-preset-es2015的modules为fasle,表示不对ES6模块进行处理。  

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// webpack.config.js
...
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    presets: [
                        ["es2015", { "modules": false }]
                    ]
                }
            }
        ]
...  

然后在module.js文件中创建三个模块sayHello,sayBye,sayHi,并在index.js引用sayHello,sayHi;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// module.js
export const sayHello = name => `Hello ${name}!`;
export const sayBye = name => `Bye ${name}!`;
export const sayHi = name => `Hi ${name}!`;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// index.js
import { sayHello } from './module';
import { sayHi } from './module';
const element = document.createElement('h1');
element.innerHTML = sayHello('World') + sayHi('my friend');
document.body.appendChild(element);

然后在当前目录执行 webpack 命令后,产出bundle.js的代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return sayHello; });
/* unused harmony export sayBye */
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return sayHi; });


var sayHello = function sayHello(name) {
  return "Hello " + name + "!";
};
var sayBye = function sayBye(name) {
  return "Bye " + name + "!";
};

var sayHi = function sayHi(name) {
  return "Hi " + name + "!";
};

/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__module__ = __webpack_require__(0);



var element = document.createElement('h1');
element.innerHTML = Object(__WEBPACK_IMPORTED_MODULE_0__module__["a" /* sayHello */])('World') + Object(__WEBPACK_IMPORTED_MODULE_0__module__["b" /* sayHi */])(' to meet you');
document.body.appendChild(element);

/***/ })

从上面可以知道,sayBye模块被打上了unused harmony export标签,sayHello和sayHi被设置为__webpack_exports__的属性,在入口文件中通过读取__webpack_exports__的属性取出。

bundle.js文件虽然对多余的模块进行了标记,但是并没有删除,这是因为webpack还没有执行压缩混淆操作,可以通过webpack -p命令对产出进行压缩处理,这时候会把打了unused harmony export 标签的模块删除掉。

webpack的tree-shaking的局限性

(1)只能是静态声明和引用的ES6模块,不能是动态引入和声明的;

在打包阶段对冗余代码进行删除,就需要webpack需要在打包阶段确定模块文件的内部结构,而ES模块的引用和输出必须出现在文件结构的第一级('import' and 'export' may only appear at the top level),否则会报错。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// webpack编译时会报错
if (condition) {
  import module1 from './module1';
} else {
  import module2 from './module2';
}

而CommonJS模块支持动态结构的,所以不能对CommonJS模块进行tree-shaking处理。

(2)只能处理模块级别,不能处理函数级别的冗余;

 因为webpack的tree-shaking是基于模块间的依赖关系,所以并不能对模块内部自身的无用代码进行删除。

(3)只能处理JS相关冗余代码,不能处理CSS冗余代码。

目前webpack只对JS文件的依赖进行了处理,CSS的冗余并没有给出很好的工具。最近听了一个讲座,提到了webpack-css-treeshaking-plugin,该插件基于AST对CSS冗余代码进行了很好的处理。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-11-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
前端-Webpack 之 treeShaking
在 github 上直接观看 markdown 会把图片转存到缓存中,github 转存后的图片清晰度很有问题,因此如果图片看不清,可以移步知乎上的相同文章
grain先森
2019/03/29
6410
前端-Webpack 之 treeShaking
Rollup 与 Webpack 的 Tree-shaking
Rollup 和 Webpack 是目前项目中使用较为广泛的两种打包工具,去年发布的 Vite 中打包所依赖的也是 Rollup;在对界面加载效率要求越来越高的今天,打包工具最终产出的包体积也影响着开发人员对工具的选择,所以对 Tree-shaking 的支持程度和配置的便捷性、有效性就尤为重要了。本文就来简单分析下两者 Tree-shaking 的流程和效果差异。
政采云前端团队
2022/12/01
1.4K0
Rollup 与 Webpack 的 Tree-shaking
Webpack 4教程 - 第七部分 减少打包体积与Tree Shaking
在本次Webpack 4教程中,我们会更进一步讲述项目优化。我们会学习什么是tree shaking以及如何使用它。你会找到让Webpack 4中tree shaking运作起来所需要的东西,并知道怎样从中受益。开始吧!
葡萄城控件
2019/05/25
9450
聊一聊面试中经常被问到的Tree Shaking
天下武功,唯快不破!最新版的 antd 以及 vue 都对 Tree Shaking 提供了支持。我们内部的组件在支持这部分功能时,也专门梳理了相关的特性。这是四月份写的文章了,长时间不用就会忘,复习一下!
前端迷
2020/08/28
2.1K0
聊一聊面试中经常被问到的Tree Shaking
webpack原理(2):ES6 module在Webpack中如何Tree-shaking构建
DCE 作用于模块内(webpack 的 DCE 通过 UglifyJS 完成),而 Tree-shaking 则是在打包的时候通过模块之间的信息打包必须的代码。
周陆军博客
2023/03/18
8020
Tree Shaking
Javascript 绝大多数情况需要通过网络进行加载再执行,加载的文件越小,整体执行时间更短,所以就有了 Tree Shaking 去除无用代码,从而减小文件体积。
政采云前端团队
2022/12/01
7260
Tree Shaking
webpack2 的 tree-shaking 好用吗?
IMWeb前端团队
2018/01/08
1.5K0
webpack2 的 tree-shaking 好用吗?
Webpack 实现 Tree shaking 的前世今生
如果看过 rollup 系列的这篇文章 - 无用代码去哪了?项目减重之 rollup 的 Tree-shaking,那你一定对 tree-shaking 不陌生了。如果对 tree-shaking 相关知识不熟悉,请先点开上面这篇文章花 5 分钟了解一下:什么是 tree-shaking。
zz_jesse
2021/07/12
1.2K0
Webpack 实现 Tree shaking 的前世今生
前端模块化杂记 前言AMD/CMD简介Commonjs简介Module简介Common和Module的区别Module与webpackModule与Babel一些问题总结引用
前端模块化在近几年层出不穷,有Node的CommonJs,也有属于client端的CMD/AMD模式,而ES6本身也出现了Modules,再加上Webpack以及babel的普及,虽然在代码中经常使用到这些用法,但是如果不去深入研究,总觉得是一个黑魔法,无法探测一些问题的根源。
菜的黑人牙膏
2019/01/28
8890
Webpack 的 Tree Shaking 概念详解
webpack 2.0 开始引入 tree shaking 技术,翻译过来的中文意思就是摇树,它可以在打包时忽略没有用到的代码。
张张
2019/12/31
1.3K0
Webpack 的 Tree Shaking 概念详解
Rspack 作者揭秘,你的 Tree Shaking 真的起作用了吗?
本文主要探讨了 Webpack Tree Shaking 的基本概念,而非深入其底层代码实现。相关的代码示例可以在 这里[1] 查看。
童欧巴
2024/05/09
3510
Rspack 作者揭秘,你的 Tree Shaking 真的起作用了吗?
手把手教你撸一个简易的 webpack
随着前端复杂度的不断提升,诞生出很多打包工具,比如最先的grunt,gulp。到后来的webpack和Parcel。但是目前很多脚手架工具,比如vue-cli已经帮我们集成了一些构建工具的使用。有的时候我们可能并不知道其内部的实现原理。其实了解这些工具的工作方式可以帮助我们更好理解和使用这些工具,也方便我们在项目开发中应用。
muwoo
2018/06/11
1.2K1
手把手教你撸一个简易的 webpack
webpack模块化原理-ES module
上一篇文章介绍了webpack对commonjs模块的支持(如果你还没读过,建议你先阅读),这篇文章来探究一下,webpack是如何支持es模块的。
Keller
2021/12/14
1.4K0
构建打包工具Rollup.js入门指南
最近在看Vue源码的时候发现一个新的打包工具Rollup.js,之前没有听说过这个工具,也不了解Rollup.js相比于常用的打包工具webpack有什么异同和优势,随后查了一下了解到Vue,React,D3,Three.js,Moment源码里都有它的身影,Rollup到底什么?这篇文章带你走进Rollup的世界。
用户1462769
2019/08/12
2.6K0
构建打包工具Rollup.js入门指南
关于Rollup那些事
下一代打包工具,这是rollup对自己的定位。如今的前端领域,构建工具并不缺少,每个前端工程师都用过或者听过webpack。可以看到的是像React、Vue等框架的构建工具使用的都是rollup。既然如此,这些框架为什么会选择rollup?它的特性是什么?面对不同场景,我们要怎么选择构建工具?本文将一一为你呈现。
腾讯IVWEB团队
2020/06/24
6920
深入了解 webpack 模块加载原理
无论你开发使用的是 CommonJS 规范还是 ES6 模块规范,打包后的文件都统一使用 webpack 自定义的模块规范来管理、加载模块。本文将从一个简单的示例开始,来讲解 webpack 模块加载原理。
谭光志
2020/09/28
1.4K0
揭秘webpack5模块打包
​在上一节中我们初步了解了webpack可以利用内置静态模块类型(asset module type)来处理资源文件,我们所知道的本地服务,资源的压缩,代码分割,在webpack构建的工程中有一个比较显著的特征是,模块化,要么commonjs要么esModule,在开发环境我们都是基于这两种,那么通过webpack打包后,如何让其支持浏览器能正常的加载两种不同的模式呢?
Maic
2022/07/28
9450
揭秘webpack5模块打包
【模块化】:Webpack 是如何将不同规范(ESM、CJS、UMD、AMD、CMD)的模块化代码打包到一起并协调它们运行的?
在一个项目中同时使用 ES6、CJS、CMD、AMD、UMD 5种不同的模块化规范编写代码,并同时应用静态导入、动态导入(Dynamic Import)方法来引用这些模块。观察 Webpack 是如何将这些不同模块化规范的代码打包到一起和协调它们运行的。
WEBJ2EE
2022/03/30
7.1K2
【模块化】:Webpack 是如何将不同规范(ESM、CJS、UMD、AMD、CMD)的模块化代码打包到一起并协调它们运行的?
从webpack4打包文件说起
一堆的webpack配置教程看腻了?这里有webpack4的打包及加载机制,要不了解一下?而这一切就得从打包文件说起。
elson
2018/08/01
2.9K1
webpack模块化的原理
在webpack中既可以书写commonjs模块也可以书写es模块,而且不用考虑浏览器的兼容性问题,我们来分析一下原理。
gogo2027
2022/10/31
5080
相关推荐
前端-Webpack 之 treeShaking
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验