博客
关于我
webpack简单配置及其用法二
阅读量:395 次
发布时间:2019-03-05

本文共 5962 字,大约阅读时间需要 19 分钟。

一、编写可维护的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组合配置

const merge = require("webpack-merge)merge(    {a:[1], b:5, c:20},    {a:[2], b:6, d:35})>{a:[1,2],b:6,c:20,d:35} // 非对象或非数组,则有相同的变量名,后面的覆盖前面的合并配置: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的耗时

安装插件

npm install -D speed-measure-webpack-plugin

创建对象

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

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

smp.wrap(...)

 

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

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

安装依赖

npm install -D webpack-bundle-analyzer

配置

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = {  plugins: [    new BundleAnalyzerPlugin()  ]}

 

栗子:使用高版本的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插件

npm install -D hard-source-webpack-plugin

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

const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')plugin: [  new HardSourceWebpackPlugin()]

栗子:缩小构建目标

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

比如:babel-loader不解析node_modules

module.exports = {    module: {        rules: [            {                test: /\.js$/,                loader: ''babel-loader,                exclude: 'node_modules            }        ]    }}

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

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

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

优化resolve.mainFields配置

优化resolve.extensions配置

合理使用alias

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

 

栗子: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

npm i purgecss-webpack-plugin -D

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

下面写法是单文件入口写法,参考地址:

const PurgeCSSPlugin = require('purgecss-webpack-plugin')const PATHS = {  src: path.join(__dirname, 'src')} plugins: [    new PurgeCSSPlugin({      paths: glob.sync(`${PATHS.src}/**/*`,  { nodir: true }),    }) ]

栗子:图片压缩

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

使用:配置image-webpack-loader

使用参考文档:

1)安装插件

npm install image-webpack-loader -D

2)在配置文件中设置

module.exports.module.rules = [{                test: /\.(png|jpg|jpeg|gif|svg)$/,                use: [                    {                        loader: 'file-loader',                        options: {                            name: 'img_[name][hash:8].[ext]'                        }                    },                    {                        loader: 'image-webpack-loader',                        options: {                          mozjpeg: {                            progressive: true,                          },                          // optipng.enabled: false will disable optipng                          optipng: {                            enabled: false,                          },                          pngquant: {                            quality: [0.65, 0.90],                            speed: 4                          },                          gifsicle: {                            interlaced: false,                          },                          // the webp option will enable WEBP                          webp: {                            quality: 75                          }                        }                    }                ]            }]

栗子:构建体积优化,动态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文件里面定义了什么

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

启动后的结果:

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

 

栗子:webpack-cli源码阅读

 

 

 

 

 

 

 

 

 

转载地址:http://ohzzz.baihongyu.com/

你可能感兴趣的文章
Mysql 纵表转换为横表
查看>>
mysql 编译安装 window篇
查看>>
mysql 网络目录_联机目录数据库
查看>>
MySQL 聚簇索引&&二级索引&&辅助索引
查看>>
Mysql 脏页 脏读 脏数据
查看>>
mysql 自增id和UUID做主键性能分析,及最优方案
查看>>
Mysql 自定义函数
查看>>
mysql 行转列 列转行
查看>>
Mysql 表分区
查看>>
mysql 表的操作
查看>>
mysql 视图,视图更新删除
查看>>
MySQL 触发器
查看>>
mysql 让所有IP访问数据库
查看>>
mysql 记录的增删改查
查看>>
MySQL 设置数据库的隔离级别
查看>>
MySQL 证明为什么用limit时,offset很大会影响性能
查看>>
Mysql 语句操作索引SQL语句
查看>>
MySQL 误操作后数据恢复(update,delete忘加where条件)
查看>>
MySQL 调优/优化的 101 个建议!
查看>>
mysql 转义字符用法_MySql 转义字符的使用说明
查看>>