前端工程化
Webpack 基础
Webpack 作用、核心概念与工具对比
包含的题目:
- Webpack 的作用是什么?(高频考点)
- Webpack 的核心概念有哪些?(高频考点)
- Webpack 与 Vite 的区别是什么?(高频考点)
- Webpack 与 Rollup 的区别是什么?
详细答案:
Webpack 作用:
- 模块打包:将多个模块打包成静态资源
- 代码转换:通过 Loader 处理各种文件类型
- 代码优化:压缩、分割、Tree Shaking 等
- 开发支持:开发服务器、热更新、Source Map
核心概念:
- Entry:入口起点
- Output:输出配置
- Loader:文件转换器
- Plugin:扩展插件
- Mode:开发/生产模式
- Module:项目中的每个文件
- Chunk:代码块
- Bundle:最终输出文件
配置文件示例:
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{ test: /\.js$/, use: 'babel-loader' },
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
],
},
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
mode: 'development',
};
工具对比:
| 工具 | 特点 | 适用场景 |
|---|---|---|
| Webpack | 功能全面,生态成熟 | 大型复杂项目 |
| Vite | 启动快,开发体验好 | 现代前端项目 |
| Rollup | 打包效率高,Tree Shaking 好 | 库/组件开发 |
Webpack 核心概念详解
Entry、Output、Loader、Plugin
包含的题目: 5-18. Entry、Output、Loader、Plugin、Mode 相关题目
详细答案:
Entry 配置:
// 单入口
entry: './src/index.js'
// 多入口
entry: {
main: './src/index.js',
vendor: './src/vendor.js',
}
Output 配置:
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
publicPath: '/',
clean: true,
}
Loader 配置:
rules: [
// JavaScript
{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' },
// CSS
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
// 图片
{ test: /\.(png|jpg|jpeg|gif|svg)$/, type: 'asset/resource' },
// 字体
{ test: /\.(woff|woff2|eot|ttf|otf)$/, type: 'asset/resource' },
]
常用 Loader:
- babel-loader:ES6+ 转换
- css-loader/style-loader:CSS 处理
- sass-loader/less-loader:预处理器
- file-loader/url-loader:文件处理
- vue-loader:Vue 单文件组件
Plugin 配置:
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new MiniCssExtractPlugin({ filename: '[name].[contenthash].css' }),
new CleanWebpackPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
}),
]
常用 Plugin:
- HtmlWebpackPlugin:生成 HTML
- MiniCssExtractPlugin:提取 CSS
- CleanWebpackPlugin:清理输出目录
- DefinePlugin:定义环境变量
- HotModuleReplacementPlugin:热更新
Webpack Loader 与 Plugin 原理
包含的题目: 23-41. Loader 与 Plugin 原理相关题目
详细答案:
Loader 原理:
- 函数式处理,接收源文件内容,返回处理结果
- 链式调用:从右到左执行
- 可以同步或异步
自定义 Loader 示例:
module.exports = function(source) {
// 处理逻辑
const result = source.replace(/console\.log\(.*?\);/g, '');
return result;
};
Plugin 原理:
- 基于 Tapable 事件流机制
- 通过 apply 方法注册到 Webpack 生命周期
- 可以访问整个编译过程
自定义 Plugin 示例:
class MyPlugin {
apply(compiler) {
compiler.hooks.done.tap('MyPlugin', (stats) => {
console.log('编译完成');
});
}
}
Webpack 生命周期钩子:
environment:环境准备compile:开始编译make:构建模块emit:输出资源done:完成构建
Webpack 构建流程
包含的题目: 42-48. 构建流程相关题目
详细答案:
Webpack 构建流程:
- 初始化:合并配置,创建 Compiler 实例
- 编译:从 Entry 开始递归解析依赖
- 构建:调用 Loader 转换模块
- 生成:创建 Chunk,构建依赖图
- 输出:将资源写入文件系统
Tapable 事件流:
// Webpack 核心事件机制
compiler.hooks.compile.tap('Plugin', () => {
console.log('开始编译');
});
Compiler vs Compilation:
- Compiler:编译器实例,包含完整配置
- Compilation:单次构建上下文,包含本次构建信息
Webpack 优化
包含的题目: 49-64. 性能优化相关题目(高频考点)
详细答案:
构建速度优化:
// 1. 缩小搜索范围
resolve: {
extensions: ['.js', '.jsx'],
modules: [path.resolve(__dirname, 'node_modules')],
}
// 2. 使用缓存
cache: { type: 'filesystem' }
// 3. 多进程构建
use: ['thread-loader', 'babel-loader']
// 4. DllPlugin 预编译
new webpack.DllPlugin({ /* 配置 */ })
打包体积优化:
// 1. 代码压缩
optimization: {
minimize: true,
minimizer: [new TerserPlugin(), new CssMinimizerPlugin()],
}
// 2. 代码分割
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: { test: /[\\/]node_modules[\\/]/, name: 'vendors' },
},
}
// 3. 按需加载
import(/* webpackChunkName: "lazy" */ './lazy-module')
Tree Shaking 原理:
- 基于 ES6 模块的静态分析
- 移除未使用的代码
- 需要满足条件:
- 使用 ES6 模块语法
- 生产模式自动开启
- package.json 中配置 sideEffects
Scope Hoisting:
- 将多个模块合并到一个函数作用域
- 减少函数声明和闭包
- 提升运行速度
懒加载实现:
// React 懒加载
const LazyComponent = React.lazy(() => import('./LazyComponent'));
// 使用 Suspense
<Suspense fallback={<div>加载中...</div>}>
<LazyComponent />
</Suspense>
缓存优化策略:
- 文件名使用 contenthash
- 提取第三方库到单独 chunk
- 使用持久化缓存
Webpack 开发环境
包含的题目: 61-64. 开发环境配置相关题目
详细答案:
devServer 配置:
devServer: {
static: './public',
compress: true,
port: 3000,
open: true,
hot: true,
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
},
},
historyApiFallback: true,
}
HMR 热更新原理:
- 建立 WebSocket 连接
- 文件变化时重新编译
- 通过 WebSocket 发送更新
- 客户端替换模块
- 保持应用状态
source-map 类型:
- 开发环境:
eval-cheap-module-source-map - 生产环境:
source-map或hidden-source-map
Vite 基础
包含的题目: 65-67. Vite 基础相关题目(高频考点)
详细答案:
Vite 核心特性:
- 闪电启动:基于原生 ES Modules
- 即时热更新:HMR 速度快
- 按需编译:只编译所需模块
- 预构建:转换 CommonJS 模块
- 框架支持:Vue、React、Svelte 等
Vite 优势:
- 开发体验好,启动快
- 配置简单,开箱即用
- 构建高效,生产使用 Rollup
- 生态完善,插件丰富
Vite vs Webpack:
| 对比项 | Vite | Webpack |
|---|---|---|
| 启动速度 | 极快(< 1s) | 慢 |
| 热更新 | 快 | 随项目增大变慢 |
| 配置 | 简单 | 复杂 |
| 生态 | 中等 | 非常成熟 |
Vite 原理
包含的题目: 68-73. Vite 原理相关题目(高频考点)
详细答案:
Vite 原理:
- 开发环境:原生 ES Modules + 按需编译
- 生产环境:Rollup 打包
ES Modules 使用:
<script type="module">
import { hello } from './hello.js';
hello('world');
</script>
开发服务器原理:
- 浏览器请求模块
- Vite 拦截请求
- 按需编译后返回
- 缓存编译结果
预构建(Dependency Pre-bundling):
- 扫描 CommonJS/UMD 模块
- 使用 esbuild 转换为 ES Modules
- 合并小模块,减少请求
HMR 热更新:
if (import.meta.hot) {
import.meta.hot.accept('./module.js', (newModule) => {
newModule.render();
});
}
生产构建:
- 使用 Rollup 打包
- 代码分割、压缩、优化
- 支持 Tree Shaking
Vite 配置
包含的题目: 74-76. Vite 配置相关题目
详细答案:
vite.config.js 基本配置:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
root: process.cwd(),
base: '/',
server: {
host: 'localhost',
port: 3000,
proxy: { '/api': { target: 'http://localhost:8080' } },
},
build: {
outDir: 'dist',
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'vue-router'],
},
},
},
},
resolve: {
alias: { '@': path.resolve(__dirname, 'src') },
},
});
环境变量使用:
// .env 文件
VITE_API_URL=https://api.example.com
// 代码中访问
console.log(import.meta.env.VITE_API_URL);
Vite 插件
包含的题目: 77-81. Vite 插件相关题目
详细答案:
Vite 插件系统:
- 兼容 Rollup 插件
- 提供丰富的生命周期钩子
- 支持自定义插件
插件结构:
export default function myPlugin() {
return {
name: 'my-plugin',
config(config) {
// 修改配置
return config;
},
transform(code, id) {
// 转换代码
return code;
},
};
}
常用插件:
- @vitejs/plugin-vue:Vue 支持
- @vitejs/plugin-react:React 支持
- @vitejs/plugin-legacy:旧浏览器支持
- vite-plugin-svg-icons:SVG 图标处理
常见问题与解决方案
包含的题目: 86-95. 常见问题相关题目
详细答案:
构建速度慢:
- 原因:项目过大,配置不当
- 解决方案:
- 使用缓存(cache: { type: 'filesystem' })
- 多进程构建(thread-loader)
- 缩小文件搜索范围
- 使用 DllPlugin 预编译
打包体积大:
- 原因:未压缩,未分割,未 Tree Shaking
- 解决方案:
- 代码压缩(TerserPlugin)
- 代码分割(splitChunks)
- 按需加载(import())
- 排除外部库(externals)
热更新失败:
- 原因:配置错误,模块不兼容
- 解决方案:
- 检查 HMR 配置
- 确保模块支持 HMR
- 使用 module.hot.accept()
环境变量问题:
- 解决方案:
- 正确配置 DefinePlugin
- 使用 process.env 访问
- 区分开发/生产环境
版本升级:
- 步骤:
- 备份项目
- 查看官方迁移指南
- 逐步升级依赖
- 测试验证
以上是对前端工程化 95 道面试题目的综合解答,涵盖了 Webpack 和 Vite 的核心概念、配置、优化和常见问题。每个主题都包含了理论说明、配置示例和最佳实践建议。