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

前端开发中的webpack打包工具

前端技术发展迅猛,各种可以提高开发效率的新思想和框架层出不穷,但是它们都有一个共同点,即源代码无法直接运行,必须通过转换后才可以正常运行。webpack是目前主流的打包模块化JavaScript的工具之一。

本章主要涉及的知识点有: 

l 什么是webpack

l webpack的作用

l webpack的配置

l webpack-dev-server

以前,一个网站可能只是由几个HTML和CSS文件构成,在某些情况下可能还有一个或几个JavaScript文件。但随着前端技术的发展,这一切都被改变。

整个开发社区一直致力于改善用户和开发人员在使用和构建JavaScript/Web应用程序方面的整体体验。因此,在项目中引入了许多新的库和框架。

一些设计模式也随着时间的推移而演变,为开发人员提供了一种更好、更强大但非常简单的编写复杂JavaScript应用程序的方法。网站不再只是一个包含几个文件的程序包,随着JavaScript模块的引入,编写封装的小块代码成为一种新趋势。但随之而来的是网站代码的体积越来越大,而且JavaScript版本不断升级,新的API层出不穷,在开发人员编写的代码类型和浏览器能够理解的代码类型方面也存在巨大差异。开发人员必须使用大量被称为polyfills的辅助代码,以确保浏览器能够解析其中的代码。

为了解决这些问题,开发了一系列构建工具,它们各有优缺点。由于前端工程师很熟悉JavaScript,Node.js又可以满足所有构建需求,因此大多数构建工具都是用Node.js开发的。

1. Grunt

Grunt是一个任务执行者,它有大量现成的插件封装了常见的任务,也能管理任务之间的依赖关系,自动化地执行依赖的任务。每个任务的具体执行代码和依赖关系写在配置文件Gruntfile.js里,代码如下:

module.exports = function(grunt) {grunt.initConfig({uglify: {app_task: {files: {'build/app.min.js': ['lib/index.js', 'lib/test.js']}}}, watch: {another: {files: ['lib/*.js'],}}});grunt.loadNpmTasks('grunt-contrib-uglify');grunt.loadNpmTasks('grunt-contrib-watch');grunt.registerTask('dev', ['uglify','watch']);
};

其中,uglify和watch都是插件,分别用于压缩和监听自动刷新,grunt.loadNpmTasks用于加载插件;grunt.registerTask用于执行任务。在项目根目录下执行命令grunt dev,就会启动JavaScript文件压缩和自动刷新功能。

Grunt的优点是灵活,它可以执行自定义的任务,并且有大量的可复用的插件封装好了常见的构建任务。

Grunt的缺点是集成度不高,要写很多配置后才可以用,无法做到开箱即用。

2. Gulp

Gulp是一个基于流的自动化构建工具,除了可以管理和执行任务之外,还支持监听文件、读写文件。Gulp被设计得非常简单,只通过5种方法就可以支持几乎所有的构建场景:gulp.task用于注册一个任务,gulp.run用于执行任务,gulp.watch用于监听文件的变化,gulp.src用于读取文件,gulp.dest用于写文件。

Gulp的最大特点是引入了流的概念,同时提供了一系列常用的插件去处理流,流可以在插件之间传递。Gulp的示例代码如下:

01	var gulp = require('gulp'); 
02	var jshint = require('gulp-jshint');
03	var sass = require('gulp-sass');
04	var concat = require('gulp-concat');
05	var uglify = require('gulp-uglify');
06	gulp.task('sass', function() {
07	  gulp.src('./scss/*.scss')
08	    .pipe(sass())
09	    .pipe(gulp.dest('./css'));
10	});
11	gulp.task('scripts', function() {
12	  gulp.src('./js/*.js')
13	    .pipe(concat('all.js'))
14	    .pipe(uglify())
15	    .pipe(gulp.dest('./dist'));
16	});
17	gulp.task('watch', function(){
18	  gulp.watch('./scss/*.scss', ['sass']);
19	  gulp.watch('./js/*.js', ['scripts']);    
20	});

代码解析:

  1. 第01~05行引入Gulp和相关插件。
  2. 第06~10行通过gulp.task('sass', function() {}编译SCSS任务。其中第07行通过gulp.src读取文件,第08行通过pipe管道加载插件,第09行输出CSS文件。
  3. 第11~16行通过gulp.task('scripts', function() {}合并压缩JavaScript文件。
  4. 第17~20行通过gulp.task('watch', function() {}监听文件的变化。

Gulp的优点是好用又不失灵活,既可以单独完成构建,也可以和其他工具搭配使用。其缺点和Grunt类似,集成度不高,要写很多配置后才可以用,无法做到开箱即用。

可以将Gulp看作Grunt的加强版。相对于Grunt,Gulp增加了监听文件、读写文件、流式处理的功能。

3. webpack

webpack是一个打包模块化JavaScript的工具,在webpack里一切文件皆模块,通过Loader转换文件,通过Plugin注入钩子,最后输出由多个模块组合成的文件。webpack专注于构建模块化项目。

webpack具有很大的灵活性,通常在项目中编写webpack.config.js配置处理文件的方式,示例代码如下:

module.exports = {entry: './app.js',output: {filename: 'bundle.js'}
}

其中,entry是所有模块的入口,webpack从入口开始递归解析出所有依赖的模块;output将入口所依赖的所有模块打包成一个bundle.js文件并输出。

webpack专注于处理模块化的项目。通过webpack,现在使用React、Vue、Angular等搭建的项目能做到开箱即用、一步到位,并且可以通过Plugin扩展很多功能。webpack社区庞大而活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展。

简单来说,webpack会遍历项目中的所有文件,如JavaScript、CSS、SCSS、图片、模板等,并创建它们的依赖关系图,该依赖关系图用于描述各个模块之间的依赖关系。根据依赖关系图,对项目中的各模块进行组合和打包,形成一个bundle.js文件,在这个文件中可以很容易地插入HTML文件并用于应用程序。

webpack在打包的同时还会对各文件进行编译。把浏览器不能识别的语法(例如ES 6的语法、Node.js的模块化、Sass)编译成CSS,将TypeScript编译成JavaScript等,转换成浏览器能够识别的语法。

webpack在打包时可以根据配置对代码进行压缩、优化,以减小网络传输过程中文件的体积。最典型的做法是把所有变量名都精简为一个字母,所有的换行符和缩进都去掉。如图8.1所示是webpack打包后的JS文件。

webpack的功能还有很多,例如代码分割、自动刷新等。代码分割就是提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。自动刷新是指监听本地源代码的变化,自动重新构建、刷新浏览器。

webpack官方网站首页中的一张图片形象地展示了webpack的作用,如图8.2所示。

目前,随着单页应用的流行,大多数团队在开发新项目时会采用“模块化+新语言+新框架"的方式。webpack可以为这些模块化项目提供一站式的解决方案、良好的生态链和维护团队,从而提供良好的开发体验并保证项目质量。

webpack的配置项很多,具体可以参考官方网站文档(https://webpack.js.org/concepts/)。本节介绍几个重要且常用的配置项。

在对webpack进行配置之前,首先要安装webpack。在终端输入如下代码:

npm install webpack webpack-cli --save-dev

webpack-cli是一个用来在命令行中运行webpack的工具,可以用来处理命令行参数。

通常在项目根目录下增加webpack.config.js文件,在该文件中编写代码进行webpack的配置。例如,在webpack.config.js文件中添加以下代码:

01	const path = require('path');
02	const HtmlWebpackPlugin = require('html-webpack-plugin');
03	
04	module.exports = {
05	  entry:'./src/index.js',
06	  output:{
07	    path: path.join(__dirname, '/dist'),
08	    filename: 'bundle.js'
09	  },
10	  module: {
11	    rules: [
12	      {
13	        test: /\.(js|jsx)$/, 
14	        exclude: /node_modules/,
15	        use: {
16	          loader: 'babel-loader'
17	        }
18	      }
19	    ]
20	  }, 
21	  plugins: [
22	    new HtmlWebpackPlugin({
23	      template: './src/index.html'
24	    })
25	  ]
26	}

代码解析:

  1. 第01行引入Node.js内置模块path,用于获取文件路径并更改文件的位置。
  2. 第02行引入插件html-webpack-plugin,用于生成一个HTML文件,这个HTML文件用于引用打包后的JavaScript文件。因为JavaScript文件必须放到HTML文件中才可以在浏览器中执行。
  3. 从第04行开始定义module.exports对象,其中包含一些属性,例如entry、output、module、plugins等。
  4. 第05行的entry属性用于指定webpack应该从哪个文件开始,以便创建内部依赖关系图。这里是src下的index.js文件。
  5. 第06行的output属性指定应该在哪里生成打包后的文件以及打包后的文件的名称。output.path用于指定文件存储位置,output.filename用于指定文件名称。
  6. 第10~20行的module指定需要哪些loader。loader指定webpack应该怎样处理特定类型的文件。注意,webpack默认只理解JavaScript和JSON类型的文件,对于项目中使用的其他类型文件或语言,例如PNG、JPG、GIF格式的图片文件或者SCSS、LESS文件,需要在这里加载相应的loader插件进行处理。此处用正则表达式匹配所有后缀是.js或.jsx的文件,且排除/node_modules/下的文件,使用babel-loader对这些文件进行编译处理。还有很多别的loader插件,例如处理CSS和SCSS文件的style-loader、css-loader、sass-loader,处理图片的url-loader等。
  7. 第21~25行的plugins是插件属性,用于扩展webpack的功能。这里使用html-webpack-plugin插件将src/index.html作为模板文件,所有打包后的文件都将自动放入该HTML文件中。html-webpack-plugin插件还有更多的配置,具体可以参考官方文档。插件还有mini-css-extract-plugin,用于将CSS提取到单独的文件中,即为每个包含CSS的JavaScript文件创建一个CSS文件,terser-webpack-plugin用于压缩JavaScript文件。

最后,要处理ES 6代码。ES 6是2015年发布的JavaScript语言标准,它引入了新的语法和API,例如class、let、for...of、promise等,但是这些JavaScript新特性只被最新版本的浏览器支持。低版本浏览器并不支持。因此,低版本浏览器需要一个转换工具,把ES 6代码转换成浏览器能识别的代码。Babel就是这样的一个工具,它是JavaScript语法的编译器。

Babel工具在使用之前需要先进行配置。

首先在项目根目录下创建一个.babelrc文件,它是一个JSON格式的文件,用来保存Babel工具的配置。webpack中的babel-loader加载后会从项目根目录下的.babelrc文件中读取配置。

在.babelrc配置文件中,主要是对预设(presets)和插件(plugins)进行配置。.babelrc配置文件一般如下:

{"presets": ["es2015","react"]
}

其中,presets属性告诉Babel要转换的源代码使用了哪些新的语法特性,它是一组Plugins的集合。上面的代码表示先用React转换,然后用ES 2015(ES 6)转换。

以上配置中用到的loader或plugins,如果不是webpack内置的,那么在使用前需要先安装,例如编译CSS和SCSS文件的loader,使用npm install css-loader style-loader sass-loader --save-dev进行安装。

webpack配置好以后,可以在package.json文件中增加如下代码:

"scripts": {"dev": "webpack --config webpack.config.js"
},

在scripts属性中,npm允许通过名称引用本地安装的Node.js包。上面的代码表示在开发dev模式下运行webpack,在终端命令行中输入npm run dev时执行webpack --config webpack.config.js。

在实际项目中,需要根据特定情况使用不同的配置文件,例如,开发时执行webpack.dev.config.js;当需要打包部署到生产环境时,执行webpack.prod.config.js。这些webpack文件的配置项也要根据用途进行不同的配置,例如开发环境时需要配置webpack-dev-server,但是生产环境时需要配置CSS、JS压缩等。

本节选自《React.js+Node.js+MongoDB企业级全栈开发实践》,获出版社和作者授权共享。

相关文章:

前端开发中的webpack打包工具

前端技术发展迅猛,各种可以提高开发效率的新思想和框架层出不穷,但是它们都有一个共同点,即源代码无法直接运行,必须通过转换后才可以正常运行。webpack是目前主流的打包模块化JavaScript的工具之一。 本章主要涉及的知识点有&am…...

Mybatis配置-数据库厂商标识(databaseIdProvider)

MyBatis可以根据数据库供应商执行不同的语句。多数据库供应商支持是基于映射语句的databaseId属性。MyBatis将加载所有没有databaseId属性或具有与当前数据库匹配的databaseId属性的语句。如果找到具有和不具有databaseId的相同语句,则后者将被丢弃。要启用多供应商…...

【Java】使用递归的方法获取层级关系数据demo

使用递归来完善各种业务数据的层级关系的获取 引言:在Java开发中,我们通常会遇到层层递进的关系型数据的获取问题,有时是树状解构,或金字塔结构,怎么描述都行,错综复杂的关系在程序中还是可以理清的。 这…...

工业6轴机械臂运动学逆解(解析解)

工业6轴机械臂运动学逆解(解析解) 通常工业机械臂采用6旋转轴串连的形式,保证了灵活性,但为其运动学逆解(即已知机械臂末端的位姿 P P P,求机械臂各个旋转轴的旋转角)带来了较大的困难&#xff…...

管理类联考——数学——真题篇——按题型分类——充分性判断题——蒙猜A/B

老规矩,看目录,平均3-5题 文章目录 A/B2023真题(2023-19)-A-选项特点:两个等号;-判断需联立的难易:难,看着感觉需要联立,所以判断联立需要有理论支撑,不然还…...

为什么GRU和LSTM能够缓解梯度消失或梯度爆炸问题?

1、什么是梯度消失(gradient vanishing)? 参数更新过小,在每次更新时几乎不会移动,导致模型无法学习。 2、什么是梯度爆炸(gradient exploding)? 参数更新过小大,破坏了…...

【力扣100】146.LRU缓存

添加链接描述 class DLinkedNode:def __init__(self, key0, value0):self.key keyself.value valueself.prev Noneself.next Noneclass LRUCache:def __init__(self, capacity: int):self.cache dict()# 使用伪头部和伪尾部节点 self.head DLinkedNode()self.tail D…...

【Vue中给输入框加入js验证_blur失去焦点进行校验】

【Vue中给输入框加入js验证_blur失去焦点进行校验】 通俗一点就是给输入框加个光标离开当前文本输入框时&#xff0c;然后对当前文本框内容进行校验判断 具体如下&#xff1a; 1.先给文本框加属性 blur“validatePhoneNumber” <el-input v-model“entity.telephone” blur…...

vue3项目引入电子签名(可横屏竖屏)

实现效果&#xff1a;&#xff08;左边横屏&#xff0c;右边竖屏&#xff09; 前言&#xff1a;【使用开源项目smooth-signature 实现签名的功能。Gitee 地址是 &#xff1a;GitHub - linjc/smooth-signature: H5带笔锋手写签名&#xff0c;支持PC端和移动端&#xff0c;任何前…...

mysql中count(*)、count(1)、count(主键)、count(字段)的区别

文章目录 count函数的语义count(主键)count(1)count(*)count(字段)替代方案explain或者show table status中间表或者其他数据库计数 以下分析都是基于 select count(?) from table 这个语句来分析&#xff0c;不带过滤条件。 count函数的语义 count() 是一个聚合函数&#x…...

Nginx生成自签名证书从而添加域名的HTTPS访问

数字证书 ## 原理参考 https://mysticaldream.github.io/2023/05/certificate/## https://blog.csdn.net/m0_52440465/article/details/130713591 简介 数字证书是由证书颁发机构(CA)签名并颁发的电子文件,用于建立网络连接的身份认证和加密通信。SSL 证书是数字证书的一种。…...

无框架Java转go语言写http与tcp请求

项目地址 https://github.com/cmdch2017/http_tcpServer 项目结构 如何快速上手 http篇 1、controller包就相当于RestController&#xff0c;这里返回了一个Person对象&#xff0c;当你需要新建一个接口时&#xff0c;再新写一个func仿照下面的方法就行了 package control…...

【Git】Git基本操作

文章目录 Git 是什么Git 的优点Git 安装Linux UbuntuLinux CentOsWindows Git 基本操作1. 创建 Git 本地仓库2. 配置 Git3. Git工作区、暂存区和版本库4. 添加文件5. 查看 .git 文件6. 修改文件7. 版本回退 Git 是什么 Git是一个免费的、开源的分布式版本控制系统&#xff0c;…...

JavaSE学习笔记 Day20

JavaSE学习笔记 Day20 个人整理非商业用途&#xff0c;欢迎探讨与指正&#xff01;&#xff01; 上一篇 文章目录 JavaSE学习笔记 Day20十七、数据结构与算法17.1算法17.1.1冒泡排序17.1.2选择排序17.1.3插入排序17.1.4三个排序的区别 17.2顺序表17.2.1顺序表代码实现17.2.2顺…...

【蓝桥杯选拔赛真题52】python空调模式 第十四届青少年组蓝桥杯python 选拔赛比赛真题解析

目录 python空调模式 一、题目要求 1、编程实现 2、输入输出...

Android Studio: 解决Gradle sync failed 错误

文章目录 1. 前言2. 错误情况3. 解决办法3.1 获取gradle下载地址3.2 获取gradle存放目录3.3 替换并删除临时文件3.4 触发Try Again 4. 执行成功 1. 前言 今天调试项目&#xff0c;发现新装的AS&#xff0c;在下载gradle的过程中&#xff0c;一直显示连接失败&#xff0c;Gradl…...

【手写数据库】从零开始手写数据库内核,行列混合存储模型,学习大纲成型了

目录 ​专栏内容: 参天引擎内核架构 本专栏一起来聊聊参天引擎内核架构,以及如何实现多机的数据库节点的多读多写,与传统主备,MPP的区别,技术难点的分析,数据元数据同步,多主节点的情况下对故障容灾的支持。 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以…...

机器学习中的一些经典理论定理

PAC学习理论 当使用机器学习方法来解决某个特定问题时&#xff0c;通常靠经验或者多次试验来选择合适的模型、训练样本数量以及学习算法收敛的速度等。但是经验判断或多次试验往往成本比较高&#xff0c;也不太可靠&#xff0c;因此希望有一套理论能够分析问题难度、计算模型能…...

c语言:成本100元,40%的利润怎么计算|练习题

一、利润的计算公式&#xff1a; 利润售价-成本 售价成本/(1-利润率) 二、用c语言代码表示为&#xff1a; 如图&#xff1a; 三、计算源代码【带注释】 #include <stdio.h> int main() { float cost;//成本变量 int prof_rate;//利润率变量 float price;//…...

【Python必做100题】之第二十二题(复制列表)

题目&#xff1a;将一个列表的数据复制到另一个列表中 重点&#xff1a;确保复制到位要导入copy方法进行深度复制 代码如下&#xff1a; #将一个列表的数据复制到另一个列表中 import copy list [1,2,3,4] print(list) list1 copy.copy(list) list[0] 30 print(list) pri…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

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

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

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...