乐趣区

关于webpack:Webpack构建速度优化

前言

当咱们的我的项目越来越大,webpack 的配置项越来越多时,构建速度会越来越慢,所以咱们须要通过一些配置来进步 webpack 的构建速度。

目录

  • 放大范畴
  • noParse
  • IgnorePlugin
  • 优化 resolve 配置
  • externals
  • 缓存

放大范畴

在配置 loader 的时候,咱们须要更准确的去指定 loader 的作用目录或者须要排除的目录,通过应用 includeexclude 两个配置项,能够实现这个性能,常见的例如:

  • include:符合条件的模块进行解析
  • exclude:排除符合条件的模块,不解析,优先级更高

这样一来,一开始构建,咱们就能去除一些选项,比方,在应用 babel-loader 的时候

{
  test: /\.jsx?$/,
  use: [
    {
      loader: 'babel-loader',
      options: {presets: ['@babel/preset-env', '@babel/react'],
        plugins: [[require('@babel/plugin-proposal-decorators'), {legacy: true}]],
        cacheDirectory: true, // 启用缓存
      },
    },
  ],
  include: path.resolve(__dirname, 'src'),
  exclude: /node_modules/,
 },

noParse

对于咱们引入的一些第三方包,比方jQuery,在这些包外部是必定不会依赖别的包,所以基本不须要 webpack 去解析它外部的依赖关系,应用 noParse 进行疏忽的模块文件中不会解析 importrequire 等语法

module:{noParse:/jquery|lodash/}

IgnorePlugin

有很多的第三方包外部会做国际化解决,蕴含很多的语言包,而这些语言包对咱们来说时没有多大用处的,只会增大包的体积,咱们齐全能够疏忽掉这些语言包,从而进步构建效率,减小包的体积。

用法

  • requestRegExp 示意要疏忽的门路。
  • contextRegExp 示意要疏忽的文件夹目录。
new webpack.IgnorePlugin({resourceRegExp, contextRegExp});

以 moment 为例,首先找到 moment 中语言包所在的文件夹,而后在 webpack 配置文件中增加插件

new webpack.IgnorePlugin(/./locale/, /moment/)

也能够写成

new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),

这时候 moment 应用默认语言英语,如果要应用别的语言,能够手动引入须要应用的语言包。

import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-CN')

优化 resolve 配置

alias

alias 用的创立 importrequire 的别名,用来简化模块援用,我的项目中根本都须要进行配置。

const path = require('path')
{
  ...
  resolve:{
    // 配置别名
    alias: {'~': resolve('src'),
      '@': resolve('src'),
      'components': resolve('src/components'),
    }
  }
}

配置实现之后,咱们在我的项目中就能够

// 应用 src 别名 ~ 
import '~/fonts/iconfont.css'

// 应用 src 别名 @ 
import '@/fonts/iconfont.css'

除此之外,因为一些第三方库,如 react,咱们在装置的时候,实际上曾经装置好了它编译好的包,所以咱们在这里能够间接指定别名门路

alias: {
react: path.resolve(
          dirname,
          '../node_modules/react/umd/react.production.min.js'
       ),
}

配合上 noParse,在应用的时候,就毋庸在构建一遍 react

noParse: /react\.production\.min\.js$/,

extensions

在 webpack 中,咱们能够事后设定一些文件的扩展名

webpack 默认配置

const config = {
  //...
  resolve: {extensions: ['.js', '.json', '.wasm'],
  },
};

如果在编写的时候不带文件后缀,如

import file from '../path/to/file';

webpack 在解析的时候,就能够从咱们设置的扩展名中从左往右进行判断

须要留神的是:

  • 高频文件后缀名放后面;
  • 手动配置后,默认配置会被笼罩
  • 参考 webpack 视频解说:进入学习

如果想保留默认配置,能够用 ... 扩大运算符代表默认配置,例如

const config = {
  //...
  resolve: {extensions: ['.ts', '...'], 
  },
};

modules

通知 webpack 解析模块时应该搜寻的目录,常见配置如下

const path = require('path');

// 门路解决办法
function resolve(dir){return path.join(__dirname, dir);
}

const config = {
  //...
  resolve: {modules: [resolve('src'), 'node_modules'],
  },
};

通知 webpack 优先 src 目录下查找须要解析的文件,会大大节俭查找时间

externals

externals 配置选项提供了「从输入的 bundle 中排除依赖」的办法,因为咱们在每次打包的时候,有些依赖的变动很小,所以咱们能够不抉择不把依赖打包进去,而应用 script 标签的模式来加载他。

比方 react 和 react-dom,咱们在页面中引入它

<script src="https://unpkg.com/[email protected]/umd/react.development.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js" crossorigin="anonymous"></script>

而后配置 externals

externals: {
     react: 'React',
     'react-dom': 'ReactDOM',
},

留神 这里配置项的键值是 package.json 文件中依赖库的名称,而 value 值代表的是 第三方依赖编译打包后生成的 js 文件,而后 js 文件执行后赋值给 window 的全局变量名称

咱们能够通过上面的办法,来找这个全局变量

下面所说的 js 文件就是要用 CDN 引入的 js 文件。那么能够通过浏览器关上 CDN 链接,抉择没有压缩过的那种(不带 min),比方

https://cdn.bootcdn.net/ajax/libs/react/18.2.0/cjs/react-jsx-dev-runtime.development.js

而后在它的源代码外面找,相似与导出赋值这种代码

缓存

webpack5 提供了十分弱小的长久化缓存的能力,开箱即用

catch 缓存

webpack5 新加了缓存项配置,具体如下

默认缓存门路在node_modules/.cache/webpack

// 缓存配置 
    cache: {
      type: 'filesystem',  // 开启长久化缓存
      version: createEnvironmentHash(env.raw),  // 参考 react 脚手架的配置 能够记录打包缓存的版本
      cacheDirectory: path.appWebpackCache, // 缓存门路
      store: 'pack',
      // 构建依赖,如果有文件批改,则从新执行打包流程
      buildDependencies: {defaultWebpack: ['webpack/lib/'],
        config: [__filename],
      },
    },
babel-loader 开启缓存

abel 在转译 js 过程中工夫开销比价大,将 babel-loader 的执行后果缓存起来,从新打包的时候,间接读取缓存

缓存地位:node_modules/.cache/babel-loader

配置

// 反对本义 ES6/ES7/JSX
{
  test: /\.jsx?$/,
  use: [
    {
      loader: 'babel-loader',
      options: {presets: ['@babel/preset-env', '@babel/react'],
        plugins: [
          [require('@babel/plugin-proposal-decorators'),
            {legacy: true},
          ],
        ],
        cacheDirectory: true, // 启用缓存
      },
    },
  ],
  include: path.resolve(__dirname, 'src'),
  exclude: /node_modules/,
},
cache-loader

缓存一些性能开销比拟大的 loader 的处理结果,缓存地位:node_modules/.cache/cache-loader

配置 cache-loader

const config = {
 module: { 
    // ...
    rules: [
      {test: /.(s[ac]|c)ss$/i, // 匹配所有的 sass/scss/css 文件
        use: [
          // 'style-loader',
          MiniCssExtractPlugin.loader,
          'cache-loader', // 获取后面 loader 转换的后果
          'css-loader',
          'postcss-loader',
          'sass-loader', 
        ]
      }, 
      // ...
    ]
  }
}

dll 动静链接(已弃用)

在 webpack5.x 中曾经不倡议应用这种形式进行模块缓存,因为其曾经内置了更好体验的 cache 办法

hard-source-webpack-plugin

hard-source-webpack-plugin 为模块提供了两头缓存,反复构建工夫大概能够缩小 80%,然而在 webpack5 中曾经内置了模块缓存,不须要再应用此插件

退出移动版