最新示例

IIFE立即执行函数无法tree shaking

使用rollup打包文件时,iife立即执行函数无法实现tree shaking

什么是tree shaking

Tree shaking是前端界打包前端文件时自动移除不相干的代码片段,以文件体积最小化输出。webpackagerollup是常见的打包工具。因为本产品属于框架类,所以选择了rollup作为打包工具。

什么是IIFE

IIFE是Immediately Invoked Function Expression的简称,中文译名为“立即调用的函数表达式”,它的写法如下:


//一般用法
(function () {
  //块级作用域
})();      
//简写
()();

IIFE会形成一个块级作用域,与函数外部形成隔离,内部可以调用外部的变量,但是外部却不能调用内部。关于它的更多特性我们不做深究,我们主要来研究立即执行函数在打包中存在的问题。

打包

一般说来启用了tree shaking,可以将未引用的普通的变量和单纯的函数移除掉,但是我们在打包时发现IIFE函数是不能被移除。

我们准备以下简单的代码。


//入口文件
import { y } from "a.js"
console.log(y)
//导入的文件a.js,并使用忽略注释
const x = /*@__PURE__*/()();
const y = 100;
export {y}

在配置文件中配置忽略副作用。


//rollup.config.js配置
export default {
    treeshake: {
      moduleSideEffects: false, 
      propertyReadSideEffects: false,
      tryCatchDeoptimization: false,
    }
}
//package.json配置
{
  "sideEffects": false,
}
()();

也就是说我们三管齐下:

  1. 使用忽略注释/*@__PURE__*/
  2. npm环境忽略副作用"sideEffects": false
  3. rollup环境忽略副作用treeshake.moduleSideEffects: false

都无济于事,立即执行函数依然会保留在打包文件里面,并没有实现tree shaking。

不单单是IIFE,还发现不能treeshaking的情况有许多:

  • mixin多态继承
  • 函数作为参数传入的高阶函数
  • class类的static静态成员中使用filter、map等高阶函数
  • 对象的属性中使用了复杂函数或者未知的值

为了实现tree shaking,不得不放弃某些巧妙的写法,老老实实使用纯函数和简单的继承。