webpack简单配置及其用法二

妖狐艹你老母 2022-12-31 01:14 284阅读 0赞

一、编写可维护的webpack构建配置

栗子:构建配置包设计

构建配置抽离成npm包的意义

通过性:业务开发者无需关注构建配置;统一团队构建脚本

可维护性:构建配置合理的拆分;reademe,changelog文档

质量:冒烟测试,单元测试,测试覆盖率;持续继承

构建配置管理的可选方案

1)通过多个配置文件管理不同环境的构建,webpack —config参数进行控制使用的配置文件,如

基础配置:webpack.base.js;开发环境:webpack.dev.js;生产环境:webpack.prod.js;ssr环境:webpack.ssr.js

2)将构建配置设计成一个库,比如hjs-webpack Neutrino webpack-blocks

规范:git commit日志,README,ESLINT规范,Semver规范

质量:冒烟测试,单元测试,测试覆盖率和CI

3)抽成一个工具进行管理,比如:create-react-app kyt nwb

4)将所有的配置写在一个文件,通过—env参数控制分支选择、

1)2)适合小团队使用,大团队可选择3)方式

通过webpack-merge组合配置

  1. const merge = require("webpack-merge)
  2. merge(
  3. {a:[1], b:5, c:20},
  4. {a:[2], b:6, d:35}
  5. )
  6. >{a:[1,2],b:6,c:20,d:35} // 非对象或非数组,则有相同的变量名,后面的覆盖前面的
  7. 合并配置:module.exports=merge(baseConfig,devConfig)

二、webpack构建速度和体积优化策略

体积优化方法:

1)scope hoisting

2)tree-shaking

3)公共资源分离

4)图片压缩

5)动态polyfill

提升构建速度方法:

1)充分使用缓存,提升二次构建速度

2)进一步分包:预编译资源模块

栗子:构建速度和速度分析

1)使用webpack内置的stats:构建的统计信息

2)速度分析:用speed-measure-webpack-plugin,分析整个打包的耗时,每个插件和loader的耗时

安装插件

  1. npm install -D speed-measure-webpack-plugin

创建对象

  1. const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
  2. const smp = new SpeedMeasurePlugin();

将之前module.exports的内容,包裹在smp.wrap()里面

  1. smp.wrap(...)

3)体积分析:用webpack-bundle-analyzer

可以分析依赖的第三方模块文件大小,业务里面的组件代码大小

安装依赖

  1. npm install -D webpack-bundle-analyzer

配置

  1. const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
  2. module.exports = {
  3. plugins: [
  4. new BundleAnalyzerPlugin()
  5. ]
  6. }

栗子:使用高版本的webpack和node

栗子:充分利用缓存,提升二次构建速度——首次构建速度不会变化,下次构建的速度才会有变化

缓存思路:

1)babel-loader开启缓存,解析js语法或者jsx语法,等下次在解析一样的语法的时候,就可以读取缓存的内容,提升解析的速度

2)terser-webpack-plugin 开启缓存,代码压缩的时候,提升压缩速度

3)cache-loader或者hard-source-webpack-plugin,提升模块转换阶段的速度

如果在代码层面开启了缓存,那在node_modules下有.cache目录,比如开启了babel-loader,则会生成文件夹babel-loader(node_modules/.cache/babel-loader/….),文件夹里面包含了解析出的js文件

注意:如果开启了缓存,有可能会影响到包的更新,比如在项目中安装了包a@1.0.0,后面更新成a@1.0.1,但是发现这个包的代码还是上个版本的

解决方法:就是在更新包之前要将.cache文件夹整个移除,在更新包

以hard-source-webpack-plugin为栗子:

1)安装hard-source-webpack-plugin插件

  1. npm install -D hard-source-webpack-plugin

2)在配置文件中,引进该插件,并进行配置

  1. const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
  2. plugin: [
  3. new HardSourceWebpackPlugin()
  4. ]

栗子:缩小构建目标

目的:尽可能的少构建模块,

比如:babel-loader不解析node_modules

  1. module.exports = {
  2. module: {
  3. rules: [
  4. {
  5. test: /\.js$/,
  6. loader: ''babel-loader,
  7. exclude: 'node_modules
  8. }
  9. ]
  10. }
  11. }

比如:减少文件搜索范围:

webpack同node查找文件的方法很相似,指定要查找的路径或者文件类型,缩小查找时间

优化resolve.modules配置(减少模块搜索层级)

优化resolve.mainFields配置

优化resolve.extensions配置

合理使用alias

  1. resolve: {
  2. alias: {
  3. react: path.resolve(__dirname, ./node_modules/react/dist/react.min.js') // 直接给定取别名的路径
  4. },
  5. modules: [path.resolve(__dirname, 'node_modules')], // 安装第三方包是在node_modules目录下,那么在引进第三方包的时候直接到node_module目录下查找
  6. extensions: ['.js'], // 指定查找文件的类型
  7. mainFields: ['main'] // 发布到npm上的包会指定入口路径,即main字段的值,即查找文件只在该路径下查找
  8. }

栗子:tree shaking(摇树优化)

概念:1个模块可能有多个方法,只要其中某个方法使用到,则整个文件就会被打包到bundle,而tree shaking只是把用到的方法打包到bundle里面,没用到的方法会在uglify阶段擦除掉

使用:webpack默认支持,在.babelrc设置modules:false即可,注意:mode:production情况下默认开启

要求:必须是ES6语法,cjs方式不支持

无用的css如何删除?

PurifyCSS:遍历代码,识别已经用到的的css class

uncss:HTML需要通过jsdom加载,所有的样式通过PostCSS解析,通过document.querySelector来识别在html文件里面不存在的选择器

在webpack中如何使用PurifyCSS

使用purgecss-webpack-plugin和min-css-extract-plugin配合使用

1)安装插件purgecss-webpack-plugin

  1. npm i purgecss-webpack-plugin -D

2)在项目中把插件引进来

下面写法是单文件入口写法,参考地址:https://www.npmjs.com/package/purgecss-webpack-plugin

  1. const PurgeCSSPlugin = require('purgecss-webpack-plugin')
  2. const PATHS = {
  3. src: path.join(__dirname, 'src')
  4. }
  5. plugins: [
  6. new PurgeCSSPlugin({
  7. paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }),
  8. })
  9. ]

栗子:图片压缩

要求:基于Node库的imagemin或者tinypng API

使用:配置image-webpack-loader

使用参考文档:https://www.npmjs.com/package/image-webpack-loader

1)安装插件

  1. npm install image-webpack-loader -D

2)在配置文件中设置

  1. module.exports.module.rules = [{
  2. test: /\.(png|jpg|jpeg|gif|svg)$/,
  3. use: [
  4. {
  5. loader: 'file-loader',
  6. options: {
  7. name: 'img_[name][hash:8].[ext]'
  8. }
  9. },
  10. {
  11. loader: 'image-webpack-loader',
  12. options: {
  13. mozjpeg: {
  14. progressive: true,
  15. },
  16. // optipng.enabled: false will disable optipng
  17. optipng: {
  18. enabled: false,
  19. },
  20. pngquant: {
  21. quality: [0.65, 0.90],
  22. speed: 4
  23. },
  24. gifsicle: {
  25. interlaced: false,
  26. },
  27. // the webp option will enable WEBP
  28. webp: {
  29. quality: 75
  30. }
  31. }
  32. }
  33. ]
  34. }]

栗子:构建体积优化,动态polyfill

使用polyfill-service:只给用户返回需要的polyfill,ua识别,下发不同的polyfill

三、通过源代码,掌握webpack打包原理

栗子:webpack启动过程分析

项目启动的时候发生了什么?

一般启动项目,我们都会砸控制台输入npm run dev等语句,然后项目就启动,或者在控制台输入webpack entry.js bundle.js也能直接运行————这个过程发生什么???

当执行上面语句的时候,npm会让命令行工具进入node_modules/.bin目录查找是否存在webpack.sh webpack.cmd文件,存在就执行,否则抛错;实际的入口文件路径:node_modules/webpack/bin/webpack.js(这里定义了命令,但是是webpack包还是webpack-cli包那个提供的命令?

全局安装的包,会从userLocal/.bin下查找,但是webpack我们一般是局部安装,即安装到具体项目里面,所以会从项目的根目录下的node_modules/.bin去查找文件

局部安装包的时候,想再.bin目录下有这个命令,就必须在package.json的bin字段进行指定

看下node_modules/.bin/webpack文件里面定义了什么

  1. process.exitCode = 0 // 正常执行返回
  2. const runCommand = (command, args) => {} // 运行某个命令
  3. const isInstalled = packageName => {} // 判断某个包是否安装了
  4. const CLIs = [....] // webpack可以用的cli:webpack-cli webpack-command
  5. const isntalledClis = CLIs.filter(cli => cli.installed) // 判断安装了那些cli
  6. if (isntalledClis.length === 0) {// 根据安装数量进行处理
  7. } else if (isntalledClis.length === 1) {
  8. } else {
  9. }

启动后的结果:

webpack最终找到webpack-cli(webpack-command)这个npm包,并且执行cli

栗子:webpack-cli源码阅读

发表评论

表情:
评论列表 (有 0 条评论,284人围观)

还没有评论,来说两句吧...

相关阅读

    相关 webpack配置

    1.新建文件夹 webpack-demo vscode 打开文件 -》打开控制台(只要进入文件目录中) 2.初始化webpack webpack init -