阅读 367
webpack 通用配置及构建速度,体积优化

webpack 通用配置及构建速度,体积优化

前言

最近在学习webpack,记录一下学习的基础东西,以及项目构建的速度和体积的优化。

webpack基本配置

基本配置之前写过一遍文章,不重新写啦,不了解请转webpack之小白篇

修改代码,自动编译

  • webpack --watch 不会刷新浏览器,开发环境打包后的js是存在磁盘中。

package.json文件 image.png webpack.dev.js文件 image.png 注:webpack.dev.js // 开发环境配置 webpack.prod.js // 生成环境配置

  • webpack-dev-server --open 会自动打开浏览器,需要与webpack.HotModuleReplacementPlugin()配合使用,代码变动,可以自动刷新浏览器。

package.json文件 image.png webpack.dev.js文件 image.png

热更新(HMR:Hot Module Replacement)原理

image.png

  • Webpack Complier将代码转化为bundle.js文件。
  • 将bound.js文件传输Bounle Server,提供浏览器Browser访问。
  • 当代码更新时,会出发HMR Server 将代码传入到HMR Runtime(通常以json形式)
  • HMR Runtime接受会更新代码,刷新浏览器。

文件指纹

打包输出的文件名的后缀,通常作为版本的管理,没有修改的文件,可以使用浏览器缓存,加速访问。

  • hash:和整个项目有关,只要文件修改,整个项目构建的hash都会改变,通常图片和字体使用。
  • chunkhash:不同的entry有不同的chunkhash值,通常js文件使用。
  • contenthash:根据文件内容生成hash值,通常css使用。

style-loader:是将css插入style标签,插入到头部,没有单独的css文件。 MiniCssExtractPlugin(filename:'[name][conetnthash:8].css').loader 将css提出单独的文件,link到头部。 webpack.prod.js image.png

代码压缩

  • js,webpack4使用了terser-webpack-plugin插件默认以及打包过了,uglifyjs-webpack-plugin打包es6会报错。
  • html,使用html-webpack-plugin(一个html模板对应一个html-webpack-plugin)
  • css,使用optimize-css-assets-webpack-plugin插件,与cssnano配合使用

image.png

css3:自动添加浏览器前缀(aotuperfixer)

image.png

移动端css中的px转化为rem

  • rem:相对单位,(相对于根元素html的font-size)
  • px:绝对单元
  • px2rem:将px转为rem

image.png

  • lib-flexible:动态的计算根元素的font-size

在入口文件引入import 'lib-flexible'

多页面应用(entry+html-webpack-plugin)

动态的设置entry,html-plugin-webpack,使用glob库,glob.sync()可以同步的获取正则匹配的目录信息。 image.png

source map 定位源代码

开发环境中开启,生产环境上关闭。 webpack.prod.js image.png

优化构建时命令行日志显示

webpack中stats:统计信息 使用friendly-errors-webpack-plugin插件,将stats设置为'error-only' image.png image.png

webpack进阶用法

提取公共资源

  • 将react,react-dom 等公用的库,通过cdn的方式引入,不打包进入到bounld.js,使用html-webpack-externals-plugin引入
new HtmlWebpackExternalsPlugin({
 externals: [
    {
      module: 'react',
      entry: 'https://unpkg.com/react@17/umd/react.production.min.js',
      global: 'react',
    },
  ],
}) 
复制代码
  • 通过webpack4自带的splitchunk属性进行公共脚本分离,splitchunk也可以提取公共使用的自己封装的函数,但是需要多个打包入库同时使用,一个项目使用多次是不可以的。
    optimization:{
        splitChunk:{
           minSize:0,
           cacheGroups:{
                vendor:{ // 提取node_modules的公共资源
                    test:/[\\/]node_modules[\\/](react|react-dom)[\\/]/,
                    name:'vendor',
                    chunks:'all'
                },
                commons:{ // 提取node_modules以及自己写的公告函数。(需要多个打包入口引用了依赖和公共函数)
                    chunks:'all',
                    name:'commons',
                    minChunks:'2'
                }
           }
        }
    }
复制代码

tree shaking (摇树优化)

只支持es6语法。webpack4的production默认打开。 原因:对代码进行静态分析,而不是在代码运行的时候在分析哪些是没有用到的,在tree shaking阶段把无用的代码注释,在代码压缩的阶段删除无用代码。

利用es6模块的特点:

  • import只能最为模块的顶层出现
  • import的模块名称只能是字符串常量(导入之后不能修改)
  • import binding 是immutable的(不能动态引入的)

注:不能在代码中动态的require导入

DCE(dead code elimination)

  • 代码不可达
  • 代码执行结果不会被用到
  • 代码只会影响死变量(只写不读)

Scope Hositing(/ˈhɔɪstɪŋ/)

webpack4的production默认打开,必须使用es6语法,不支持cjs。

不开启Scope Hoisting会导致什么问题:

  • 大量的闭包函数代码,会导致构建之后代码体积变大
  • 运行代码时创建的函数作用域变多,内存开销变大

scope hoisting的原理:

对所有模块的代码按照引用顺序放在一个函数作用域里,适当的重命名一些变量放置变量名冲突。

对比:通过scope hositing处理代码之后,会减少函数声明代码和内存开销。

注:如果模块只是用一次,会直接内联在函数作用域里,吐过使用多次,将会重新创建一个新的函数作用域。

代码分割

将所有的代码打包到一个文件中是不够有效的,特别是有些代码在某种特殊情况下才会用到,webpack可以将打包过的代码分割成多个chunks,当代码运行我们在进行加载。

webpack打包组件库

简单的组件库rollup更适合

发布npm包

  • 需要打包压缩版和非压缩版
  • 需要支持AMD/CJS/ESM模块导入,把output的library设置为'umd'。

webpack.config.js 配置

image.png

npm发布步骤

  • npm login // 登录
  • npm publish // 发布包
  • npm version path // 改bug打补丁
  • npm version minjor // 做一个feature,升级一个小的版本号
  • npm version major// 升级一个大版本

语义化版本(Semantic Versioning)格式规范

  • 主版本号:当做了不兼容的API的修改
  • 此版本号:当做了向下兼容的功能性新增
  • 修订号:当做了向下兼容的问题修正

先行版本号

  • alpha:是内部测试版,一般不向外发布,会有很多bug,一般只是测试人用。
  • beta:也是测试版,这个阶段的版本相对于alpha版的改进,消除了严重的错误,但是还存在着缺陷,这个版本也会一直加入新的功能,在alpha版之后推出。
  • rc:系统平台上发行的候选版本,rc版不会再加入新的功能了,主要着重于排错。

webpack构建速度

speep-measure-webpack-plugin速度分析 作用:可以查看每个loader和插件的执行耗时时间,整个打包耗时。 image.png

项目速度提升

1.使用高版本的webpack和node

2.多进程多实例构建

thread-loader(webpack4推荐使用),每次webpack解析一个模块,thread-loader将会将它及它的依赖分配给worker线程中。 image.png 3. 多进程实例压缩

terser-webpack-plugin 设置paralled参数 image.png 4. 分包:预编译资源模块

使用dllPlugin,dllReferencePlugin插件,使用script引入打包好的dll文件。 创建webpack.dll.js文件 image.png 在package.json文件中 image.png 执行npm run dll,就会生成公共包的文件。

在webpack.dev.js,webpack.prod.js配置即可(当打出多个文件时,每个文件都需要添加一个插件,文中只打包了一个文件) image.png

5.利用缓存提升二次构建

  • babel-laoader开启缓存
  • terser-webpack-plugin 开启缓存
  • 使用hard-source-webpack-plugin

image.png 6. 减少文件搜索范围 resolve.modules,resve.mainFields,resolve.extensions,resolve.alias配置。

webpack构建体积

webpack-bundle-analyzer分析体积 作用:第三方依赖包大小,我们自己组件代码大小

项目体积优化

1.图片压缩

使用image-webpack-loader

2.删除无用的css

  • PurifyCSS:遍历代码,识别已经用到的css,使用purgecss-webpack-plugin(css不可以使用)
  • uncss:需要html使用jsdom加载,样式使用postcss解析,通过document.querySelect来识别html文件里面不存在的选择器。

3.提取公共的资源模块

详见webpack速度提升的分包:预编译资源模块

总结

webpack的实践及优化,整理知识点,后期学习继续添加。

文章分类
前端
文章标签