webpack简单优化的配置

webpack性能优化

1.开发环境新能优化

1.1优化打包构建速度

1.1.1 HMR: hot module replacement / 热模板替换

作用: 一个模板发生变化,只会重新打包这一个模块(默认是打包所有)

1.2优化代码调试

1.1.2 source-map

作用: 一种提供源代码到构建后代码映射技术 (如果 构建后代码出错了 可以通过映射追踪源代码错误)

2. 生产环境性能优化

2.1优化打包构建速度

2.1.1 开启babel缓存

cacheDirectory: true,
让第二次打包更快,绑定contenthash值让线上运行缓存更好使

{
    test: /\.js$/,
    exclude: /node_modules/,
    loader: 'babel-loader',
    options: {
      // 预设  指示babel做怎么样的兼容性处理
      presets: [
        ['@babel/preset-env',
          {
            useBuiltIns: 'usage', // 按需加载
            corejs: { version: 3 }, // 制定corejs的版本
            targets: { // 指定具体的兼容性的版本
              chrome: '60',
              firefox: '60',
              ie: '9',
              safari: '10',
              edge: '17',
            },
          },
        ],
      ],
      // 开启babel缓存
      // 第二次构建时 会读取之前的缓存
      // 需要给 输出文件带上contnenthash值  不然无法更新变化
      cacheDirectory: true,
    },
},

  1. hash:每次webpack构建时会生成一个唯一的hash值,js和css同一个.
  2. chunkhash: 根据chunk生成的hash值,如果打包的来源于同一个chunk,那么chuankhash值就是一样的,js和css的还是一样的
  3. contenthash: 根据文件内容生成的hash值.不同文件hash值不一样

2.1.2 多进程打包 thread-loader

多用babel-loader 启动时间大概为600ms 只有工作消耗时间比较长的才需要多进程打包

一定要放在需要多进程的loader后面

{
  /**
   * 开启多进程打包。
   * 启动时间大概为600ms
   * 只有工作消耗时间比较长的才需要多进程打包
   */
  loader: 'thread-loader',
  options: {
    workers: 2, // 进程2个
  },
}

2.1.3 externals

忽略文件,不进行打包

externals: {
//拒绝jq被打包进来
//线上的需要通过cdn引入这个包
    jquery:'jQuery'
}

2.1.4 dll

使用dll技术,对某些库(第三方库:jq,react,vue…)进行单独打包,只用打包一次,之后就不用打包了

注意:当运行webpack时,默认查找webpack.config.js配置文件

需要运行webpack.dll.js文件 要指定
–> webpack --config webpack.dll.js

<!--webpack.dll.js文件-->
const {resolve} = require('path')
const webpack = require('webpack')
module.export = {
    entry: {
        //最终打包生成的[name]--> jquery
        //['jquery',xxx]-->要打包的库
        jquery:['jquery',xxx]
    },
    output: {
        filename: '[name].js',
        path: resolve(__dirname,'dll'),
        //打包库里面向外面暴露出去的内容叫什么名字
        library:'[name]_[hash]'
    },
    plugins:[
        new webpack.Dllplugin({
           //映射库暴露的内容名称 name:'[name]_[hash]',
            path: resolve(__dirname, 'dll/manifest.json')
        })
    ],
    mode: 'production'
}
<!--webpack.config.js文件-->
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const AddassetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
module.export = {
    entry:'./src/index.js',
    output: {
        filename: 'built.js',
        path: resolve(__dirname,'build'),
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'./src/index.html'
        }),
        //告诉webpack那些库不参与打包,同时使用名称时也得变
        new webpack.DllReferencePlugin({
            manifest: resolve(__dirname,'dll/manifest.json')
        })
        //将某个文件打包出去。并在html中自动引入资源
        new AddassetHtmlWebpackPlugin({
            filepath: resovle(__dirname,'dll/jquery.js')
        })
    ],
    mode: 'production'
}

2.2优化代码运行性能

2.2.1 oneOf

module:{
    rules:[
        {
            test: /\.js$/,
            exclude: /'node_modules'/,
            enforce: 'pre', // 优先执行
            loader: 'eslint-loader',
            options: {
              // 自动修复
              fix: true,
            },
        },
        {
         oneOf:[
            {
                exclude: /\.(css|js|html|less|jpg|png|gif)$/,
                loader: 'file-loader',
                options: {
                  outputPath: 'font',
                },
             },
         ]
        } 
    ]
}

不用oneOf的话 每个文件都要被所有Loader过滤一遍,注意:不能有两个配置处理一中类型的文件

  1. 正常来说 一个文件只能被一个loader处理
  2. 当要被多个Loader处理的时候 需要弄清执行的顺序 比如 先要 执行 eslint 在执行babel转换 ,不然 先babel转换成es5的话,再eslint回报错
  3. 使用enforce:'pre’属性,提到oneOf外面

2.2.2 tree shaking 去除无用代码

注意: 1.必须使用es6模块化 2.开启production环境

作用: 减少代码体积,会自动删除没有使用的代码,使用production时会自动开启,

防止css被删除,需要在package.json中配置:
“sideEffects”:["*.css"]

2.2.3 code split代码分割

分割成多个js文件,实现并行加载 速度更快

2.2.3.1 从入口入手
entry:{
//多个入口 多个bundle  多页面
//单页面 则单入口
    main:'./src/js/index.js',
    test:'./src/js/test.js',
},
output: {
    //[name]文件名
    fileName:'js/[name].[contenthash:10].js',
    path: resolve(_dirname,'build')
}
2.2.3.1 optimization
// 可以将node_module中代码单独打包成一个chunk输出(单入口)
//可以自动分析多入口chunk中,公共文件,有可以单独打包成一个chunk,不会重复的打包多次(多入口)
optimization:{
    splitChunks:{
        chunks:'all'
    }
}

//单入口 引入js打包成单独的
// import动态导入 
import(/* webpackChunkName:'test' */'./test')
.then(()=>{文件加载成功})
.catch(()=>{文件加载失败})

2.2.3 懒加载

//js懒加载 需要使用时候才加载
document.getElementById('btn').onclick = function () {
  import( /* webpackChunkName:'ppp' */ './ppp').then(({
    add
  }) => {
    add(4, 6)
  })
}

2.2.4预加载

//js预加载 webpackPrefetch  会在使用之前提前加载 等其他资源加载完毕 再偷偷加载
document.getElementById('btn').onclick = function () {
  import( /* webpackChunkName: 'test',webpackPrefetch: true */ './ppp' ).then(({
    add
  }) => {
    add(4, 6)
  })
}

2.2.5 PWA 渐进式网络开发应用程序

workbox --> workbox-webpack-plugin

<!--config.js-->
    new WorkboxWebpackPlugin.GenerateSW({
      // 帮助serverwork快速启动   删除旧的serverwork
      // serverwork配置文件  一般在入口文件中配置
      clientsClaim: true,
      skipWaiting: true,
    }),
    
<!--index.js-->

//注册serverwork
//需要处理兼容性问题
//eslint不认识window等全局变量
// "env": {
//   "browser": true  //支持浏览器
// }
if ('serverWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serverWorker.register('/service-worker.js')
      .then(() => {
        console.log("serverworker注册成功")
      })
      .catch(() => {
        console.log("serverworker注册失败")
      })
  })
}
<!--package.json(eslint)-->
  "eslintConfig": {
    "extends": "airbnb-base",
    "env": {
      "browser": true
    }
  },
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章