Webpack5 基本使用 - 1

Webpack 是什么

webpack 的核心目的是打包,即把源代码一个一个的 js 文件,打包汇总为一个总文件 bundle.js
基本配置包括mode指定打包模式,entry指定打包入口,output指定打包输出目录。
另外,由于 webpack默认只能打包js文件,如果需要打包其他类型的文件,就需要配置loader
plugins 用于配置插件,插件可用于执行更广泛的任务,包括打包优化和压缩、或者重新定义环境中的变量。

webpack 和 vite 的区别

Vite是一个轻量的、快速的构建工具。核心是由于浏览器支持 es module,所以在开发环境下避免了打包成 js bunlde,浏览器请求时,按需为浏览器提供es module文件,浏览器获取 ES Module 文件会直接执行,极大的提高了启动速度和热更新速度。

ViteWebpack 的区别:

  • Webpack支持的模块化规范是ES ModulesCommonJSAMD Modules
  • Webpack在开发环境:通过 webpack-dev-server 托管打包好的模块;
  • Webpack 在生产环境通过Webpack构建。
  • Vite支持的模块化规范是 ES Module
  • Vite 在开发环境下直接使用ES Module,托管给浏览器去执行;
  • Vite 在生产环境通过rollup构建

基本配置

初始化项目

npm init -y

使用 webpack

  1. 安装 webpack、webpack-cli
yarn add webpack webpack-cli --save
  1. 在项目下新建配置文件 webpack.config.js
  • 默认依据 webpack.config.js 进行打包
  • 如果使用别的名字,需要在通过 --config 指定配置文件
const path = require('path');

module.exports = {
    mode: 'development', // 指定打包模式 development / production
    output: {},
    module: {},
    plugins: []
};
  1. 打包命令
// 默认使用 webpack.config.js
npx webpack
// 指定配置文件
npx webpack --config webpack.dev.js

在这里插入图片描述

webpack 配置

基本五要素

mode
  • 指定打包方式:development / production
module.exports = {
	mode: 'development' // 开发模式
};
module.exports = {
	mode: 'production' // 生产模式,默认会压缩 js
};
entry
  • 指定打包的入口文件。
单入口
  1. 不配置 entry
  • 默认打包方式是单入口
  • 默认打包入口文件是 /src/index.js
  1. 配置单入口
  • 打包形成一个 chunk,输出一个 bundle 文件
  • 默认打包后的 chunk 名字叫 main.js,想要修改输出文件名称需要在 output 配置
// 单入口:字符串形式
const path = require('path');

module.exports = {
    entry: path.join(__dirname, 'src/index.js') // 指定打包入口文件
};
多入口

配置多入口:对象形式 / 数组形式。

// 例如有两个文件
// /src/index.js
function add(a, b) {
	return a + b;
}

export default add;
// /src/count.js
function count(a, b) {
	return a - b;
}

export default count;
  • 对象形式配置多入口
// 对象形式配置多入口
// 有几个入口文件就形成几个 chunk,输出几个 bundle 文件
// bundle 默认名称是对应的 key
module.exports = {
	entry: {
		index: path.join(__dirname, 'src/index.js'),
		other: path.join(__dirname, 'src/count.js')
	},
	// 指定打包后的代码输出目录
    // output: {
        // filename: 'bundle.[name].[contenthash:8].js',  // [name] 对应 entry 的 key
        // path: path.join(__dirname, 'dist') // 输出的文件目录
    // },
};

在这里插入图片描述

  • 数组形式配置多入口
// 数组形式配置多入口
// 所有文件最终只会形成一个 chunk,输出文件只有一个 bundle 文件
// 会将后面的文件内容打包到第一个文件中,bundle 文件默认名字 main.js
module.exports = {
    entry: [path.join(__dirname, 'src/index.js'), path.join(__dirname, 'src/count.js']
};
// 这时打包后只会输出一个 bundle 文件,会默认将 /src/count.js 打包到 /src/inde.js 中

在这里插入图片描述

// 一般不使用数组形式
// 唯一用处是解决:在开启 HMR 功能后,html 文件的热加载功能失效 的问题

// 开启 HMR 功能后,在 entry 入口添加 html 文件,就能解决 html 文件热加载失效的问题
module.exports = {
	// 注意这里引入了 index.html 后,需要配置 html-loader 才能处理 html 文件
    entry: [path.join(__dirname, 'src/index.js'), path.join(__dirname, 'src/index.html')]
};
output

指定打包后的文件输出目录。

  1. 不配置 output:默认所有打包后的资源都输出到更目录下的 dist 文件夹中
// 默认所有打包后的资源都输出到更目录下的 dist 文件夹中
module.exports = {
	output: {}
};
  1. 配置 output:将打包后的资源都输出到指定目录下
const path = require('path');

// 对象形式
module.exports = {
    output: { 
		// path 配置公共目录,指定所有资源文件的输出目录
		// 如果不配置,默认是输出到 dist 目录
		path: path.resolve(__dirname, '/build'), //  __dirname 是项目根目录的绝对路径
		
		// 指定输出到公共目录下的资源名称(文件名 + 目录)
		// 如果不配置: 默认输出文件名是 main.js, 输出结果是 /build/main.js
		filename: 'js/bundle.js', // 输出为 /build/js/bundle.js
		// filename: 'bundle.[name].js',  // [name] 对应 entry 多入口的 key;
		// filename: 'bundle.[contenthash:8].js',  // 打包代码时加上 hash 戳可以命中缓存
		
		// publicPath: 所有资源引入公共路径的前缀
		// 不配置则 <script src="built.js"></script>
		// 配置则 <script src="/built.js"></script> 会从项目根目录去寻找
		publicPath: '/',
		// 自动清空上次打包的内容
		// 在打包前将 path 整个目录内容清空,再进行打包
		clean:true
    }
};
// 上面的 filename 配置是只输出一个 bundle 文件的情况
// 如果需要输出多个 bundle 文件  这里的 [name] 对应的就是多入口配置的 key
module.exports = {
	entry: {
		build: path.join(__dirname, 'src/index.js'),
		other: path.join(__dirname, 'src/count.js')
	},
    output: { 
		path: path.resolve(__dirname, '/build'),
		filename: 'js/[name].js' // 输出结果 /build/js/build.js 和 /build/js/other.js
    }
};
module

module 里一般用于配置 loader

loader 是用于帮助 webpack 去处理非 js 文件的,因为 webpack 只能打包js文件。

// module 对象套 rules 数组,在数组中配置 loader
module.exports = {
	module: {
		rules: [
		    // 使用单个loader的写法
			{
				test: /\.js$/, // 需要检测的文件,正则表达式
				loader:  'babel-loader', // loader 名称
				options: { 
					// 给 loader 指定一些特殊配置
				}
			},
			{
				test: /\.js$/,
				// 如果一种文件需要被多个 loader 执行,必须要指定先后执行顺序
				// enforce 指定优先执行 pre
				enforce: 'pre',
				exclude: /node_moduls/,
				loader:  'eslint-loader', // loader 名称
				options: {}
			},
			// 需要使用多个 loader
			{
				test: /\.css$/,
			   // 数组写多个 loader,调用方式是从后往前,先调用的需要写到后面
				use: [ 
					'style-loader',
					{
						loader: 'css-loader',
						options: {
							// 指定特殊配置
						}
					}
				]
			}
			// 其它属性
			{
				test: /\.css$/,
			    // 默认是匹配所有目录
				// include 指定要匹配的目录, 多个就用数组形式
			    include: [/asset/, /global/], 
				// exclude 指定要排除的目录
				// 单个就直接写, 目录都用 // 包裹, 多个就用数组形式
			 	exclude: /mode_modules/,
				use: [
					  'style-loader',
					  'css-loader'
				]
			}
		]
	}
};
plugin

plugins 用于配置插件。

插件可用于执行更广泛的任务,包括打包优化、压缩文件、重新定义环境中的变量。

// 首先将需要的插件引入
const HtmlWebpackPlugin = require('html-webpack-plugin');

// plugins 是数组形式配置
module.exports = {
	plugins: [
		// 调用插件
		new HtmlWebpackPlugin()
	]
};

开发环境配置

devServer

用于开发环境下的配置,可修改端口号,自动打开浏览器,设置代理,开启 HMR,方便开发者的开发工作。

  1. 安装 webpack-dev-server
yarn add webpack webpack-dev-server -D
  1. 配置 devServer
const path = require('path');

module.exports = {
    devServer: {
        port: 3000, // 修改端口号
        progress: true,  // 显示打包的进度条
        contentBase: path.join(__dirname, 'dist'),  // 指定运行代码的目录,输出在内存中,看不到
        open: true,  // 自动打开浏览器
        compress: true,  // 启动 gzip 压缩

        // 设置代理
        proxy: {
            // 将本地 /api/xxx 代理到 localhost:3000/api/xxx
            '/api': 'http://localhost:3000',

            // 将本地 /api2/xxx 代理到 localhost:3000/xxx
            '/api2': {
                target: 'http://localhost:3000',
                pathRewrite: {
                    '/api2': ''
                }
            }
        }
    }
};
配置热更新 HMR
  • 自动刷新:整个网页全部刷新,速度较慢;状态会丢失
  • 热更新:新代码生效,网页不刷新,状态不丢失
// 自动刷新 (一般不需要配置自动刷新)
module.export = {
	watch: true// 开启监听,默认为false
	// 注意,开启监听之后,webpack-dev-server 会自动开启刷新浏览器
	// 监听配置
	watchOptions: {
		ignored: /node_modules/// 忽略哪些文件
		// 监听到变化发生后会等 300ms 再去执行动作,防止文件更新太快导致重新编译频率太高 
		aggregateTimeout:300// 默认为 300MS
		// 判断文件是否发生变化是通过不停的去询问系统指定文件有没有变化实现的 
		poll: 1000 // 默认每隔 1000 毫秒询问一次
	}
};
// 开启 HMR
module.export = {
	devServer: {
		hot: true
	}
};
HMR 原理

webpack-dev-server 会创建两个服务:express 服务(提供静态资源) 和 socket 服务(服务器可以主动发送文件到客户端)。

  • express server 负责直接提供静态资源的服务:打包后的资源直接被浏览器请求和解析。
  • HMR Socket Server,是一个 socket 的长连接,建立连接后双方可以通信,服务器可以直接发送文件到客户端。而 http 请求必须要浏览器主动发起请求。

当服务器监听到对应的模块发生变化时,会生成两个文件。 manifest.json 文件记录更新的位置信息等配置信息,update chunk .js 文件记录实际更新的具体内容。通过长连接,可以直接将这两个文件主动发送给浏览器,浏览器拿到两个新的文件后,通过 HMR runtime 机制(webpack 在打包的时候提供),加载这两个文件,并且针对修改的模块进行更新。

resolve

alias

alias 属性配置路径别名。

文件目录隔的比较远就可以用路径别名来代替相对路径。比如存在目录:/src/pages/monitor/container.jsx/src/common/utils/i18n.jscontainer.jsx文件需要引用 i18n.js 文件,通过以下配置后,引入时就可以缩短路径名称 import xxx from '@utils/i18n.js';

module.exports = {
	resolve: {
		alias: {
			'@utils': path.resolve(__dirname, 'src/common/utils')
		}
	}
};
extentions

extentions 配置省略文件路径后缀名。
配置后在引入该文件的时候,可以不用写后缀名。

module.exports = {
	resolve: {
		// 配置省略文件路径后缀名
		// 默认是省略 .js 和 .json
		extensions: ['.js', '.json', '.jsx']
	}
};

modules

告诉 webpack 解析模块应该去找哪个目录。默认是 node_modules

module.exports = {
	resolve: {
		// 告诉 webpack 解析模块是去找哪个目录
		// 默认是 node_modules,但是会在目录中一层一层的找,先找 js 当前目录,找不到就往上一层找,直到找到
		modules: 'node_modules'
	}
};
const path = require('path);
	
module.exports = {
	resolve: {
		// 通过 resove 指定去哪一层找
		// 一般后面还要加上 node_modules,如果指定目录找不到,就再一层一层找
		modules: [path.resolve(__dirname, '../../node_modules'), 'node_modules']
	}
};

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

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

相关文章

R语言批量把数值变量和因子变量的互转

#我们以rms包的lung数据集为例 library(rms) data<-lung #这里有两种方法&#xff0c; #第1是知道需要转化的变量在哪几列&#xff1b; #第2知道需要转化的变量名 str(data) #假设我们想转化inst/status/sex/三个变量的类型 #图1先看看变量类型和处于第几列 str(dat…

【C++11并发】mutex 笔记

简介 在多线程中往往需要访问临界资源&#xff0c;C11为我们提供了mutex等相关类来保护临界资源&#xff0c;保证某一时刻只有一个线程可以访问临界资源。主要包括各种mutex&#xff0c;他们的命名大都是xx_mutex。以及RAII风格的wrapper类&#xff0c;RAII就是一般在构造的时…

VRRP6协议--负载均衡配置

VRRP6负载均衡 VRRP6负载均衡指的是创建多个备份组,多个备份组同时承担数据转发的任务,对于每一个备份组,都有自己的Master和若干Backup设备。 VRRP6负载分担与VRRP6主备备份的基本原理和报文协商过程都是相同的。同样对于每一个VRRP6备份组,都包含一个Master设备和若干Ba…

蓝桥杯备战——7.DS18B20温度传感器

1.分析原理图 通过上图我们可以看到DS18B20通过单总线接到了单片机的P14上。 2.查阅DS18B20使用手册 比赛的时候是会提供DS18B20单总线通讯协议的代码&#xff0c;但是没有提供读取温度数据的代码&#xff0c;所以还是需要我们去查看手册&#xff0c;我只把重要部分截下来了 …

幻兽帕鲁搭建私服,一键更新方法

看着帕鲁这么火&#xff0c;估计更新会变为常态了&#xff0c;如果有自己搭建私服的话&#xff0c;跟着我下面的方法去进行更新吧&#xff01; 如果你还没有自己的私服&#xff0c;快去三五十搞一个吧&#xff0c;只需三五分钟&#xff0c;叫上你的小伙伴一起去搞起来吧 只需3分…

计算机网络体系架构认知--网络协议栈

文章目录 一.计算机网络分层架构各协议层和计算机系统的联系从整体上理解计算机网络通信计算机网络通信的本质 二.Mac地址,IP地址和进程端口号三.局域网通信与跨局域网通信局域网通信跨局域网通信全球互联的通信脉络 四.网络编程概述 一.计算机网络分层架构 实现计算机长距离网…

25考研每日的时间安排

今天要给大家分享一下25考研每日的时间安排。 没有完美的计划&#xff0c;只有合适的计划。 仅供参考 很多人说复习不要只看时长而是要看效率&#xff0c;所以学多长时间不重要&#xff0c;重要的高效率完成任务。 完美的计划 这个计划看起来很完美&#xff0c;从早到晚有学习…

【产品笔记】ESP32及其物联网硬件设备——ESP32智能网关

ESP32是一款适用于许多物联网应用的强大芯片。本文作为学习笔记&#xff0c;记录ESP32及其衍生产品在物联网中的特点&#xff0c;希望对您选择基于ESP32的物联网网关也能有帮助。 什么是ESP32&#xff1f; 在嵌入式系统和物联网应用领域&#xff0c;ESP32是一款广受欢迎的微控…

【JavaMail】Java中发送邮件

文章目录 一、概念二、Java中发送邮件1.导入2.连接SMTP服务器3.创建Session会话4.发送纯文本邮件5.发送带附件邮件 三、封装工具类 一、概念 首先需要明白以下概念&#xff1a; 不需要深入了解他们是怎么工作的&#xff0c;记住关键字即可&#xff1a; SMTP协议&#xff1a;邮…

进程地址空间(Linux)

进程地址空间 一、引入概念1. 程序的地址分布2. 线性地址和物理地址 二、进程地址空间1. 初步认识2. 地址空间和物理内存的联系3. 区域划分4. 拓展——关于“线” 三、进一步理解进程地址空间四、页表总结 一、引入概念 1. 程序的地址分布 测试代码&#xff1a; #include &l…

HttpHeaders 源码中headers成员变量为什么声明为final

源码如下 public class HttpHeaders implements MultiValueMap<String, String>, Serializable {private final Map<String, List<String>> headers;public String getFirst(String headerName) {List<String> headerValues (List)this.headers.get(…

STM32标准库开发—W25Q64详细介绍

W25Q64简介 Flash编程原理都是只能将1写为0&#xff0c;而不能将0写成1.所以在Flash编程之前&#xff0c;必须将对应的块擦除&#xff0c;而擦除的过程就是将所有位都写为1的过程&#xff0c;块内的所有字节变为0xFF.因此可以说&#xff0c;编程是将相应位写0的过程&#xff0c…

【Java发送邮箱】spring boot 发送邮箱

导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId> </dependency> 2.在properties配置邮箱 # 发件人QQ号 spring.mail.username2508575653qq.com # QQ邮箱授权码 sp…

EIGRP实验

实验大纲 一、基本配置 1.构建网络拓扑结构图 2.路由器基本配置 3.配置PC 4.测试连通性 5.保存配置文件 二、配置EIGRP 1.查看路由表 2.配置EIGRP动态路由 3.查看路由器路由表 4.测试网络连通性 5.查看所有路由器的路由协议 6.保存配置文件 三、配置OSPF 1.配置…

vue+draggable+el-upload上传图片拖拽重排方法

vuedraggableel-upload上传图片拖拽重排方法 1.html <el-row><el-col><el-form-item label"添加视频/图片" prop"device_id"><div class"image-upload"><draggable v-model"fileList" update"dataDr…

外包干了2个月,技术反而退步了...

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入广州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

OpenHarmony—类型转换仅支持as T语法

规则&#xff1a;arkts-as-casts 级别&#xff1a;错误 在ArkTS中&#xff0c;as关键字是类型转换的唯一语法&#xff0c;错误的类型转换会导致编译时错误或者运行时抛出ClassCastException异常。ArkTS不支持使用语法进行类型转换。 当需要将primitive类型&#xff08;如num…

2.4.4 代理一个TCP客户端(示例补充)

2.4.4 代理一个TCP客户端 不能直接访问的目标网站&#xff1a; package mainimport ("io""log""net" )// echo is a handler function that simply echoes received data. func echo(conn net.Conn) {defer conn.Close()// Create a buffer to s…

假期刷题打卡--Day15

1、MT1152韩信又生气了 韩信点兵(大于10人)&#xff0c;三个三个一排少1个人&#xff0c;五个五个一排又少1个人&#xff0c;七个七个一排还少1个人。韩信生气了&#xff0c;从别的队伍里调来一个人!这样不管是三个一排五个一排还是七个一排都完美了。问原本最少应该有多少人。…

《从零开始制作消除游戏:基于Web技术的简单教程》

在撰写《从零开始制作消除游戏&#xff1a;基于Web技术的简单教程》这篇博客时&#xff0c;主要的目标是提供一个清晰、逐步的指南&#xff0c;帮助读者从零开始创建自己的消除游戏。 游戏逻辑实现 游戏板设计与初始化&#xff1a;描述如何创建游戏板的数据结构&#xff0c;以…
最新文章