参考链接:
https://blog.youkuaiyun.com/zy1992As/article/details/127774819
https://www.zhihu.com/question/30220505
文章目录
打包
打包的作用
前端打包主要有两个作用:
- 将
多个文件合并成一个文件
, 减少http请求文件的次数 - 进行
编译
, 将ES6、Sass等高级语法进行转换编译,以兼容高版本的浏览器。 压缩
,使用打包工具可以对代码进行压缩,减少代码的体积。打包可以将打包文件的容量进一步压缩,以加快资源的下载和加载速度,从而优化用户体验。缓存静态资源
,通过可以将与当前页面无关的资源文件(如公用的css样式和图片等)进行缓存,使得浏览器无需重复请求,加快页面展示的速度。
它的作用就是通过将代码编译、压缩、合并
等操作,来减少代码体积,减少网络请求,以及方便在服务器上运行。
打包并不是必须的如果你的项目比较小,所使用的语言浏览器完全可以解析,也可以不进行打包。
多个文件合并成一个文件
打包的概念是在nodejs产生之后才产生的:
- 最开始的网页基本是纯静态的html,引入js的时候使用
<script src=''>
进行引入,如果需要引入多个js文件就多次调用<script src=''>
- 造成的问题是,引入的过程繁琐。还要注意引入的先后顺序,如果模块A是依赖于模块B的,那么就必须先引入模块B,再引入模块A,如果引入文件很多这就是一个比较痛苦的过程
- 后来nodejs诞生了,他主张模块化的开发方式,每个js文件会被认为单独一个的模块,不同的js文件之间可以进行相互引用,如果一个html文件需要引入10个js文件,那么可以先选出一个js文件先引入其他9个js文件,最后再将这个js文件以
<script src=''>
的方式引入到html中,这样就解决了之前引用的苦恼 - 与之而来的还有两个问题:
- 浏览器不支持模块化,遇到require、export、import之类的模块语法就会报错
- nodejs是依赖于CommonJS 语法的,但是 CommonJS 在浏览器内并不适用。因为 require() 的返回是
同步
的,意味着有多个依赖的话会阻塞 JS脚本的执行。
- 由此打包工具应运而生:
- 使用打包工具,它会从入口 js 文件开始,把所有的 require() 调用的文件打包合并到
一个文件
,这样就解决了同步加载的问题。同时合并成一个文件,页面只需请求一次,这样能在一定程度上提升页面渲染效率
。 - 使用打包工具,可以进行编译将require、export、import之类的模块语法解析成浏览器能够读懂的语言。
- 使用打包工具,它会从入口 js 文件开始,把所有的 require() 调用的文件打包合并到
编译
打包工具的另一个重要的作用就是进行编译,将浏览器读不懂的语言编译成浏览器(如:(如TypeScript、CoffeeScript、ES6等))可以读懂的语言(即:符合标准的HTML、CSS和JavaScript)。
- 将浏览器无法识别的ES6等高级语法编辑成浏览器可识别的ES5语法。
- 将浏览器无法识别的样式文件
.less .sass
等编译成.css
文件 - 图片合并
压缩
前端打包工具通常采用以下两种压缩方式来减小打包后的文件大小:
1. JS/CSS压缩
。通过将打包生成的 JavaScript 和 CSS 文件进行一些精简和压缩操作,例如删除注释、空格,将变量名、函数名缩短等,从而减小文件的大小。常用的工具有 UglifyJS、clean-css 等。
2. 图片压缩
。对于打包后的图片,可以通过压缩它们的文件大小来减小网页的总体积。在图片不失真的情况下,可以采用无损压缩的方式,常用的工具有 pngquant、jpegtran 等。在图片可以容忍一定程度的失真的情况下,可以采用有损压缩的方式,常用的工具有 Tinypng、Squoosh 等。
这些压缩方式可以显著地减少打包后的文件大小,提高网页的加载速度,改善用户体验。不过,在进行压缩时,需要注意压缩程度的深浅,以免影响文件的执行效率和观感。
缓存静态资源
- CDN加速
CDN加速指的是利用内容分发网络
(CDN)的服务,通过将静态资源
(如图片、样式文件、脚本文件等)分散到全球多个节点上,使得在用户请求这些静态资源时,能够就近获取资源
,从而提高资源的下载速度和页面的加载速度,降低延迟和带宽占用。
在前端打包中,可以通过指定打包文件中的静态资源路径为CDN的域名
,将这些资源上传到CDN上,使其在全球各地部署的CDN节点中都可以缓存这些资源,用户访问时可以尽可能快地获取资源。为了保证资源的一致性,通常在资源变更时也需要保证CDN缓存的资源已经被刷新。使用CDN加速可以大幅提高用户访问网站的体验,降低了页面的加载时间和资源请求的延迟,特别对于较大的静态资源文件(如图片、视频等)的加载效果最为明显。
前端的打包工具
前端常用的打包工具有:
Webpack
:最流行的前端打包工具,提供了强大的 module bundling、code splitting、lazy loading、minification、tree shaking 等功能。Parcel
:另一种前端打包工具,适用于简单的项目,无需配置即可使用。Rollup
:专注于将 JavaScript 模块打包成一个单独的、优化的文件。适用于打包库文件。Grunt
:是一种任务运行器,可以自动执行重复性的工作,如压缩、编译、打包等任务。Gulp
:又称为构建工具,通过编写 JavaScript 代码,灵活地自定义构建流程,最大程度地简化前端工作流程。(构建工具指的是提供一个项目的框架,基于这个框架可以直接开发项目)
Webpack
Webpack 是一个现代化的静态模块打包器(module bundler),提供了丰富的功能,可以处理 JavaScript、CSS、图片等类型的资源,并将它们打包成适合部署到生产环境的优化的静态资源。
Webpack 的主要功能包括以下几个方面:
模块化
:Webpack 支持多种模块化规范(如 CommonJS、AMD 和 ES6 等),同时能够将代码按照依赖关系划分成多个模块
。Webpack 支持将各种类型的文件(如 JavaScript、CSS、图片等)通过加载器(Loader
)转换成模块
。打包
:Webpack 能够将多个模块打包成一个或多个 bundle
,支持 tree-shaking 机制,提取公共模块等功能,可以优化文件体积和加载速度。Web 开发服务器
:Webpack 提供了内置的开发服务器,支持热更新(Hot Module Replacement)等功能,可以提高开发效率。插件系统
:Webpack 提供了丰富的插件系统
,通过使用插件,可以完成代码压缩、提取 CSS 等特定的优化需求。
Webpack 是一个功能强大的静态模块打包器,能够提高 Web 应用程序的开发效率和运行性能,被广泛应用于前端开发领域。
Rollup
Rollup 是一个类似 Webpack 的 JavaScript 模块打包工具,它专注于将 JavaScript 库打包成一个单独的、优化的文件。
- 与 Webpack 的区别在于:
Rollup 仅仅支持 ES6 模块规范
不支持动态导入等高级特性
,因此它对于打包纯 JavaScript 模块的工具包和库来说是更加合适的
- 与 Webpack 的相同点:
- 与 Webpack 有些类似,它同样使用配置文件来进行打包配置,
- 都支持引用npm包中的模块以及编写插件等功能
- 都能自定义多种打包输出格式。
- Rollup与 Webpack相比 的优势在于:
它能够更加精简地打包 JavaScript 模块,去掉无用代码,生成更小的包,也就是所谓的 tree-shaking 操作,提高浏览器的执行效率以及减少资源的传输时间。
Rollup 适用于开发开源库或框架等需要打包发布的项目
,而如果是开发单页面应用等独立的 Web 应用,则使用 Webpack 更为合适。
打包工具搭建项目的功能
大多数打包工具不仅仅只有打包功能,还有编译、模块解析等功能,可以用来搭建项目框架,可以提供类似于 vue脚手架、create-react-app
的功能。
webpack
- Webpack可以搭建项目。Webpack是一个流行的
构建工具
,可以用于打包JavaScript、CSS和其他前端资源,可以支持从多个不同源的模块构建应用程序。 - Webpack也可以提供类似脚手架的功能。Webpack官方提供了一些预设配置,例如可以使用
webpack-cli
工具来快速创建一个新项目,其中可以选择使用哪一种预设配置,例如React、Vue、TypeScript
等等。同时,也有很多第三方脚手架工具
是基于webpack开发的,例如create-react-app、vue-cli
等等。 - webpack不仅仅只是一个打包工具,它还可以在项目运行的时候编译代码,同时利用webpack的配置项,loader和插件,也可以为项目配置编译工具测试工具等。
- webpack有自己的开发服务器。在开发环境,Webpack Dev Server 可以提供一个本地服务器,使得开发者能够通过浏览器访问正在开发的项目,并在代码发生变化时自动重新编译和刷新页面内容。
( 即我们常用的 create-react-app
命令就是基于webpack实现的:
create-react-app底层使用了Webpack作为构建工具。在执行create-react-app
命令时,它会在幕后自动帮您创建一个新的React项目,并对Webpack进行了配置,包括入口文件、输出文件、webpack-dev-server
等等。同时,它还预置了一些Webpack插件,例如webpack-hot-middleware
、html-webpack-plugin
等等,来提高开发效率和构建的性能。但是,create-react-app并未暴露Webpack的所有配置选项,以保持默认配置的简洁性,对于一些复杂的应用场景需要进行配置时,可以通过eject
命令将配置文件暴露出来以进行定制。总之,create-react-app是一个快速构建React应用程序的脚手架工具,底层使用了Webpack作为构建工具来构建和打包React项目。)
- 使用Webpack构建的优点是灵活性高、可以支持各种各样的场景和需求,拥有大量的插件和Loader可供选择。
Parcel
Parcel也可以用来搭建项目。但是Parcel主要是在打包方面进行优化。
- 它也提供了一些开箱即用的功能可以快速搭建项目,例如支持ES6模块、TypeScript、React和Vue等等。
- 在创建项目时,你可以选择不同的模版,并指定不同类型的项目,例如Web应用或Node.js应用,从而能够快速搭建起一个基本的项目骨架。
- 使用
Parcel
搭建项目的缺点是的可扩展性和自定义性较低,因此对于一些特定的需求可能无法提供足够的支持 - Parcel更适合于快速搭建一些
简单的Web应用程序
,但对于一些复杂的项目来说,建议使用其他更加强大和灵活的构建工具。
Rollup
Rollup可以用来搭建项目。
- rollup是为JavaScript库和组件而设计的,因此比较适合于
搭建一些小型项目和库
。 - 将Rollup用于项目搭建时,需要设置好项目的入口和出口文件路径,并根据需要配置一些插件和设置。
- Rollup 自身并没有内建的开发服务器,但在开发阶段,可以通过配置文件加上监听模式 (–watch) 来实现类似的实时编译。开发者通常会结合其他工具(如
rollup-plugin-serve
或其他开发服务器)来提供本地运行和实时刷新功能。
Grunt
Grunt是一个自动化任务运行器,虽然它可以用来执行很多构建和打包任务,但它并不是一个专门用于搭建项目的工具。
- Grunt主要用于构建Web应用程序的自动化任务,例如编译
LESS和SASS文件
、压缩JavaScript和图片文件等等,还可以用于运行测试和处理代码质量。 - 对于项目搭建来说,Grunt相对于其他工具而言更加灵活,而灵活性带来的是更复杂的配置和设置。
Gulp
Gulp是一个自动化构建工具,可以用于搭建项目。
- 在项目搭建时,您可以使用Gulp的自动化任务来构建您的应用程序,包括创建HTML、CSS和JavaScript文件,复制文件和文件夹、启动Web服务器等等。
- 通过Gulp的自动化工具,可以大大提高您的开发效率,同时还能够减少手动构建任务所需的时间和精力。因此,对于那些希望利用
自动化工具来构建和打包应用程序
的人来说,Gulp是一个非常好的选择。
vite
Vite也是一个项目的构建和开发工具。Vite 是基于 Rollup 进行了封装和扩展的构建工具。
Vite 是由尤雨溪开发的一款基于浏览器原生 ES 模块
开发的前端工具,可以提供类似 Vue CLI
和 Create React App
的开发体验,但是却有着更快的速度和更低的内存占用。
Vite 的主要特点包括:
快速的冷启动
:在开发环境中,通过利用浏览器原生的 ES 模块特性,以及 Vite 本身的模块分析和缓存技术,可以实现几乎即时的冷启动和热更新
功能。真正的按需编译
:在开发模式下,Vite 不会像 Webpack 和 Rollup 那样对所有的模块都进行打包,而是只对修改过的代码进行编译,可以大幅提高开发效率。支持多种前端框架
:目前 Vite 支持 Vue、React、Preact、Svelte 和 Lit Element 等多种前端框架进行开发。内建静态文件服务
:Vite 内置了基于 Koa 的开发服务器,可与任何服务器框架配合使用。丰富的插件生态
:Vite 基于 Rollup
重新实现了现代化的工具链,它的插件机制很灵活,可以与大量的第三方插件配合使用。
总体来说,它的特点是快速的构建速度
和实时的热更新
能力,同时也能让 Web 应用程序在运行时拥有更好的性能和可扩展性。
补充:冷启动
冷启动通常有两种不同的含义,具体取决于上下文:
- 在开发中,冷启动通常指
第一次启动一个应用程序或者项目时所需的时间
,这包括加载开发环境、构建项目、启动服务器等等。例如,在运行一个本地服务器时,第一次启动通常需要更长的时间,因为需要构建并加载所有必需的文件和资源。 - 在网络中,冷启动通常指
第一次访问一个Web应用程序时所需的时间
,也就是第一次加载并显示应用程序所需的时间。这包括下载HTML、CSS、JavaScript、图像和其他必需的资源
,以及建立与服务器之间的连接。由于第一次请求
需要加载和处理这些资源,通常需要更长的时间,从而导致用户等待时间更长。
补充:热部署
- 热部署通常指
在应用程序运行时
通过重新加载实现代码和资源更新
的过程,而无需重新启动整个应用程序。换句话说,热部署可以在运行时
更新应用程序代码、样式和其他内容,以实现最新更改的即时反馈,而无需中断应用程序的运行。就是我们在平时开发时保存代码就可以看到最新的内容,无需重新启动。 - 在Web开发中,热部署通常通过WebSocket或者HTTP请求实现,可以使浏览器和服务器之间的通信更加高效。
- 一些流行的前端框架和工具,例如React、Vue、Webpack、Parcel等等,都提供了热部署功能,从而使得开发者能够在进行代码更改时无需手动刷新页面即可立即查看更改的结果。
vite和rollup的区别
Vite 和 Rollup 都可以作为项目的构建工具,二者在某些方面有一些相似之处,但在其他方面又有很大的差异。
- 相同点:
- 构建安装和配置都比较简单。
- 两者都可以通过 Tree-shaking 操作去掉无用的代码。
- 都支持以不同的格式导出代码。
- 不同点:
- Rollup 专注于构建
JavaScript 库
,而 Vite 面向的是构建单页面应用
程序。 - Rollup 使用默认的配置项即可构建,而 Vite 需要在配置文件中自定义开发、构建和部署选项(vite.config.js)。
- Vite 提供了一种基于实时预编译和热重载的
开发服务器
,而 Rollup 没有内置的开发服务器。 - 在处理依赖关系时,Rollup 采用
静态分析
的方式,Vite 使用动态处理
的方式。这意味着 Rollup 对于导出的隐式依赖性更加敏感,但需要确保所有的依赖都明确指定,而 Vite 可以处理显式和隐式依赖,不必手动指定。 - Rollup合其他工具(如 rollup-plugin-serve 或其他开发服务器)来提供本地运行和实时刷新功能;Vite 则在本地开发阶段利用了浏览器对 ES 模块(ESM)的原生支持,通过服务端按需编译模块,实现了几乎
瞬时的启动速度和高速的热更新
。
vite的底层原理和rollup的关系
Vite 的底层是借助了 Rollup
进行模块化打包,但它并不是使用 Rollup 作为全面的构建工具
。
具体来说:
Vite 在开发阶段不会像 Rollup 一样对所有模块进行打包
,而是利用了浏览器的 ES 模块加载特性和服务端渲染的方式,通过动态服务端编译实现了近乎即时的模块热更新。- Vite 每次
只对修改的代码进行编译
,而不是重新编译整个应用程序,因此可以在几乎没做任何优化的情况下实现即时的热更新功能。
因此,可以说 Vite 的底层使用了 Rollup,但 Vite 对于开发体验和打包策略等方面做了一些特别的优化。
补:构建工具
构建工具是在软件开发过程中,用来自动化处理和管理代码的工具。它们的目标是简化、加速开发过程,减少人为错误,并确保开发结果的一致性和可重复性。
构建工具的功能:
- 编译:对于需要编译的语言(如Java、C、C++等),构建工具可以完成编译的过程,将源代码转化为可运行的二进制文件。
- 测试:构建工具可以自动执行项目中的自动化测试,帮助开发者快速发现代码中的错误。
- 打包:将编译后的代码和其依赖的库文件等打包成为一个可分发的文件,例如jar、war、ear或者是exe等。
- 安装:将打包后的文件安装到系统的指定位置。
- 部署:在生产环境或者测试环境将软件部署起来运行。
- 文档生成:根据代码和相应的注释等信息,自动生成软件文档。
- 代码决议度测量:通过自动化的工具测量代码的质量,例如FindBugs、CheckStyle、PMD等。
构架工具是一个统称
他包括但不限于编译工具、测试工具、打包工具和部署工具。
常见的构建工具:
- Webpack: 是一个静态模块打包工具,用于处理JavaScript、CSS、HTML等文件,可以处理和打包各种资源和模块,非常适合单页应用程序的开发。
Webpack 不仅仅在项目构建(如生产环境打包)时发挥作用,还在本地开发阶段起到关键作用:- 编译模块:
- ES6转译:Webpack 可以配合 Babel Loader 将使用 ES6(甚至更高版本)特性的 JavaScript 代码编译为大多数现代浏览器都能识别的 ES5 代码。
- 类型检查:通过 TypeScript Loader,Webpack 可以编译 TypeScript 代码,执行类型检查并转换为 JavaScript。
- 样式预处理器:对于 Sass、Less 或 Stylus 等样式预处理器,Webpack 可以通过对应的 Loader 将它们编译为浏览器能识别的 CSS 格式。
- 资源转换:图片、字体等静态资源也可以通过相应的 Loader 进行编译或压缩处理。
- Tree Shaking:在编译过程中,Webpack 还可以执行 Tree Shaking 优化,移除未使用的代码片段,进一步缩小输出文件体积。
- 处理模块的依赖关系:对于第三方库,可以直接使用库名引入,这是因为Webpack 会按照一定的解析策略去寻找这个模块
- 首先,它会在当前文件的同级目录查找是否有package这个文件或者文件夹。如果有,就会直接引用。如果没有,它会去node_modules目录下查找package这个文件夹,如果找到了就会引入里面的模块。
- 如果在当前目录的node_modules下没有找到,那么就会沿着目录树,向上级目录查找,直到找到为止。
- 如果一直找到了根目录还没有找到相应的模块,Node.js 就会认为这个模块不存在,然后抛出一个错误。
- 模块捆绑:在开发过程中,Webpack 会监视项目源代码的变化,当检测到文件改动时,它会重新编译相关模块
- 热模块替换:在开发环境中,Webpack Dev Server 可以启用热模块替换功能,即修改后的模块无需刷新整个页面就能实时反映到浏览器上
- 本地服务器:Webpack Dev Server 可以作为一个轻量级的本地服务器运行,它能为前端项目提供静态资源服务,使得开发者可以通过 localhost 地址直接在浏览器预览和调试项目。
- 编译模块:
- Babel: 是一个JavaScript编译器,用于将最新版本的JavaScript代码转换为旧版本,以便在不支持最新语言特性的环境中运行。
- Gulp: 是一个基于流的自动化构建工具,可以自动化处理和重复的任务,如压缩、测试、重载等。
- Grunt: 也是一种JavaScript任务运行器,它的作用跟Gulp类似,但是它的工作方式更加配置驱动,适合于需要执行大量不同类型任务的大型项目。