前言
工作流算是面试中的常考题了,面试中主要围绕着搞定复杂的前端开发工作流程的几个工具:vite
, webpack
,rollup gulp
。接下来用通俗一点的方式带友友认识下webpack
,简单来说,Webpack
负责将你的源码及其依赖转换成浏览器可以理解的形式,并且将所有文件整合到一个或多个 bundle
中,同时自动处理好 HTML
文件中的脚本引用,使得整个应用可以正常运行。
一:webpack 与 vite区别
Webpack
- 更适合大型项目:Webpack 的强大功能和灵活性使其适用于处理复杂的大型项目。
- 配置复杂:为了满足多样化的需求,Webpack 的配置较为复杂。
- 构建较慢:由于需要对所有资源进行打包处理,构建速度相对较慢。
- 功能强大:具备丰富的插件生态系统,能够处理各种类型的资源和构建需求。
Vite
- 更适合中小型项目:Vite 的简洁配置和快速启动使其适用于中小型项目的开发。
- 启动速度快:Vite 采用按需编译的方式,无需预先打包整个应用。
- 利用 ES 模块:直接利用浏览器对 ES 模块的支持,简化了开发流程,但在高级特性和插件支持上功能相对有限。
二:Webpack 打包过程概述
读取入口文件的内容,分析入口文件,递归的去读取模块所依赖的其他文件内容,生成 AST 语法树 ,然后根据 AST 语法树生成浏览器能运行的代码(代码版本的降级)
2.1. HTTP 服务器
- 使用
webpack-dev-server
创建一个本地开发服务器。 - 配置服务器监听 5173 端口,并且能够自动刷新页面。
- 服务器会自动识别打包输出的文件,并在浏览器中加载。
2.2. 自动生成 index.html
- 使用
html-webpack-plugin
插件来自动生成 index.html
文件。 - 插件会在
index.html
中自动插入打包后的 JavaScript 文件的引用(如 bundle.js
)。 - 这样可以确保 HTML 文件与生成的 JS 文件正确关联。
2.3. 打包 main.js
Webpack
从 main.js
开始解析应用的所有依赖项。- 它会把所有依赖的模块合并到一个或多个输出文件(
bundle
)中。 - 默认情况下,这些文件会被命名为
bundle.js
并放在指定的输出路径下。
三:构建webpack
3.1:初始化项目
- 新建一个文件夹,因为工作流是一个后端项目,所以可输入指令
npm init -y
初始化为后端项目 - 创建一个
public
文件夹,在该文件夹下新建文件index.html
- 在
src
文件夹下创建main.js
文件作为入口文件,随便写点输出,测试效果
3.2:设置package.json
文件
项目从npm run dev
启动
webpack
:核心包,提供了Webpack的功能。webpack-cli
:个命令行工具,允许运行Webpack。webpack-dev-server
:中间件,为开发提供了快速反馈循环,具有热更新能力。html-webpack-plugin
:插件,用于生成一个HTML文件,并将Webpack打包后的JS文件注入到该HTML文件中。@babel/core
:Babel的核心包,Babel是一个编译器,可以将较新的JavaScript代码转换成向后兼容的代码。@babel/preset-env
:预设,告诉Babel如何转换你的代码以支持目标环境。babel-loader
:Webpack加载器,用于将Babel集成到Webpack的工作流程中。
"scripts": {
"dev":"webpack serve --open"
},
"devDependencies": {
"webpack":"^5.36.2",
"webpack-cli":"^4.6.0",
"webpack-dev-server":"^3.11.2",
"html-webpack-plugin":"^5.3.2",
"@babel/core":"7.15.0",
"@babel/preset-env":"7.15.0",
"babel-loader":"8.2.2"
}
3.3:设置webpack.config.js
文件
webpack 核心概念是通过编写配置文件实现对项目工程的把控 以下是基于您提供的结构整理的Webpack配置项概述,按照您所要求的格式进行排列:
- 入口 (
entry
):定义了应用的起点文件,即Webpack从哪个文件开始构建依赖图。常见的入口文件是 main.js
或者其他类似的初始化脚本文件。 - 输出 (
output
):确定了最终打包文件的名称以及它们将被放置的位置。例如,bundle.js
会被输出到 dist
目录下。
- 模式 (
mode
):设置为 development
模式可以启用一些有助于提高开发体验的功能,如更详细的错误堆栈跟踪、不压缩代码等。 - 开发服务器 (
devServer
):用于配置开发环境中的HTTP服务器,可以指定服务器监听的端口、是否启用热模块替换(Hot Module Replacement, HMR)等功能,帮助开发者更快地迭代开发工作。
- 加载器与规则 (
module.rules
):通过一系列规则定义了Webpack如何处理项目中的不同类型的资源文件。例如,.js
文件可能需要通过 babel-loader
进行转译,而 .css
文件可能需要通过 css-loader
和 style-loader
来加载和应用样式。 - 插件 (
plugins
):Webpack 插件用于执行范围更广的任务,如清理旧的构建文件、优化输出结果、注入HTML模板等。一个常见的插件是 HtmlWebpackPlugin
,它可以自动生成 HTML 文件并将打包后的 JavaScript 文件自动注入其中。
Babel 帮助开发者简化了开发流程,集中精力于业务逻辑而不是兼容性问题
- Babel 是一个 JavaScript 转译器,可将现代 JS 代码转换为向后兼容的代码。
- 允许开发者使用最新的 JavaScript 语法,而不用担心浏览器兼容性问题。
- AST (抽象语法树) : Babel 通过解析源代码生成 AST,然后基于此树进行转换。
- Presets (预设) : 一组 plugins (插件),告诉 Babel 如何进行代码转换, @babel/preset-env: 根据目标环境自动选择需要转换的语法特性。
- 通过
.babelrc
或 babel.config.js
文件指定 presets 和 plugins,可以设定特定的环境变量和条件来控制转换行为。 - 可以自动添加 polyfills (对于一些新的 API 方法) 来保证旧环境下的功能实现。
// commonjs 模块化
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development', // 开发阶段
entry: './src/main.js',
// 入口文件,沿着入口找到所有依赖模块,将之打包成一个文件
// 打包成bindle.js
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')//resolve会校验路径
},
//模块车间
module:{
rules:[
{
test:/.js$/,
exclude:/node_modules/,
use:{
loader:'babel-loader',
}
}
]
},
devServer:{
port:8080,
contentBase:path.join(__dirname,'public'),//join拼接路径
hot:true
},
plugins:[
new HtmlWebpackPlugin({
template:'./public/index.html'
})
]
}
在main.js中输入进行测试
let a = 1
console.log(`${a}`)
使用Babel
,需要在根目录下创建一个名为.babelrc
的文件
{
"presets": [
"@babel/preset-env"
]
}
通过上述配置,Webpack 将能够处理项目的入口文件 main.js
及其依赖,生成一个或多个捆绑包(如 bundle.js
),并启动一个开发服务器来服务于这些文件。同时,通过 HtmlWebpackPlugin 插件自动生成带有正确脚本引用的 index.html
文件。友友们可以在命令行输入npm run dev
启动项目,看看输出
四:按需配置
4. 1:上线形式打包
- 在
webpack.config.js
文件删去 mode: 'development'
"scripts": {
"build":"webpack --mode production"
},
- 运行
npm run build
,会发现自动生成了一个dist
文件夹
4.2:引入css
- 在
webpack.config.js
文件中的module.rules
中添加
{
test:/.css$/,
use:[
'style-loader',
'css-loader'
]
}
test: /.css$/
:这是一个正则表达式,用于匹配所有 .css
文件。
use
数组:指定了在处理 CSS 文件时使用的 loader。
'style-loader'
:将 CSS 插入到 DOM 的 <style>
标签中。'css-loader'
:解析 CSS 文件中的 @import
和 url()
,并将其处理为 JavaScript 模块。
"devDependencies": {
"css-loader":"6.0.0",
"style-loader":"3.0.0"
}
3.再简单设置一下css文件中的样式
body{
width: 100%;
height: 100%;
background-color: #d31818;
}
4.在入口文件(main.js
)中输入import './common.css'
,这告诉 Webpack 处理这个 CSS 文件,并将其打包到最终的 bundle 文件中.npm i
之后就可以利用webpack加载静态资源
4.3:使用Vue
- 在
webpack.config.js
文件中的module.rules
中添加说明,同时引入插件
{
test:/.vue$/,
use:{
loader:'vue-loader'
}
},
{
test:/.styl(us)?$/,
use:[
'style-loader',
'css-loader',
'stylus-loader'
]
}
test: /.vue$/
:匹配所有 .vue
文件。use: { loader: 'vue-loader' }
:使用 vue-loader
来处理 .vue
文件。
const { VueLoaderPlugin } = require('vue-loader')
plugins:[
new VueLoaderPlugin()
]
VueLoaderPlugin
:这是一个 Vue 专用的 Webpack 插件,它在构建过程中处理 Vue 组件。没有这个插件,vue-loader
将无法正常工作
- 在
package.json
文件中说明依赖之后,npm i
安装依赖
"devDependencies": {
"vue-loader": "^16.2.0",
"stylus-loader": "^8.1.0",
"stylus":"0.63.0"
},
"dependencies": {
"vue": "^3.0.0"
},
3.设置main.js
,与正常使用vue一样
import './common.css' //webpack/vite加载静态资源
import App from './App.vue'
import { createApp } from 'vue'
createApp(App)
.mount('#app')
4.在src下创建App.vue
<template>
<div class="title">
App {{ word }}
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const word = ref('Hello')
onMounted(() => {
setTimeout(() => {
word.value = 'World'
}, 2000)
})
</script>
<style lang="stylus">
.title
font-size 30px
color green
</style>
项目跑起来之后效果如图
(ps:如果运行不起来,报错配置有问题,尝试删除 node_modules
文件夹和 package-lock.json
文件,然后重新安装依赖)
五:webpack 与 vite区别
构建完webpack之后,相信友友们再次回答这个问题时,会有更深的理解了
- Webpack: 配置文件较为复杂,核心概念包括
entry
(入口点)、output
(输出配置)、module
(使用 loader 处理各种文件类型) 和 plugins
(插件扩展功能)。Webpack 的灵活性允许用户高度定制化其构建流程。Webpack 在早期没有支持 <script type="module">
,所有模块必须通过 Webpack 的模块依赖系统打包,处理完所有文件后才能运行,充当了一个全面的打包器 (bundler)。 - Vite: 采用约定大于配置的理念,配置需求极少,旨在简化开发过程。Vite 内置了现代构建工具的最佳实践,减少了用户配置的复杂性。Vite 支持原生 ES6 模块 (
<script type="module">
),允许懒加载和按需加载模块。当切换路由或引入新功能时,Vite 只会在需要时动态加载相关模块,从而提高了启动速度。
- Webpack: 作为早期的工作流解决方案,Webpack 在其早期版本中建立了成熟的生态系统,适用于各种项目需求。它的高度可配置性和插件系统使其适合企业级应用。
- Vite: 由 Vue 3 团队推出,作为 Vue 3 的官方构建工具,Vite 更加现代,提供了更快的开发体验。Vite 的构建流程不需要传统的打包步骤,通过使用原生 ES6 模块和支持懒加载,显著提高了开发速度和性能。Vite 的缺点是目前只能支持 IE11 及之后版本的浏览器。
- Webpack: 在处理大型项目时,Webpack 的构建速度可能会变得很慢,特别是在启动阶段,构建时间可能需要几十秒到几分钟。随着项目规模的增加,性能问题愈加显著。Webpack 需要将所有文件处理完毕才能运行,导致较长的构建时间。
- Vite: 通过不需要传统的打包过程来显著提高性能。Vite 利用原生 ES6 模块进行即时的模块热重载,使启动速度更快,并且能在切换路由或引入新功能时进行按需加载。这样,Vite 提供了更加流畅的开发体验,尽管在支持浏览器的范围上有一定限制。
- Webpack: 拥有广泛的生态系统和社区支持,支持各种插件和加载器,满足复杂的配置需求。其成熟的工具链和社区资源使其成为企业级项目的首选。
- Vite: 尽管较新,但其生态系统正在迅速发展,尤其是与 Vue 的紧密集成带来了良好的体验。随着时间的推移,Vite 的生态系统和社区也在不断壮大。
总结
Webpack 提供了全面的功能和高度的配置能力,适用于各种复杂的开发场景,而 Vite 则通过简化配置和提高性能,提供了更加流畅的开发体验,特别适合需要快速反馈的现代前端开发环境。Vite 的原生 ES6 模块支持和按需加载特性进一步增强了开发速度,但目前的浏览器支持范围有所限制。