webpack优化

优化方向

在这里插入图片描述

热更新

概念

/**

  • hmr: hot module replacement 热模块替换 / 模块热更新
  • 作用: 一个模块发生改变,只会重新打包这一个模块(而不是打包所有模块),极大的提升了构建速度
  • 样式文件: 可以使用hmr功能: style-loader内部实现了热更新功能
  • js文件:默认没有这个功能(会全量刷新)—> 修改js代码,只能处理非入口文件
  • html文件: 默认没有这个功能(会全量刷新)因为项目中只有一个html文件,所以我们不需要做热更新
    */

实现

因为我们在开发环境使用的是webpack-dev-server,所以不需要额外的添加代码,hot默认值为true,自动会热更新。但是对于js我们需要额外的处理。
// 在入口文件中写如下代码

if (module.hot) {
    // 一旦 module.hot为true, 说明开启了热更新功能,--》让hmr功能代码生效
    module.hot.accept('./print.js',function() {
        // 方法会监听到print.js文件的变化,一旦发生变化,其他模块不会重新打包构建
        // 会执行回调函数
        print();
    })
}

source-map

是一种提供源代码到构建后代码的一种映射技术(如果构建后代码出错了,通过映射关系,可以追踪到源代码的错误)。

  1. 配置
  /**
   * 是一种提供源代码到构建后代码的一种映射技术(如果构建后代码出错了,通过映射关系,可以追踪到源代码的错误)。
   * [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
   * source-map: 外联   错误代码的准确信息和源代码的错误位置
   * inline-source-map: 内联 (只生成一个source-map)  错误代码的准确信息和源代码的错误位置
   * hidden-source-map: 外联    错误代码的原因,但没有错误代码的位置,不能追踪源代码的错误,只能提示构建代码的位置 (防止代码泄露)
   * eval-source-map: 内联 (每个文件都生成一个source-map,都在eval中)   错误代码的准确信息和源代码的错误位置
   * nosources-source-map 外联  错误代码准确信息,但没有任何源代码信息 
   * cheap-source-map  外联   错误代码的准确信息和源代码的错误位置 只能精确到行,不能精确到列
   * cheap-module-source-map 外联  错误代码的准确信息和源代码的错误位置  module会将loader的source-map加入
   * 
   * 内联和外联的区别:1. 外联生成了文件,内联没有 2.内联构建速度更快
   * 
   * 使用:
   * 开发环境:
   * 速度快, (eval > inline > cheap) eval-cheap-source-map:速度最快 
   * 调试更友好 
   * source-map
   * cheap-module-source-map
   * cheap-source-map
   * 
   *  ----> 开发环境使用:eval-source-map / eval-cheap-module-source-map
   * 生产环境:源代码要不要隐藏,调试要不要更友好
   * 内联会让包的体积非常大,所以生产环境一般不用内联
   * 
   * 隐藏: 
   * nosources-source-map (全部隐藏)
   *  hidden-source-map (部分隐藏)
   * 生产环境使用:source-map / cheap-module-source-map
   *  */  
   devtool: 'source-map'

oneOf

  • 使用
module:{
  rules:[
    {
      oneOf: [
        // loader 
      ]
    }
  ]
}

正常情况中我们每个文件都会被所有的loader“处理一下”,但是在oneOf中的loader,他匹配到之后就不会接着执行下面的loader了,所以oneOf,**可以提升构建速度 **,当一类文件,配置了多个的情况下,可以将其他的放到oneOf外面处理

缓存

  1. babel缓存

就是要在babel下,添加 cacheDirectory: true, 个人实验没啥效果(构建速度提升不明显)

 {
   //  1. js兼容性处理: babel-loader @babel/core  @babel/preset-env
   //  问题:babel只能转换基础的语法,如promise则不能进行转换
   //  2. 全部兼容  @babel/polyfill
   //  问题:可以解决兼容性问题,但是引入了所有的兼容性代码,体积太大
   //  3. 需要做兼容性的处理就ok,按需加载---> core-js
   test: /\.js$/,
     exclude: /node_modules/,
       loader: 'babel-loader',
         options: {
           // 预设: 指示babel做怎样的兼容性处理
           presets: [[
             '@babel/preset-env',
             {
               useBuiltIns: 'usage', //按需加载
               corejs: {
                 version: 3, // 指定core-js版本
               },
               targets: {  // 指定兼容浏览器版本
                 chrome: '60',
                 firefox: '60',
                 ie: '9',
                 safari: '10',
                 edge: '17'
               }
             }
           ]],
             // 开启babel缓存,第二次构建,会读取之前的缓存
             cacheDirectory: true,
         }
 },
  1. 全局加cache ,构建速度显著提升(从2778ms–>419ms)
module.export = {
  cache: {
    type: 'filesystem',
    allowCollectingMemory: true,
  },
}
  1. 文件资源缓存,提升线上访问速度
// 通过修改文件名来实现缓存的效果,输出文件全部加上[contenthash:10]

/**
 * 缓存
 * babel缓存:cacheDirectory:true  --》让代码第二次构建打包速度更快
 *  文件资源缓存
 *  hash: 每次webpack构建时会生成一个唯一的hash值
 *   问题: js和css同时使用一个hash值
 *   如何重新打包,会导致所有的缓存失效
 *   chunkhash: 根据chunk生成的hansh值,如果打包来源于同一个chunk,那么hash值就一样    chunkid modeid
 *   contenthash: 文件内容不变,hash值不变  ---》让代码线上运行缓存更好使用
 * */ 
例如:
 output: {
        filename: 'budle.[contenthash:10].js',
        path: resolve(__dirname,'build')
 },

tree sharking

去掉没有用的代码,只留下引用了的代码,减小代码体积。

/**
 *  tree shaking 去除无用代码
 *  前提: 1. 必须使用es6模块化(使用import export 导入导出)  2. 开启production环境
 *  在package.json中配置
 *   "sideEffects": false 所有代码都没有副作用(度可以进行tree shaking)
 *   问题: 可能会把css /  @babel/polyfill 文件干掉
 *   解决:"sideEffects": ["*.css"]
 *   在sideEffects配置不需要删除的代码
 * */ 

code split

  1. 多入口

适合多页面开发

entry: {
  main: './src/index.js',
  test: './src/print.js'
}
output: {
  filename: '[name].[contenthash:10].js', // 这里的【name】,在入口文件中配置了, main test将成为文件名
  path: resolve(__dirname,'build');
}
  1. chunk
 // 将node_modules中代码单独打包成一个chunk最终输出  
  //  自动分析多入口chunk中有没有公共的文件,如果有会打包成单独一个chunk
   optimization: {
     splitChunks: {
        chunks: 'all'
     }
   }
  1. import

注意:!!! 如果你配置了eslint,可能会报错,因为eslint不能够解析import动态引入的语法,不报错的话就不需要使用babel-eslint。

// 通过js代码,让某个文件单独被打包成一个chunk
// import动态导入
import(/* webpackChunkName: 'test' */'./print').then(({print,mul}) => {
  console.log(3, 6);
}).catch(e) {
  console.log("文件加载失败",e)
}

下载
npm i -D babel-eslint

在package.json文件中加入parser配置

 "eslintConfig": {
    "extends": "airbnb-base",
    "parser": "babel-eslint",
    "parserOptions": {
      "sourceType": "module", 
      "allowImportExportEverywhere": true 
    }
  },

懒加载

  1. 将import动态引入放入异步函数中
document.querySelector('#btn').onclick = function() {
  import(/*webpackChunkName: 'test'*/'./print')
  .then(({mul}) => {
    console.log(mul(4, 5));
  })
  .catch((err) => {
    console.log(err)
  })
}

预加载

document.querySelector('#btn').onclick = function() {
// 懒加载: 当文件需要使用才加载
// prefetch: 预加载,提前加载js文件  等其他资源加载完毕,浏览器空闲了,在偷偷加载资源
// 正常加载:可以认为是并行加载(同一时间加载多个js文件)
import(/* webpackChunkName: 'test',webpackPrefetch: true */'./print')
.then(({ mul }) => {
  console.log(mul(3, 9));
})
.catch((e) => {
    console.log('文件加载失败',e);
})
}

PWA

  1. 下载插件

npm i -D workbox-webpack-plugin

  1. 代码 webpack.config.js中
/**
 * PWA: 渐进式网络开发应用程序(离线可访问)
 * workbox --> workbox-webpack-plugin
 */
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
plugins: [
  // 生成一个serviceworker配置文件
  new WorkboxWebpackPlugin.GenerateSW({
    clientsClaim: true,  // 帮助serviceworker快速启动
    skipWaiting: true, // 删除旧的 serviceworker  
  })
]
  1. 入口文件
//  注册serviceworker
//  处理兼容性问题
// eslint不认识window navigator全局变量
// 解决: 修改package.json中的eslintConfig配置
//  "env": {
//    "browser": true
//  }
// servicework代码必须构建在服务器上
if ('serviceWorker' in navigator) {
    window.addEventListener('load',() => {
        navigator.serviceWorker.register('/service-worker.js')
        .then(() => {
            console.log('serviceWorker注册成功')
        })
        .catch(() => {
            console.log('serviceWorker注册失败~')
        })
    })
}
  1. package.json文件中
"eslintConfig": {
    ...
    "env": {
      "browser": true
    }
 },

多进程开发

  1. 下载

npm i thread-loader -D

  1. 代码
/**
 * 开启多进程打包                         
 * 进程启动大概600ms,进程通信也有开销                           
 * 只有工作消耗时间比较长,才需要多进程打包 
 * 一般用来处理js文件消耗比较大的时候使用
 * */                          
{
  loader: 'thread-loader',
    options: {
      workers: 3,
    }
},

externals

让一些额外的包,不打包到build.js中

externals: {
    jquery: '$', // 外部可以通过$直接访问,不需要引入了
},

index.html中引入jquery文件

 <script
    src="https://code.jquery.com/jquery-3.1.0.js"
    integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
    crossorigin="anonymous"
   ></script>

dll

  1. 根目录下创建webpack.dll.js文件
/**
 * 使用dll技术,对某些库(第三方库: jquery, react, vue...)进行单独打包
 * 当运行webpack时默认查找webpack.config.js配置文件
 * 需求: 我们需要运行webpack.dll.js文件    webpack --config ./webpack.dll.js
 * */ 
const { resolve } = require('path');
const webapck = require('webpack');

module.exports = {
    entry: {
        // 最终打包生成的[name] ---> jquery
        jquery: ['jquery']
    },
    output: {
        filename: '[name].js',
        path: resolve(__dirname, 'dll'),
        library: '[name]_[hash:10]', //打包的库里面向外暴露出去的内容名字

    },
    plugins: [
        // 打包生成一个 mainfest.json ---> 提供和jquery映射关系
       new webapck.DllPlugin({
         name: '[name]_[hash:10]', // 映射库暴露的内容名称
         path: resolve(__dirname, 'dll/mainfest.json') // 输出文件路径
       })
    ],
    mode: 'production'
}
  1. 执行该文件

webpack -c ./webpack.dll.js -c是 --config缩写

  1. 下载包

npm i -D add-asset-html-webpack-plugin

  1. 在webpack.config.js中加入如下代码
plugins: [
   // 告诉webpack那些库不参与打包,同时使用时的名称也得改变
  new webpack.DllReferencePlugin({
    manifest: resolve(__dirname,'dll/mainfest.json')
  }),
  // 将某个文件打包输出去,并在html中自动引入该资源
  new AddAssetHtmlWebpackPlugin({
    filepath: resolve(__dirname, 'dll/jquery.js'),
    outputPath: 'auto', // 生成的index.html文件中多了一层auto目录
  }),
]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/801838.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

防火墙-NAT策略和智能选路

一、背景技术 在日常网络环境&#xff0c;内部网络想要访问外网无法直接进行通信&#xff0c;这时候就需要进行NAT地址转换&#xff0c;而在防火墙上配置NAT和路由器上有点小区别&#xff0c;思路基本一致&#xff0c;这次主要就以防火防火墙配置NAT策略为例&#xff0c;防火墙…

【学习css3】使用flex和grid实现等高元素布局

过往的实现方法是使用浮动加计算布局来实现&#xff0c;当flex和grid问世时&#xff0c;这一切将变得简单起来 一、简单的两列实现 1、先看页面效果 2、css代码 .container {padding: 10px;width: 100ch;margin: 0 auto;box-shadow: inset 0 0 0 2px #ccc;}.column {margin: 2…

git clone 报错 Unable to negotiate

Unable to negotiate with 192.168.110.10 port 39418: no matching cipher found. Their offer: aes128-cbc,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc fatal: Could not read from remote repository. 查询支持哪些加密算法 ssh -Q cipher 修改文件 /etc/ssh/ssh_config…

AR0132AT 1/3 英寸 CMOS 数字图像传感器(AR0132AT6R、AR0132AT6C)适用于监控和高清视频等多种应用

AR0132AT 1/3 英寸 CMOS 数字图像传感器&#xff0c;带 1280H x 960V 有效像素阵列。它能在线性或高动态模式下捕捉图像&#xff0c;且带有卷帘快门读取。它包含了多种复杂的摄像功能&#xff0c;如自动曝光控制、开窗&#xff0c;以及视频和单帧模式。它适用于低光度和高动态范…

基于AT89C51单片机构造波形发生器设计(含文档、源码与proteus仿真,以及系统详细介绍)

本篇文章论述的是基于AT89C51单片机构造波形发生器设计的详情介绍&#xff0c;如果对您有帮助的话&#xff0c;还请关注一下哦&#xff0c;如果有资源方面的需要可以联系我。 目录 摘要 仿真图 总体结构框图 仿真程序效果图 原理图 代码 系统论文&#xff08;部分&…

Qcom平台通过Hexagon IDE 测试程序性能指导

Qcom平台通过Hexagon IDE 测试程序性能指导 1 安装Hexagon IDE工具2 测试工程2.1 打开Hexagon IDE2.2 新建工程2.3 添加测试案例2.3.1 方法一&#xff1a;新建2.3.2 方法二&#xff1a;拷贝 2.4 配置测试环境2.4.1 包含头文件2.4.2 添加程序优化功能(需先bulid一下)2.4.3 添加g…

【14】Github Copilot环境搭建

环境搭建 这里以Visual Studio Code为例&#xff0c;安装好vs code&#xff0c;打开扩展侧边菜单栏&#xff0c;搜索“Github Copilot”&#xff0c;会出现如下图的两个插件&#xff0c;点击安装第一个&#xff0c;另一个会附带一起安装&#xff0c;然后弹出提示重新启动vs co…

阿里云CDN- https(设计支付宝春节开奖业务)

HTTP相关概念 1. HTTP概述 http是最广泛的网络协议&#xff0c;是客户端与服务器之间的请求与应答的标准&#xff08;TCP&#xff09;&#xff0c;用于www服务器传输超文本到本地浏览器的传输协议&#xff0c;使浏览器更加高效&#xff0c;网络传输减少。 2.HTTPS概述 http…

OpenHarmony移植之编译工具链

OpenHarmony移植之编译工具链 1、下载工具链 选择适合自己芯片的arm编译工具链&#xff0c;因为我的是arm cortex-a9的芯片&#xff0c;所以我选择如下交叉工具链 Downloads | GNU-A Downloads – Arm DeveloperDownload the The GNU Toolchain for the Cortex-A Family are…

稀疏3D检测-Sparse4Dv1v2v3

0. Multi-view 3D detection LSS(Lift-Splat-Shoot)利用深度估计将图像特征提升到3D空间&#xff0c;并将特征拍到BEV平面。后续工作将lift-splats操作应用于3D检测领域。 Bevformer将时序信息以BEV特征cat一起引入时序信息。 DETR3D中通过预测的3D点投影到图像平面后获取图像…

HTTPS请求头缺少HttpOnly和Secure属性解决方案

问题描述&#xff1a; 建立Filter拦截器类 package com.ruoyi.framework.security.filter;import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.…

vue仿甘特图开发工程施工进度表

前言 本文是根据项目实际开发中一个需求开发的demo&#xff0c;仅用了elementUI&#xff0c;可当作独立组件使用&#xff0c;C V即用。 当然没考虑其他的扩展性和一些数据的校验&#xff0c;主要是提供一个处理思路&#xff0c;有需要的小伙伴可以直接复制&#xff1b;本demo的…

厂家置换电费如何达到最大化收益

新能源行业知识体系-------主目录-----持续更新https://blog.csdn.net/grd_java/article/details/140004020 文章目录 一、电能电费二、同时刻不同厂家置换&#xff0c;不会影响最终电能电费结果三、风险防范补偿和回收机制四、我们的数据如何考虑补偿和回收五、如何利用补偿和…

K8S私有云裸金属服务器负载均衡器OpenELB——筑梦之路

OpenELB介绍 OpenELB 是一个专为裸机 Kubernetes 集群设计的开源负载均衡器实现。 在云服务环境中的 Kubernetes 集群里&#xff0c;通常可以用云服务提供商提供的负载均衡服务来暴露 Service&#xff0c;但是在本地没办法这样操作。而 OpenELB 可以让用户在裸金属服务器、边缘…

二叉树问题,两种解决方法(1遍历 2直接定义名字功能递归

1第一种方法就是另写一个traverse方法&#xff0c;2第二种方法就是把函数名当成已经实现的功能&#xff0c;直接写 1、翻转二叉树 class Solution {public TreeNode invertTree(TreeNode root) {if(rootnull) return null;TreeNode leftinvertTree(root.left);TreeNode righti…

Facebook:数字时代的社交瑰宝

在当今数字化飞速发展的时代&#xff0c;社交媒体已经成为人们日常生活中不可或缺的一部分&#xff0c;而Facebook作为其中的领军者&#xff0c;不仅连接了全球数十亿的用户&#xff0c;更深刻地改变了人们的社交方式和生活方式。本文将探讨Facebook如何成为数字时代的社交瑰宝…

【排序算法】1.冒泡排序-C语言实现

冒泡排序&#xff08;Bubble Sort&#xff09;是最简单和最通用的排序方法&#xff0c;其基本思想是&#xff1a;在待排序的一组数中&#xff0c;将相邻的两个数进行比较&#xff0c;若前面的数比后面的数大就交换两数&#xff0c;否则不交换&#xff1b;如此下去&#xff0c;直…

SimMIM:一个类BERT的计算机视觉的预训练框架

1、前言 呃…好久没有写博客了&#xff0c;主要是最近时间比较少。今天来做一期视频博客的内容。本文主要讲SimMIM&#xff0c;它是一个将计算机视觉&#xff08;图像&#xff09;进行自监督训练的框架。 原论文&#xff1a;SimMIM&#xff1a;用于掩码图像建模的简单框架 (a…

支持大量边缘盒子集中管理调度的智慧物流开源了。

智慧物流视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。用户只需在界面上…

在golang中Sprintf和Printf 的区别

最近一直在学习golang这个编程语言&#xff0c;我们这里做一个笔记就是 Sprintf和Printf 的区别 fmt.Sprintf 根据格式化参数生成格式化的字符串并返回该字符串。 fmt.Printf 根据格式化参数生成格式化的字符串并写入标准输出。由上面就可以知道&#xff0c;fmt.Sprintf返回的…