webpack相关面试题
本文最后更新于 2024-10-25,文章内容可能已经过时。
webpack是什么,为什么需要webpack
webpack是打包构建工具,目前项目比较复杂,开发文件比较多,使用到的新的技术也比较多如
es6+ vue typescript等相关技术,为了能够让浏览器正常解析使用,webpack将这些技术,通过打包转换为浏览器能够解析运行的代码!在
webpack中,不仅可以在浏览器中兼容代码,还可以对代码进行压缩!
webpack 中有哪些配置
常用配置
| 配置 | 作用 |
|---|---|
entry |
需要打包的入口文件,可以是单个文件 也可以是多个文件! |
output |
打包结果输出的文件,文件的存放位置,以及文件名命名规则, 以及引用资源的根路径等。 |
module |
模块相关配置,通过loaders来处理各种文件类型,比如JavaScript,CSS,图片,字体等。 |
plugins |
插件相关配置,比如压缩,优化,热更新等。 |
resolve |
解析相关配置,比如可以配置路径别名 模块如何寻找,解析顺序,等。 |
devServer |
开发服务器相关配置,提供的开发服务器,可以实时编译,刷新浏览器,提供热更新等功能。 |
mode |
模式相关配置,webpack 的运行模式,可以是开发模式,生产模式等。 |
optimization |
优化相关配置,webpack 打包优化配置,比如压缩,分包,代码分割等。 |
externals |
外部依赖相关配置,比如不打包的依赖,比如jquery,react,vue,等。 |
其他配置
| 配置 | 作用 |
|---|---|
devtool |
调试工具,打包后的文件调试工具,比如source-map,eval-source-map,cheap-module-source-map,cheap-module-eval-source-map,eval,none,等。 |
stats |
打包信息,打包信息配置,比如显示打包后的文件大小,显示打包后的模块数量,显示错误信息,等。 |
cache |
缓存,缓存配置,webpack 缓存配置,缓存可以加快打包速度,缓存配置可以缓存 loader,缓存插件,缓存入口文件,缓存输出文件,等。 |
context |
上下文,webpack 运行的上下文,默认是当前目录,可以指定运行的目录。 |
target |
目标环境,webpack 打包的目标环境,可以指定浏览器版本,可以指定运行环境,可以指定运行模式,等。 |
performance |
性能,webpack 打包的性能配置,可以指定打包后的文件大小,可以指定打包后的文件数量,可以指定打包时间限制,等。 |
手写一个基本配置
const path = require('path')
module.exports = {
model: 'development', // 开发模式
// 配置打包入口文件
entry: path.resolve(__dirname, '../src/index.js'),
// 配置打包结果输出文件
output: {
// 将打包结果的文件放在 dist 目录下
path: path.resolve(__dirname, '../dist'),
// 文件名,[name] 代表入口文件的文件名,[chunkhash] 代表打包后的文件 hash 值长度为 8
filename: '[name].[chunkhash:8].js',
// 输出文件中引用资源的根路径,默认是 '/'
publicPath: './',
clean: true // 每次打包前清空 dist 目录
},
// 解析模块查找规则配置
resolve: {
// 扩展
extensions: ['.js', '.json', '.jsx', '.ts', '.tsx'], // 配置解析文件扩展名
alias: {
'@': path.resolve(__dirname, '../src') // 配置路径别名
}
},
// 配置模块相关配置
module: {
rules: [
// 解析 js 文件的 loader
{
// 匹配文件规则
test: /\.(js|jsx|ts|tsx)$/,
// 包含的目录
include: path.resolve(__dirname, '../src'),
// 排除 node_modules 目录
exclude: /node_modules/,
// 使用的 loader
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: ['@babel/plugin-transform-runtime']
}
}
},
// 样式 loader 解析规则
{
test: /\.css|\.less|\.scss$/,
use: [
'style-loader',
'css-loader',
'less-loader',
'sass-loader'
]
},
// 图片 loader 解析规则
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: 'static/images/[name].[contenthash:8].[ext]'
}
}
]
}
]
}
// 配置插件相关配置
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../public/index.html'),
filename: 'index.html',
],
// 配置开发服务器相关配置
devServer: {
},
}
常见的 loader,loader 作用
在
webpack中只能处理js文件类型,如果要处理其它文件类型,需要使用loader。loader的作用就是将文件转换成webpack可以处理的模块。
常用 loader
| loader | 作用 |
|---|---|
babel-loader |
将 ES6+ 语法转换为 ES5 语法,可以处理 JSX,TypeScript 等。 |
vue-loader |
加载 Vue 组件,可以处理 Vue组件。 |
style-loader |
将样式文件插入到 DOM 中,通过 style 标签引用。 |
css-loader |
加载 CSS 文件,可以处理 CSS,Less,Sass 等。 |
less-loader |
加载 Less 文件,可以处理 Less 语法。 |
sass-loader |
加载 Sass 文件,可以处理 Sass 语法。 |
postcss-loader |
加载 CSS 文件,可以处理 CSS,Less,Sass 等,可以添加浏览器前缀,自动补全 CSS3 特性。 |
file-loader |
加载文件,可以处理图片,字体等。 |
url-loader |
与 file-loader 类似,但可以设置文件大小限制,超过限制则会使用 DataURL(base64) 格式。 |
其他 loader
| loader | 作用 |
|---|---|
html-loader |
加载 HTML 文件,可以处理模板文件。 |
raw-loader |
加载原始文件,可以处理文本文件。 |
json-loader |
加载 JSON 文件。 |
worker-loader |
加载 Web Worker 文件。 |
expose-loader |
暴露模块,可以将模块暴露到全局作用域。 |
script-loader |
加载模块,可以加载模块。 |
source-map-loader |
加载 source map 文件。 |
ts-loader |
加载 TypeScript 文件。 |
happypack |
多进程打包,可以提高打包速度。 |
thread-loader |
多线程打包,可以提高打包速度。 |
cache-loader |
缓存 loader,可以缓存 loader 的结果。 |
有哪些常见的 plugin, plugin 作用
在
webpack中plugin插件主要用来打包功能扩展,在打包过程中可以对代码进行优化,代码压缩以及打包优化等!
常见的plugin
| plugin | 作用 |
|---|---|
html-webpack-plugin |
基于 html 模版,生成对应文件的引用关系 |
clean-webpack-plugin |
清空输出目录 |
webpack-bundle-analyzer |
分析打包结果 |
copy-webpack-plugin |
复制文件,可以复制文件到输出目录。 |
mini-css-extract-plugin |
提取 CSS 文件,可以提取CSS 文件到单独的文件中。 |
optimize-css-assets-webpack-plugin |
压缩 CSS 文件,可以压缩 CSS 文件。 |
terser-webpack-plugin |
压缩 JavaScript 文件,可以压缩 JavaScript 文件。 |
webpack-merge |
合并 webpack 配置 |
uglifyjs-webpack-plugin |
压缩 JavaScript 文件,可以压缩 JavaScript 文件。 |
webpack-dev-server |
开发服务器,可以实时编译,刷新浏览器,提供热更新等功能。 |
define-webpack-plugin |
定义环境变量,可以定义环境变量。 |
webpack-manifest-plugin |
生成 manifest 文件,可以生成 manifest 文件。 |
webpack-parallel-uglify-plugin |
多进程压缩 JavaScript 文件,可以提高压缩速度。 |
laoder 和 plugin 的区别
loader: 是用来处理webpack打包所不能处理的模块,webpack只能处理js文件,像css 图片 字体 vue等其它文件需要loader来处理。plugin: 是用来扩展webpack功能的,对webpack打包功能等一个增强, 比如压缩,优化,热更新等。
loader(文件类型转换器): 更专注于文件的转换, 是文件转换器,将js除外的文件,转换成webpack可以处理的模块。
plugin(webpack功能扩展):更专注于流程扩展, 是webpack的插件,用来扩展webpack的功能,对webpack的打包功能进行增强。
babel-loader常见配置
babel-loader将ES6+ 语法转换为 ES5 语法,可以处理JSX,TypeScript等。babel-loader将高级语法转换为低级语法,这样浏览器才能识别,才能运行。
常见预设配置
可以在
.babelrc或者是babel.config.js文件中配置,也可以在webpack.config.js文件中配置。 主要有presets(预设)和plugins(插件)两个配置项。
babel-preset-env:用来转换代码到指定环境的浏览器版本,可以指定浏览器版本,也可以指定运行环境,也可以指定运行模式。babel-preset-react:用来转换React代码。babel-preset-typescript:用来转换TypeScript代码。
module: {
rules: [
{
// 匹配文件规则
test: /\.js|.jsx|ts|tsx$/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
{
targets: {
chrome: '58',
firefox: '57',
ie: '11'
},
useBuiltIns: 'usage',
corejs: 3
},
'@babel/preset-react',
'@babel/preset-typescript'
],
// plugins: ['@babel/plugin-transform-runtime']
},
plugins: ['@babel/plugin-transform-runtime']
}
]
}
webpack 指纹占位符
webpack中的指纹占位符,是对文件命名的一个扩展,可以根据占位符,来生成唯一的文件名。
[ext]:文件扩展名。[path]:文件的相对路径。[name]:文件原本的文件名。[id]:唯一标识符。
常用占位符
[hash]:每次构建时,整个项目的hash值都会改变,hash值长度为32。[chunkhash]:只在当前chunk有改动的时候,hash值才会改变,hash值长度为32。[contenthash]:根据文件内容,来决定是否改变!
filename: '[name].[chunkhash:8].js',
filename: '/static/images/[name].[contenthash:8].[ext]'
webpack 打包流程
读取加载配置文件根据entry 入口文件进行递归解析依赖,找出import和require的模块文件,并将它们加入到依赖图中!文件类型转换,将非 js 和 json 文件的其它文件,通过loader匹配规则进行文件类型转换,转换为webpack能够理解的模块!插件处理,webpack通过plugin对打包过程进行额外的处理,比如打包优化、资源管理和环境变量注入等!生产输出,Webpack处理依赖关系后,会生成一个或多个 bundle 文件。这些文件是打包后的 JavaScript 文件,包含了应用程序的所有模块代码。输出结果,将打包好的bundle文件输出到指定目录!
chunk(块) bundle(包) 和 module(模块)
chunk在webpack打包分析过程中,会分成多个小块,bundle则是多个chunk组成的js文件。module则是webpack打包过程中,每一个文件都可以视为一个模块。
chunk(块)
在
Webpack中,"chunk"是一个核心概念,它代表了Webpack打包过程中生成的代码块。Webpack通过将应用程序分割成多个小块(chunks),然后将这些块打包成一个或多个bundle文件。每个chunk通常包含了一组模块(如JavaScript文件、CSS文件、图片等)的代码,这些模块在运行时可以被加载和执行。
bundle(捆绑包)
bundle是webpack打包过程中生成的文件,它是多个chunk组成的。bundle文件可以是js文件,也可以是css文件,也可以是图片文件。
module(模块)
在
webpack中,每一个文件都可以视为一个模块,js图片css等文件,通过loader和plugin来处理,最终转换成打包文件!
如何提高webpack打包速度
多进程打包:HappyPack和thread-loader这两个插件可以提高webpack打包速度。缓存:cache-loader可以缓存loader的结果,加快打包速度。压缩:terser-webpack-plugin和uglifyjs-webpack-plugin这两个插件可以压缩JavaScript文件,减少文件体积。第三方库预先打包:DllPlugin和DllReferencePlugin这两个插件可以提前打包第三方库,减少打包时间。缓存中间件: 使用HardSourceWebpackPlugin可以缓存webpack中间件的结果,加快打包速度。
减少打包体积大小/性能优化
- tree shaking:
webpack内置的tree shaking功能,可以自动删除没有用到的代码。 - 按需加载:
webpack提供了import()语法,可以按需加载代码。 - 代码分割:
webpack提供了splitChunks配置,可以自动分割代码。 - 代码压缩:
- CSS压缩:
optimize-css-assets-webpack-plugin和mini-css-extract-plugin这两个插件可以压缩CSS文件。 - JavaScript压缩:
terser-webpack-plugin和uglifyjs-webpack-plugin这两个插件可以压缩JavaScript文件。
- CSS压缩:
- 图片压缩:
image-webpack-loader或GzippedWebpackPlugin这款插件可以压缩图片。 - CDN加速:
externals配置可以使用CDN加速。
babel-loader是什么,有什么作用
babel-loader是一个webpack的loader转换器,它可以将es6+语法转换为浏览器可兼容的js代码文件! 在es标准中提出了很多新特性,而浏览器对这些新特性没有实现,所以需要babel来转换为浏览器可以运行的js代码!