webpack相关

469 阅读2分钟

1. production模式打包优化

  • tree shaking**(默认)**

    通常用于打包时移出未引用的代码,它依赖于ES6模块系统中importexport静态结构特性

  • scope hoisting**(默认)**

    将模块之间的关系进行结果推测,可以让webpack打包出来的代码文件更小、运行的更快

    原理:分析出模块之间的依赖关系,尽可能的把打散的模块合并到一个函数中去,但前提是不能造成代码冗余

    由于scope hoisting需要分析模块之间的依赖关系,因此源码必须采用ES6模块化语句,不然无法生效

  • 代码压缩**(默认)**

    所有代码使用UglifyJsPlugin插件进行压缩、混淆

2. css优化

2.1 抽离CSS,单独打包为CSS文件

  • 安装

    npm i -D mini-css-extract-plugin

  • 相关webpack.config.js代码内容

    const MiniCssExtractPlguin = require("mini-css-extract-plugin");
    ...
    module: {
        rules: [
            {
                test:/\.css$/,
                use: [MiniCssExtractPlguin.loader, "css-loader"]
            }
        ]
    }
    plugins: [
        // 抽离单独的css文件, 只能在webapck4中用
        new MiniCssExtractPlguin({
          filename: "[name].css"
        })
    ]
    ...
    

2.2开启CSS压缩

需要使用optimize-css-assets-webpack-plugin插件来完成css压缩,但是由于配置css压缩会覆盖掉webpack默认的优化配置,导致JS代码无法压缩,所以还需要手动把JS代码压缩插件导入进来:terser-webpack-plugin

  • 安装

    npm i -D optimize-css-assets-webpack-plugin terser-webpack-plugin

  • 相关webpack.config.js内容

    const TerserWebpackPlugin = require("terser-webpack-plugin")
    const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin")
    
    ....
    optimization: {
      minimizer:[new TerserWebpackPlugin({}), new OptimizeCssAssetsWebpackPlugin()]
    }
    ....
    

2.3 自动添加CSS浏览器前缀

  • 安装

    npm i -D postcss-loader autoprefixer

  • 项目根目录新建一个postcss.config.js,内容为

    module.exports = {
      plugins: [require("autoprefixer")]
    };
    
  • 相关webpack.config.js内容

    ....
    module: {
      rules: [
        {
        	// 如果是less、scss、或者stylus也配置也是大同小异  
          test: /\.css$/,
          use: [MiniCssExtractPlguin.loader, "css-loader", "postcss-loader"]
        }
      ]
    }
    ....
    

3. js优化

Code Splitting是webpack打包时用到的重要优化特性之一,此特性能够把代码分割到不同的bundle中,然后可以按需加载或者并行加载这些文件。代码分离可以用于获取更小的bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。

有三种常用的代码分离方法:

  • 入口启点(entry points):使用entry配置手动分离代码
  • 防止重复(prevent duplication):使用SplitChunksPlugin去重和分离chunk
  • 动态导入(dynamic imports):通过模块的内联函数调用来分离代码

3.1 手动配置多入口

缺点:

  • 如果入口chunks之间包含重复的模块,这些重复模块都会被引入到各个bundle中
  • 这个方法不够灵活,并且不能将核心应用程序逻辑进行动态拆分代码

3.2 抽取公共代码

Webapck v4以上使用的插件SplitChunksPlugin, 以前使用的CommonsChunkPlugin已经被移除了,最新版的webpack只需要在配置文件中的optimization节点下添加一个splitChunks属性即可进行相关配置

  • 相关webpack.config.js内容

    optimization: {
      splitChunks: {
        chunks: "all"
      }
    }
    

3.3 动态导入(懒加载)

webpack4 默认是允许import语法动态导入的,但是需要babel的插件支持,最新版babel的插件包为:@babel/plugin-syntax-dynamic-import,以前老版本不是@babel开头,已经无法使用

动态导入最大的好处是实现了懒加载,用到哪个模块才会加载哪个模块,可以提高SPA应用程序的首屏加载速度,Vue、React、Angular框架的路由懒加载原理一样

  • 安装

    npm i -D @babel/plugin-syntax-dynamic-import

  • 修改.babelrc配置文件

    {
      "presets": ["@babel/env"],
      "plugins": [
        "@babel/plugin-proposal-class-properties",
        "@babel/plugin-transform-runtime",
        "@babel/plugin-syntax-dynamic-import"
      ]
    }
    
  • 将jquery模块进行动态导入

    function getComponent(){
      return import("jquery").then(({default: $}) => {
        return $("<div></div>").html("main")
      })
    }
    
    getComponent().then(item => {
      item.appendTo("body")
    })