当前位置: 首页 > news >正文

《webpack深入浅出系列》

webpack深入浅出系列

ES6模块与CommonJS模块的主要区别

加载时机ES6模块编译时输出,即模块在编译阶段就已经确定了依赖关系;而CommonJS模块运行时才加载,即运行到某个require语句时才加载对应的模块。
(也就是说,es6的模块化是在编写程序的时候就开始有优化校验和静态分析,而commonjs只有在程序运行的时候再找所谓的对应关系)

语法差异:ES6模块使用exportimport进行模块的导出和导入;而CommonJS模块使用module.exportsexports导出,使用require导入。

设计哲学:ES6模块更注重静态分析和代码优化,而CommonJS模块更多考虑了运行时的行为。
es6模块导入需要完整的文件名后缀以及在script标签中写入type=module,而CommonJS模块又不需要等等。更是由于前端开发中存在多种模块化标准(如 ES6 模块、CommonJS、AMD 等)以及不同类型的资源(如 JavaScript、CSS、图片等),Webpack工具 就通过自己的方式来统一管理这些模块和资源。

webpack基本概念

Webpack 是一个静态资源打包工具。

  1. 它会以一个或多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件输出出去。
  2. 输出的文件就是编译好的文件,就可以在浏览器引入运行了。
  3. 我们将 Webpack 输出的文件叫做 bundle(打包)。

在前端开发中,Bundle 是指通过打包工具(如 Webpack、Vite、Rollup 等)将项目的多个模块和资源文件(如 JavaScript、CSS、图片等)整合为一个或多个打包文件,以便在浏览器中更高效地加载和执行。
Bundle 的目的是优化代码的加载和执行,避免重复请求和依赖的冗余加载。通常,打包工具会根据依赖关系将模块整合在一起,进行以下几种优化处理:

  1. 合并文件:将分散的文件合并为一个或多个较少的文件,减少浏览器请求次数。
  2. 压缩代码:去除空格、注释,短化变量名,减少文件体积。
  3. 代码拆分(Code Splitting):根据页面访问情况,将代码拆分成多个 Bundle 文件,按需加载,提高首屏加载速度。
  4. Tree Shaking:移除未使用的代码,减少打包文件大小。
  5. 缓存优化:通过生成带有哈希值的文件名,确保修改后的文件在浏览器中被正确更新缓存。

示例

假设项目中有多个模块文件,如 index.jsstyle.cssutils.js 等。通过 Webpack 配置打包后,它们会被打包成一个或多个 Bundle 文件,比如 main.bundle.jsvendor.bundle.js 等,这些文件将被插入到 HTML 中。

为什么 Bundle 重要?

  • 提升加载效率:通过压缩和合并,减少网络请求数量。
  • 提高代码复用性:共享库或通用功能可以打包到单独的文件中,多个页面共享使用。
  • 便于代码维护:打包工具会自动管理模块依赖,避免手动控制加载顺序或依赖冲突。
    打包(Bundle)可以说是现代前端项目优化和模块管理的核心步骤,尤其在大型应用中表现尤为显著。

Webpack 本身功能是有限的:
只有两种模式以及多种配置
开发模式:仅能编译 JS 中的 ES Module 语法
生产模式:能编译 JS 中的 ES Module 语法,还能压缩优化JS 代码
Webpack 本身功能比较少,只能处理 js 资源,一旦遇到 css 等其他资源就会报错。
所以我们学习 Webpack,就是主要学习如何处理其他资源。

5 大核心概念

  • entry(入口)

    指示 Webpack 从哪个文件开始打包

  • output(输出)

    指示 Webpack 打包完的文件输出到哪里去,如何命名等

  • loader(加载器)

    webpack 本身只能处理 js、json 等资源,其他资源需要借助 loader,Webpack 才能解析

  • plugins(插件)

    扩展 Webpack 的功能

  • mode(模式)主要由两种模式:

    开发模式:development
    生产模式:production

Webpack 配置文件

在项目根目录下新建文件:webpack.config.js

module.exports = {// 入口entry: "",// 输出output: {},// 加载器module: {rules: [],},// 插件plugins: [],// 模式mode: "",
};

Webpack 是基于 Node.js 运行的,所以采用 Common.js 模块化规范

修改配置文件部分示例

// Node.js的核心模块,专门用来处理文件路径
const path = require("path");module.exports = {// 入口// 相对路径和绝对路径都行entry: "./src/main.js",// 输出output: {// path: 文件输出目录,必须是绝对路径// path.resolve()方法返回一个绝对路径// __dirname 当前文件的文件夹绝对路径path: path.resolve(__dirname, "dist"),// filename: 输出文件名filename: "main.js",},// 加载器module: {rules: [],},// 插件plugins: [],// 模式mode: "development", // 开发模式
};

此时不能处理样式等资源
Webpack 能力都通过 webpack.config.js 文件进行配置,来增强 Webpack 的功能。
Webpack 是一种现代 JavaScript 应用的打包工具,通过将代码及其依赖项打包成静态文件,方便在浏览器中加载和运行。以下是 Webpack 的一些核心概念:

1. Entry(入口)

  • 作用:Webpack 开始构建的起点,定义依赖关系图的根文件。
  • 配置:指定入口文件的路径,通常是应用的主文件,比如 index.js
  • 多入口:支持多入口配置,用于生成多个 Bundle 文件,适合多页面应用。
  • 例子
    module.exports = {entry: './src/index.js', // 单入口// 或者多入口entry: {app: './src/app.js',admin: './src/admin.js'}
    };
    

2. Output(输出)

  • 作用:定义 Webpack 如何命名、生成打包后的文件及输出路径。
  • 主要参数
    • path:打包文件的输出路径。
    • filename:打包后文件的名称。
  • 例子
    module.exports = {output: {path: __dirname + '/dist',filename: '[name].bundle.js' // [name] 用于多入口生成不同文件名}
    };
    

3. Loaders(加载器)

  • 作用:处理非 JavaScript 文件,如 CSS、图片、字体等,将它们转换为 Webpack 能够理解的模块。
  • 常用 Loaders
    • babel-loader:将 ES6+ 转译成 ES5。
    • css-loader:负责将 Css 文件编译成 Webpack 能识别的模块,从而允许 JavaScript 中 import CSS 文件。
    • style-loader:会动态创建一个 Style 标签,里面放置 Webpack 中 Css 模块内容。也就是把 CSS 注入到 DOM 中。此时样式就会以 Style 标签的形式在页面上生效。
    • file-loader:处理文件资源,返回文件 URL。
  • 例子
    module.exports = {module: {rules: [{ test: /\.js$/, use: 'babel-loader' },// 用来匹配 .css 结尾的文件 // use 数组里面 Loader 执行顺序是从右到左{ test: /\.css$/, use: ['style-loader', 'css-loader'] }]}
    };
    

4. Plugins(插件)

  • 作用:执行范围更广的任务,如优化、压缩、资源管理等。
  • 常用 Plugins
    • HtmlWebpackPlugin:生成 HTML 文件并自动注入打包后的资源。
    • DefinePlugin:在编译时创建全局常量。
    • MiniCssExtractPlugin:将 CSS 提取到单独文件。
  • 例子
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    module.exports = {plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })]
    };
    

5. Mode(模式)

  • 作用:定义打包的模式,有 development(开发)和 production(生产)两种模式。
  • 影响
    • development 模式:启用代码映射和调试,未压缩的输出。
    • production 模式:启用优化、Tree Shaking、代码压缩等。
  • 例子
    module.exports = {mode: 'development' // 或 'production'
    };
    

6. Chunk(代码块)

  • 作用:Webpack 根据模块之间的依赖关系生成的代码块。通常将主代码和第三方依赖(如 node_modules)打包成不同的 Chunk,以实现更高的缓存和按需加载。
  • 配置:通过 optimization.splitChunks 来拆分代码块。

7. Module(模块)

  • 作用:模块是应用的独立单元,Webpack 会递归解析入口文件所依赖的模块,形成依赖关系图。
  • 支持的模块类型:ES6 模块、CommonJS、AMD 模块等。

8. Dependency Graph(依赖图)

  • 作用:Webpack 会从入口文件出发递归构建所有模块的依赖关系图,确保所有依赖项都被打包在最终的输出文件中。

9. Tree Shaking

  • 作用:移除未使用的代码,减少打包后的文件体积。
  • 启用条件:需要使用 ES6 模块语法(import / export),并且在 production 模式下默认启用。

Webpack 的这些概念帮助开发者灵活地控制模块化、打包、优化等过程,在开发和生产环境中构建高效的前端应用。

开发模式介绍

开发模式顾名思义就是我们开发代码时使用的模式。
这个模式下我们主要做两件事:

  1. 编译代码,使浏览器能识别运行:
    开发时我们有样式资源、字体图标、图片资源、html 资源等,webpack 默认都不能处理这些资源,所以我们要加载配置来编译这些资源
  2. 代码质量检查,树立代码规范
    提前检查代码的一些隐患,让代码运行时能更加健壮。

提前检查代码规范和格式,统一团队编码风格,让代码更优雅美观。


其实模块化在前端程序设计中有很多的体现的地方
前端模块化是指将代码分解成独立、可复用的模块,以便于维护、扩展和复用。随着项目复杂度的增加,模块化显得尤为重要。前端的模块化可以分为以下几类:

1. 文件模块化

  • 传统的文件划分:根据功能将文件划分成不同文件夹,例如 componentsutilsservices 等,这种方式在项目初期非常普遍。
  • 按页面/功能划分:把每个页面作为一个模块,如 userPage.jsadminPage.js。在大型项目中,通常按功能划分多个目录层次,提升代码结构的清晰度。

2. 模块化方案

  • ES6 模块 (ESM):使用 importexport,这是目前最主流的模块化标准,得到了浏览器和 Node.js 的支持。
  • CommonJS:通过 requiremodule.exports 实现的模块化方案,主要用于 Node.js 后端开发。
  • AMD (Asynchronous Module Definition):通过 definerequire 来定义模块,适合于浏览器端的异步模块加载,经典库有 RequireJS
  • UMD (Universal Module Definition):兼容 AMD、CommonJS 和全局变量方式,适用于一些跨平台的库。

3. 组件化框架的模块化

  • React:基于组件的开发模型,每个组件就是一个独立的模块。使用 HooksContext 等可以在组件之间共享状态和逻辑。
  • Vue:通过 SFC (单文件组件) 将 HTML、CSS、JavaScript 集成在一个文件中,每个 .vue 文件就是一个模块。
  • Angular:采用模块化的结构,通过 NgModules 来组织代码。每个 NgModule 是一组组件、指令、服务的集合。

4. CSS 模块化

  • CSS Modules:生成局部作用域的 CSS,避免全局样式污染。
  • 预处理器 (如 SASS/SCSS):提供嵌套、变量、混入等功能,让 CSS 更具模块化能力。
  • CSS-in-JS:将 CSS 写在 JavaScript 中,如 styled-componentsEmotion,适用于 React 等框架,可以将样式与逻辑模块化结合。

5. 打包工具的模块化

  • Webpack:通过 entryoutputmodule 等配置实现模块化打包。loadersplugins 使得资源可以模块化地加载和处理。
  • Vite:基于 ESM 的打包工具,启动速度快,适合现代化前端项目。
  • Rollup:专注于打包库文件,生成更小的文件体积,非常适合编写 npm 库时使用。

6. 路由模块化

  • 动态路由加载:根据用户访问的路由按需加载对应模块,可以减少初次加载时间。
  • 嵌套路由:将不同的页面划分为嵌套路由结构,方便分层控制页面和组件,常见于 Vue RouterReact Router

7. 状态管理模块化

  • Redux:把状态拆分为不同的 slice,每个模块的状态独立,便于管理和维护。
  • Vuex:将状态存储到各个模块中,并提供 gettersmutationsactions,适合 Vue 项目。
  • Context API / Zustand:对 React 项目来说,可以通过 Context API 创建共享的状态模块;Zustand 提供更轻量的解决方案。

8. API 层的模块化

  • 接口封装:将每个功能的接口封装成独立模块,如 userAPI.jsproductAPI.js,便于调用和统一管理。
  • 服务层 (Service):将所有与后端的交互逻辑集中在一个服务层中,和具体的业务模块解耦。

模块化在现代前端开发中不可或缺,通过合理的模块划分和使用,可以显著提升项目的可维护性和扩展性。


相关文章:

《webpack深入浅出系列》

webpack深入浅出系列 ES6模块与CommonJS模块的主要区别 加载时机:ES6模块是编译时输出,即模块在编译阶段就已经确定了依赖关系;而CommonJS模块是运行时才加载,即运行到某个require语句时才加载对应的模块。 (也就是说…...

云服务器使用挂载的数据盘空间(自用)

最近在使用浪潮云服务器的时候遇到系统盘存储空间全部使用完了,而浪潮提供的服务器配置里面还有数据盘空间,但是在使用df -h无法查看到数据盘的相关信息,查找后才发现是因为新开服务器没有对数据盘进行挂载,因此无法使用。在网上找…...

snmp usm OID

在Java中,SNMP(简单网络管理协议)是一种用于网络管理的互联网标准协议。它允许网络管理员从中央位置监控网络设备,如服务器、工作站、路由器、交换机和打印机等。SNMP通过允许这些设备报告关于它们状态的信息,从而帮助…...

数据仓库分层设计概念

数据仓库分层设计是一种结构化方法,用于组织和管理数据仓库中的数据。这种设计方法通过将数据从原始数据逐步转换为满足业务分析需求的结构化数据,提高了数据处理效率、数据质量和一致性。数据仓库分层设计的主要目的包括支持数据的重用、优化性能、提高…...

【HTML】defer 和 async 属性在 script 标签中分别有什么作用?

需要这两个属性的原因? 首先我们要知道的是,浏览器在解析 HTML 的过程中,遇到了 script 元素是不能继续构建 DOM 树的。 它会停止解析构建,首先去下载 js 代码,并且执行 js 的脚本;只有在等到 js 脚本执行…...

扫视扫描路径预测的评估:主观评估数 据库和基于循环神经网络的度量 记录

记录一 随着势头的不断增强,扫视预测逐渐成 为培养视觉注意力的热门研究课题。在扫视预测中,每个模型通常生成一个覆盖一系列注视点的扫描路径,以模拟动态扫视行为。因此, 通常通过计算预测的扫描路径与所有人类扫描 路径之间的相…...

【Java数据结构】优先级队列(堆)

【本节目标】 1. 掌握堆的概念及实现 2. 掌握 PriorityQueue 的使用 一. 优先级队列 1 概念 前面学过队列,队列是一种先进先出 (FIFO) 的数据结构 ,但有些情况下, 操作的数据可能带有优先级,一般出队 列时,可…...

图书个性化推荐系统|基于springBoot的图书个性化推荐系统设计与实现(附项目源码+论文+数据库)

私信或留言即免费送开题报告和任务书(可指定任意题目) 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 本论文主要论述了如何使用JAVA语言开发一个图书个性化推荐系统&…...

通用车牌正则校验

要编写一个正则表达式来包含所有类型的车牌号,我们需要考虑以下几种常见的车牌类型: 1. 普通汽车车牌(蓝牌/黄牌) 规则:1个汉字 1个字母 5个字母或数字示例:京A12345、粤B5678X 2. 新能源车牌&#xf…...

使用 SSH 连接 GitLab 的常见问题及解决方案

使用 SSH 连接 GitLab 的常见问题及解决方案 在使用 SSH 连接到 GitLab 服务器时,可能会遇到类似于以下的错误信息: git192.168.xx.xxx: Permission denied (publickey).这个错误通常表示 SSH 无法验证你的公钥,导致无法访问 GitLab 仓库。…...

泛微E9开发 校验日期型字段是否符合要求

校验日期型字段是否符合要求 1、需求分析及展示效果1.1、需求确认1.2、展示效果 2、实现方法3、扩展知识——js日期相关函数 1、需求分析及展示效果 1.1、需求确认 “填报时间”是一个日期型字段,用户提出需求只能选择每个月的第二个周二,选择其他日期…...

ubuntu安装Vim和net-tools和htop

合并安装,快捷方便 sudo apt update sudo apt install net-tools vim htop在Ubuntu中安装Vim可以通过终端使用以下命令完成: sudo apt update sudo apt install vim这两条命令首先更新了本地的包索引,然后安装了Vim文本编辑器。 安装完成后…...

每天10个js面试题(六)

1、js数组方法? Array.push()此方法是在数组的后面添加新加元素,此方法改变了数组的长度Array.pop()此方法在数组后面删除最后一个元素,并返回数组,此方法改变了数组的长度 Array.shift()此方法在数组后面删除第一个元素&#xf…...

AIGC技术的学习 系列二

文章目录 前言一、AIGC是什么?1.1. 基本概念1.2机器学习分类二、 语言模型2.1. 基于统计的语言模型。2.2. 基于神经网络的语言模型。2.3. 基于预训练机制的的语言模型/大语言模型三、读入数据3.1. 不得不说的Transformer3.2. 影响力3.3. 根据人类反馈的强化学习3.4. 生成式AI3…...

惊艳!AI模型DIAMOND可模拟《反恐精英》,单张RTX 3090就能运行

最近,研究人员开发了一种名为 DIAMOND(Diffusion for World Modelling)的 AI 模型,它能够在神经网络中模拟著名的电脑游戏《反恐精英:全球攻势》(CS:GO)。 这个模型在一张 Nvidia RTX3090显卡上运行,能够达到每秒10帧…...

中波长线天线耦合的一个方法

围绕窗外墙外牵了10米的室外天线。 短波,fm都是很简单,一个夹子直接夹在拉杆天线上面,效果已经很好。 今天偶尔听到中波前面大约510khz的地方有个摩尔斯码。是成都附近机场的NDB。这个平时要在楼顶或者很空旷的地方才能收到。音量比较小&am…...

Java基础(6)

深拷贝和浅拷贝区别了解吗?什么是引用拷贝?关于深拷贝和浅拷贝区别,我这里先给结论:浅拷贝:浅拷贝会在堆上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部…...

[JAVAEE] 线程安全问题

目录 一. 什么是线程安全 二. 线程安全问题产生的原因 三. 线程安全问题的解决 3.1 解决修改操作不是原子性的问题 > 加锁 a. 什么是锁 b. 没有加锁时 c. 加锁时 d. 死锁 e. 避免死锁 3.2 解决内存可见性的问题 > volatile关键字 (易变的, 善变的) a. 不加…...

k8s 集群给用户生成 kubeconfig 文件

在 k8s 集群的 RBAC 里有用到用户、组的概念,但是它又不直接管理这些资源,而是通过外部身份验证机制(Authentication Mechanisms)来管理和定义的,比如证书进行签名时,将其配置为 Subject: O system:master…...

(八)Proteus仿真STM32单片机GPIO驱动数码管

1,参考上篇,将LED点阵屏更换成数码管如下图 2,修改驱动函数,数组seg[14]前10个是0-9数字的编码,后四个是空格,点,横线,下划线 char seg_decode(char num)//数字解码 {const char se…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

条件运算符

C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

EtherNet/IP转DeviceNet协议网关详解

一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...