webpack5 (三)

news2024/11/19 8:28:44

 webpack 高级配置

其实就是对 webpack 进行优化,让代码在编译/运行时性能更好

1. 提升开发体验
2. 提升打包构建速度
3. 减少代码体积
4. 优化代码运行性能

一、提升开发体验

sourcemap

在编译打包后所有的 css 和 js 都合并为了一个文件,并多了很多其他代码,如果此时代码运行出错,提示的错误位置很难定位。所以开发者需要更准确的错误提示来进行开发工作。

SourceMap 源代码映射,是一个用来生成源代码与构建后代码一一映射的文件的方案。

它会生成一个 xxx.map 文件,里面包含源代码和构建后代码每一行、每一列的映射关系。当构建后代码出错后,会通过 xxx.map 文件,从构建后代码的出错位置找到映射后源代码的出错位置,从而让浏览器提示源代码的错误位置。

使用:

Devtool | webpack 中文文档 | webpack 中文文档 | webpack 中文网

实际开发中只需要关注两种情况:

  • 开发模式:cheap-module-source-map
    • 优点:打包编译速度快,只包含行映射
    • 缺点:没有列映射
module.export = {
    //其他省略
    mode:'development',
    devtool:'cheap-module-source-map'

};
  • 生产模式:source-map
    • 优点:包含行/列映射
    • 缺点:打包编译速度更慢
module.export = {
    //其他省略
    mode:'production',
    devtool:'source-map'

};

生产模式下一定要关心列的位置,因为生产模式打完完成后只有一行代码,如果不看列位置,也就无法定位错误位置。

二、提升打包构建速度

HMR(HotModuleReplacement)热模块替换

只在开发模式下有效,生产模式中是不存在的。

开发时如果修改了其中某一个模块的代码,webpack 默认会将所有模块全部重新打包编译,速度比较慢。

所以需要做到修改某个模块的代码时,就只有这个模块的代码需要重新打包编译,其他的模块不变,这样打包的速度也会更快。

HMR:在程序运行中,替换、添加或删除模块,而无需重新加载整个页面。

HotModuleReplacementPlugin | webpack 中文文档 | webpack 中文文档 | webpack 中文网

css 经过 style-loader 处理已经具备 HMR 的功能了,但是 js 还不行,在实际开发中,一般使用其他 loader 来解决。比如 vue-loader 和 react-hot-loader 。 

oneOf

正常文件在进入配置文件时,是会查看所有的loader的,即使 css 文件在第一个 css-loader 已经进行处理后,也会将全部 loader 都查看一遍。

oneOf 让文件只让一个 loader 进行处理。

只需要将 rule 下的 loader 都用 oneOf 包裹起来就可以了。这样在执行时,如果第一个 loader 被命中,就不会再查看后续 loader。

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.css$/,
        oneOf: [
          {
            resourceQuery: /inline/, // foo.css?inline
            use: 'url-loader',
          },
          {
            resourceQuery: /external/, // foo.css?external
            use: 'file-loader',
          },
        ],
      },
    ],
  },
};

include/exclude 只针对 js 文件进行处理

开发时需要使用第三方的库或者插件,所有文件都下载到 node_modules 文件夹中,而这些文件是不需要编译,可以直接使用的。

所以在对 js 文件进行打包处理时,需要排除 node_modules 文件夹下目录。

  • include 包含,只处理 xxx 文件
  • exclude 排除,除了 xxx 文件以外的其他文件都被处理。

只是用来处理 js 文件的,样式文件等都不可用

 只能使用一个,不能同时使用 

cache

每次打包时 js 文件都要经过 Eslint 检查和 babel 编译,速度比较慢。可以设置缓存之前的 Eslint 检查和 babel 编译结果,这样二次打包时速度就会更快。

作用就是对 Eslint 检查和 babel 编译结果进行缓存。

    // 配置loader
    module: {
        rules: [
            // 处理 js
            {
                test:/\.jsx?$/,
                include:path.resolve(__dirname,'../src'),
                loader:'babel-loader',//babel 也需要有一个 babel 的配置文件
                options:{
                    catchDirectory:true,
                    catchCompression:false,
                    plugins:[
                        'react-refresh/babel',//用来解决react脚手架下 js不能热更新的问题
                    ]
                }
            }
        ]
    },
    // 配置plugin
    // 处理html 
    plugin:[
        //eslint 插件也是需要有自己的配置文件
        new EslintWebpackPlugin({
            context:path.resolve(__dirname,'../src'),
            exclude:'node_modules',
            cache:true, 
            cacheLocation:path.resolve(__dirname,'../node_modules/.catch/.eslintcache'),
        }),
        new HtmlWebpackPlugin({
            template:path.resolve(__dirname,'../public/index.html'),
        }),
        new ReactRefreshWebpackPlugin()//用来解决react脚手架下 js不能热更新的问题
    ],

 Thead

当项目越来越大时,打包的速度会越来越慢,想要继续提升打包速度,其实就是要提升 js 的打包速度(因为 js 文件是量最多的),而对 js 文件处理主要是三个工具:eslint、babel、Terser 三个工具,所以需要提升工具的运行速度。

可以开启多进程同时处理 js 文件,这样速度就会比之前的单进程打包更快。

⚠️注意:开启多线程仅需要在特别耗时的操作中使用,因为每个进程启动大概就会有 600 ms的开销。

启动进程的数量就是 CPU 的核数,获取 cpu 核数:

// node js 的核心模块,可以直接使用

const os = require('os');

// cpu 核数

const threads = os.cpus().length;

const TerserPlugin = require("terser-webpack-plugin");

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin({
        parallel: threads,//启用多进程并发运行并设置并发运行次数
    })],
  },
};

 optimization 选项专门用来放置压缩文件插件的,css、js、图片等压缩插件都可以在里面 new。

三、减少代码体积

Tree Shaking

开发时会定义一些工具函数库,或者引用第三方工具函数库或组件库。

如果没有经过特殊处理,打包时会引入整个库,但是实际上可能业务中只用到了极小一部分功能,整个库打包进代码体积过大。

Tree Shaking 是一个术语,描述为移除 js 中没有使用上的代码。依赖于 ES Module。

webpack 已经默认开启了该功能,无需其他配置。

babel

babel-loader | webpack 中文文档 | webpack 中文文档 | webpack 中文网

babel 为编译的每个文件都插入了辅助代码,使代码体积比较大,babel对一些公共方法使用了非常小的辅助代码,如_extend。默认情况下会被添加到每一个需要它的文件中。可以将这些辅助代码 Babel runtime 作为一个独立的模块,来避免重复引入。

下面的配置禁用了 Babel 自动对每个文件的 runtime 注入,而是引入 @babel/plugin-transform-runtime 并且使所有辅助代码从这里引用。

rules: [
  // 'transform-runtime' 插件告诉 Babel
  // 要引用 runtime 来代替注入。
  {
    test: /\.m?js$/,
    exclude: /(node_modules|bower_components)/,
    use: {
      loader: 'babel-loader',
      options: {
        presets: ['@babel/preset-env'],
        plugins: ['@babel/plugin-transform-runtime']
      }
    }
  }
]

Image Minimizer

ImageMinimizerWebpackPlugin | webpack 中文文档 | webpack 中文文档 | webpack 中文网

开发的项目中如果引用了较多的图片,那么图片体积就会比较大,将来请求的速度比较慢,可以对图片进行压缩,减少图片体积。

⚠️注意:如果项目中图片为在线链接,就不用压缩,压缩的前提是必须为本地项目静态图片

四、优化代码的运行性能

Code Split

打包代码时,会将所有的 js 文件打包到一个文件中,体积太大了。如果只渲染首页,就应该只加载首页的 js 文件,其他文件暂时不加载。

所以需要对打包生成的文件进行代码分割,生成多个 js 文件,渲染哪个页面就只加载某个js文件,这样加载的资源少,速度更快。

代码分割(Code Split)主要做了两件事:

  1. 分割文件:将打包生成的文件进行分割,生成多个 js 文件。
  2. 按需加载:需要哪个文件就加载哪个文件。​

多入口

    entry: {
        //多个入口文件
        main: './src/main.js',
        app: './src/app.js',
    },
    output: {
        path: path.resolve(__dirname, '../dist'),//设置出口文件路径
        filename: 'static/js/[name].[contenthash:10].js',//加入哈希值
        chunkFilename: 'static/js/[name].[contenthash:10].chunk.js',//加入哈希值
        assetModuleFilename: 'static/media/[hash:10][etx][query]',
        clean: true,//将上次打包内容清空
    },

多入口提取公共组件

在多个入口文件存在着相同的模块时,将相同部分单独抽离出来,变成可复用的文件。在 optimization 模块下的设置 splitChunks 。

optimization: {
        //代码分割配置
        splitChunks: {
            chunks: 'all'
        },
}

按需加载 动态引入

import 动态导入,会将动态导入的文件进行代码分割,拆分成单独的模块,在需要的时候自动加载。

单文件 单入口

如果在进行动态导入时,eslint 不能识别,需要在 eslint 配置文件中进行单独配置,设置 plugins:["import"],用来解决动态导入语法报错。

统一命名规则

需要用到的地方:

output 中入口文件打包输出的文件名 filename,动态加载打包输出的其他文件名 chunkFilename。loader 模块 module 中图片、字体图标等命名 filename。
plugins 插件中打包样式的命名 filename 。

    output: {
        path: path.resolve(__dirname, '../dist'),//设置出口文件路径
        filename: 'static/js/[name].[contenthash:10].js',//加入哈希值
        chunkFilename: 'static/js/[name].[contenthash:10].chunk.js',//加入哈希值
        assetModuleFilename: 'static/media/[hash:10][etx][query]',
        clean: true,//将上次打包内容清空
    },

Preload/ Prefetch

前面使用的代码分割,同时会使用动态导入语法来进行按需加载(懒加载)。但是加载速度不够好,比如:

当用户点击按钮时才加载这个资源,如果资源的体积很大,那么用户会感觉到卡顿。

如果想在浏览器空闲时间,加载后续需要使用的资源,就用到 preload/prefetch 技术。

  • Preload:通知浏览器立即加载资源。
  • Prefetch:通知浏览器在空闲时间时才开始加载资源。

共同点:

  • 都只会加载资源,并不执行。
  • 都有缓存。

不同点:

  • preload 加载的优先级高;prefetch 加载优先级低。
  • preload只能加载当前页面需要使用的资源;prefetch可以加载当前页面资源,也可以加载下一个页面需要使用的资源。

在当前页面优先级高的资源用 preload 加载,下一个页面需要使用的资源用 prefetch 加载。二者的兼容性都比较差,preload 相对于 prefetch 兼容性好一点,可以去Can I Use 网站查询 API 的兼容性问题。

Network Cache

如果 a 文件依赖于 b 文件,而 b 文件进行了修改,那么 a 文件也需要重新打包,为了解决这种问题,需要把文件依赖的哈希值抽成一个 runtime 文件,这样在依赖发生修改时,只有该依赖文件和 runtime 文件的缓存失效,缓存更持久化。

CoreJs

解决 js 兼容性问题

过去使用 babel 对 js 代码进行兼容性处理,其中使用@babel/preset-env 智能预设来处理兼容性问题。它能将 ES6 的一些语法进行编译转换,比如箭头函数,扩展运算符等。但是如果是 async 函数、promise 对象、数组的一些方法等,就没有办法处理。

所以此时代码中依然存在着 js 兼容性问题,一旦遇到低版本浏览器会直接报错。所以用 core-js 来解决。

core-js 是专门用来做 ES6 及以上 API 的 polyfill。polyfill 翻译为垫片/补丁,就是用社区上提供的一段代码,让在不兼容某些新特性的浏览器上使用该新特性。​

方式一:入口文件 main.js 直接引入

import 'core-js';

按需加载:import 'core-js/es/promise';(只使用promise),需要使用什么新语法就直接加载哪个包,但此时也会带来新的问题,在代码越写越多时,一旦用到新写法都要进行重新引入。

方式二: babel 配置文件的智能预设选项

module.exports = {
  presets: [
    [
        '@babel/preset-env',
        {
            useBuiltins:"usage"//按需加载 自动引入
            corejs:3 //corejs版本
        }
    ]
  ],
};

PWA

 

​ 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

管理类联考——数学——汇总篇——知识点突破——数据分析——计数原理

角度——⛲️ 一、考点讲解 分类计数原理(加法原理) (1)定义 如果完成一件事有n类办法,只要选择其中一类办法中的任何一种方法,就可以完成这件事。若第一类办法中有 m 1 m_1 m1​种不同的方法,第二类办法中…

SpringCloud(35):Nacos 服务发现快速入门

本小节,我们将演示如何使用Spring Cloud Alibaba Nacos Discovery为Spring cloud 应用程序与 Nacos 的无缝集成。 通过一些原生的spring cloud注解,我们可以快速来实现Spring cloud微服务的服务发现机制,并使用Nacos Server作为服务发现中心,统一管理所有微服务。 1 Spring…

uniapp集成windicss的流程

一、背景介绍 Windicss是一个基于Tailwind CSS 灵感的库,它更快、更兼容,使用 TypeScript 构建。Windicss的目标是为了解决与Tailwind CSS 类似的问题,提供一个可以快速上手开发的组件库,让开发者不再需要繁琐地编写 CSS 样式。Windicss包含了几乎所有的 CSS 样式,因此开发…

MongoDB常用的比较符号和一些功能符号

比较符号 results collection.find({age: {$gt: 20}})功能符号 results collection.find({name: {$regex: ^M.*}})

联合教育部高等学校科学研究发展中心,阿依瓦科技创新教育专项正式发布!

7 月 24 日,教育部科技发展中心官网发布了《中国高校产学研创新基金-阿依瓦科技创新教育专项申请指南》。 针对高校在人工智能、智能制造、智慧校园、大数据等领域科研和教研的创新研究,教育部高等学校科学研究发展中心与阿依瓦(北京)技术有…

RK3399平台开发系列讲解(内核调试篇)IO 数据工具:iostat和iotop

🚀返回专栏总目录 文章目录 一、iostat 命令二、/proc/diskstats 文件三、iotop 命令沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 在 Linux 系统上,iostat 和 iotop 这两个 IO 数据工具非常常用。它们都是性能分析领域中不可缺少的工具性软件。 一、iostat 命令…

linux和docker下mysql安装

目录 一、linux下mysql的安装 1.进入到/etc/yum.repos.d 2.编辑vim mysql-community.repo 3.编辑以下内容 4.保存退出,更新缓存yum makecache 5.下载mysql 6.启动并查看mysql状态 7.查找mysql密码 8.登陆mysql 9.密码修改参考MySQL密码修改 二、docker安…

solidity开发环境配置,vscode搭配remix

#学习笔记 初学solidity,使用remix非常方便,因为需要的环境都配置好了,打开网站就可以使用。 不过在编写代码方面,使用vscode更方便,而vscode本身并不能像remix那样部署合约,它还需要安装插件。 点击红色箭…

springboot整合mybatis实现增删改查(xml)--项目阶段1

目录 一、前言 二、创建项目 创建MySQL数据库和表 创建springboot项目 本文总体代码结构图预览 三、编写代码 (一)新建实体层属性类 (二)新建数据层mapper接口 (三)新建mapper的映射SQL&#xff08…

QProcess 调用 ffmpeg来处理音频

项目场景: 在文章 qt 实现音视频的分贝检测系统中,实现的是边播放变解析音频数据来统计音频的分贝大小,并不满足实际项目的需求,有的视频声音正常,有的视频声音就偏低,即使放到最大音量声音也是比较小&…

Apache实现weblogic集群配置

安装apache,安装相对稳定的版本。如果安装后测试能否正常启动,可以通过访问http://localhost/进行测试。安装Weblogic,参见文档将bea安装目录 weblogic81/server/bin 下的 mod_wl_20.so 文件copy到 apache安装目录下Apache2/modules/目录下A…

90、00后严选出的数据可视化工具:奥威BI工具

90、00后主打一个巧用工具,绝不低效率上班,因此当擅长大数据智能可视化分析的BI数据可视化工具出现后,自然而然地就成了90、00后职场人常用的数据可视化工具。 奥威BI工具三大特点,让职场人眼前一亮! 1、零编程&…

【STM32】学习笔记-时间戳RTC

Unix时间戳 Unix 时间戳(Unix Timestamp)定义为从UTC/GMT的1970年1月1日0时0分0秒开始所经过的秒数,不考虑闰秒 时间戳存储在一个秒计数器中,秒计数器为32位/64位的整型变量 世界上所有时区的秒计数器相同,不同时区通…

Arrays.asList 和 null 类型

一、Arrays.asList 类型简析 Arrays.asList() 返回的List 是它的内部类&#xff0c;不能使用 retainAll() 取交集&#xff0c;导致元素的删除&#xff0c;会报错。 List<String> list Arrays.asList(value.split(",")); 替换为> List<String> list…

物联网应用中蓝牙模块怎么选?_蓝牙模块厂家

在蓝牙模块选型前期&#xff0c;一定要了解应用场景以及需要实现的功能&#xff08;应用框图&#xff09;&#xff0c;以及功能实现过程中所能提供调用的接口&#xff08;主从设备&#xff0c;功能&#xff09;&#xff0c;考虑模块供电&#xff0c;尺寸&#xff0c;接收灵敏度…

leetcode每日一练-第53题-最大子数组和

一、思路 动态规划 二、解题方法 使用了两个变量 maxSum 和 currentSum 来分别记录全局的最大和和当前连续子数组的和。遍历数组时&#xff0c;我们不断更新 currentSum&#xff0c;并比较是否需要更新 maxSum。最后&#xff0c;maxSum 就是最大的连续子数组和。 三、code …

视频监控/视频汇聚/视频云存储EasyCVR平台接入国标GB协议后出现断流情况,该如何解决?

视频监控汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。安防监控平台EasyCVR既具备传统安防视频监控的能…

【js】防抖和节流的使用场景和区别:

文章目录 一、防抖 &#xff08;多次触发 只执行最后一次&#xff09;二、节流 &#xff08;规定时间内 只触发一次&#xff09;三、防抖和节流的使用场景【1】防抖&#xff08;debounce&#xff09;【2】节流&#xff08;throttle&#xff09; 一、防抖 &#xff08;多次触发 …

功率放大器主要要求有哪些

功率放大器是电子设备中常用的组件&#xff0c;用于将输入信号的功率放大到更高的水平。为了确保功率放大器的正常工作和性能表现&#xff0c;它需要满足一系列要求。下面西安安泰将详细介绍功率放大器的主要要求&#xff0c;希望大家可以对功率放大器有清晰的认识。 一、功率放…

hadoop3.3.1单机版环境搭建详细流程记录

1、在centos7中创建必要的目录&#xff1b; 2、上传JDK安装包到tools目录&#xff1b; 3、解压JDK到/opt/server/目录&#xff1b; tar -zxvf jdk-8u221-linux-x64.tar.gz -C /opt/server/ 4、“vim&#xff1a;未找到命令”的解决办法&#xff1b; 安装vim即可&#xff1b; …