美文网首页
Tree-Shaking 和ES6 module

Tree-Shaking 和ES6 module

作者: 梦想成真213 | 来源:发表于2019-06-26 15:17 被阅读0次

    ES6 module 静态结构

    当前的JavaScript模块格式具有动态结构:导入和导出的内容可以在运行时(runtime)更改。 ES6引入自己的模块格式的一个原因是启用静态结构静态结构意味着您可以在编译时确定导入和导出(静态) --- 您只需要查看源代码,而不必执行它。 ES6在语法上强制执行:您只能在顶层导入和导出(而不嵌套在条件语句中), 并且导入和导出语句没有动态部分(不允许使用变量等)。

    对比没有静态结构的CommonJS模块

    如下代码,只有运行代码的时候才能知道导入的内容;

    var my_lib;
    if (Math.random()) {
        my_lib = require('foo');
    } else {
        my_lib = require('bar');
    }
    

    同样,也只有在运行代码的时候才能知道导出的内容

    if (Math.random()) {
        exports.baz = function baz(){};
    }
    

    ES6 模块 export import

    export function add(){
    }
    
    import react from 'react'
    

    ES6模块的灵活性较差,迫使我们保持静态,因此有如下好处:

    • 在捆绑期间消除死代码,优化打包之后的代码体积(Tree-Shaking)
    • 紧凑捆绑,没有自定义捆绑格式
    • 更快查找到入口 (commonjs必须执行才能查找,很慢,因为是动态的)
    • 效益:变量检查(静态的知道哪些变量在模块内的哪些位置可见)
    • 为类型做好准备(静态类型检查加强)

    什么是Tree-Shaking?

    Tree-Shaking是一个术语,通常用于描述移除Javascript上下文中的未引用的代码(dead-code)。它依赖于ES6 module语法的静态结构特性,如 import 和 export ,用来检测代码模块是否被导出、导入,且被Javascript文件使用。使用模块打包(webpack,rollup)将多个Javascript文件打包为单文件时自动删除未引用的代码。对于发布线上代码起到优化作用。这个术语和概念实际是由ES2015模块打包工具rollup普及起来的。

    tree-shaking更关注于无用模块的消除,消除那些引用了但并没有被使用的模块。DCE 消灭不可能执行的代码。

    webpack 2正式版内置支持ES6模块和未使用模块检测能力。新的webpack 4正式版本扩展了此检测能力,通过 package.json"sideEffects"属性作为标记,向compiler提供提示,表明项目中的哪些文件是" pure(纯 ES2015 模块) ",由此可以安全的删除文件中未使用的部分。

    使用Tree-Shaking 压缩代码(webpack 4)

    webapck.config.js

    const path = require('path')
    module.exports = {
      mode: 'production',
      entry: './src/index.js',
      output: {
        filename: 'budle.js',
        path: path.resolve(__dirname, 'dist')
      },
      optimization: {
        usedExports: true
      }
    }
    

    将文件标记为 side-effect-free(无副作用):提示 webpack compiler 哪些代码是“纯粹部分”,通过 package.json"sideEffects"属性,来实现这种方式

    {
      "name": "webpack-4-demo",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "webpack-dev-server --open --config webpack.dev.js",
        "build": "webpack --config webpack.prod.js"
      },
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "clean-webpack-plugin": "^3.0.0",
        "html-webpack-plugin": "^3.2.0",
        "webpack": "^4.35.0",
        "webpack-cli": "^3.3.5",
        "webpack-dev-server": "^3.7.2",
        "webpack-merge": "^4.2.1"
      },
      "sideEffects": false
    }
    

    结论

    想要使用tree shaking 必须注意如下几点:

    • 使用es6 模块语法(import 和 export)
    • 确保没有compiler将ES6模块语法转换为CommonJS模块(Babel preset 中 @babel/preset-env 的默认值是auto,将module 设置为false将不会转换模块)
    • 在项目 package.json 文件中,添加一个"sideEffects"属性
    • 通过将 mode 选项设置为 production,启用 minification(代码压缩)tree shaking

    你可以将应用程序想象成一棵树,绿色表示实际用到的 source code(源码) 和 library(库),是树上活的树叶。灰色表示未引用代码,是秋天树上枯萎的树叶。为了除去死去的树叶,你必须摇动这棵树,使它们落下。

    使用方法可以查下一篇文章:webpack 4 中 tree shaking 生产环境配置

    参考:
    https://exploringjs.com/es6/ch_modules.html#static-module-structure
    https://developer.mozilla.org/zh-CN/docs/Glossary/Tree_shaking
    https://webpack.docschina.org/guides/tree-shaking/#src/components/Sidebar/Sidebar.jsx
    https://juejin.im/post/5a4dc842518825698e7279a9

    相关文章

      网友评论

          本文标题:Tree-Shaking 和ES6 module

          本文链接:https://www.haomeiwen.com/subject/sjhccctx.html