《前后端面试题
》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux... 。

文章目录
- 一、本文面试题目录
-
-
- 01-40面试题
- 41-60面试题
- [61. 什么是webpack的profile配置?有什么作用?](#61. 什么是webpack的profile配置?有什么作用?)
- [62. 如何分析webpack的打包结果?使用什么工具?](#62. 如何分析webpack的打包结果?使用什么工具?)
- [63. webpack-bundle-analyzer的作用是什么?如何使用?](#63. webpack-bundle-analyzer的作用是什么?如何使用?)
- [64. 如何解决webpack打包后出现的重复代码问题?](#64. 如何解决webpack打包后出现的重复代码问题?)
- [65. 什么是tree-shaking失效的情况?如何避免?](#65. 什么是tree-shaking失效的情况?如何避免?)
- [66. webpack中如何配置公共路径(publicPath)?](#66. webpack中如何配置公共路径(publicPath)?)
- [67. 如何在webpack中配置不同环境的全局变量?](#67. 如何在webpack中配置不同环境的全局变量?)
- [68. 什么是webpack的模块解析规则?](#68. 什么是webpack的模块解析规则?)
- [69. 如何处理webpack中的循环依赖?](#69. 如何处理webpack中的循环依赖?)
- [70. webpack中如何配置图片的base64编码转换的阈值?](#70. webpack中如何配置图片的base64编码转换的阈值?)
- [71. 如何在webpack中禁用AMD和CommonJS模块语法?](#71. 如何在webpack中禁用AMD和CommonJS模块语法?)
- [72. 什么是webpack的noEmitOnErrors配置?](#72. 什么是webpack的noEmitOnErrors配置?)
- [73. 如何在webpack中配置打包后的文件名?](#73. 如何在webpack中配置打包后的文件名?)
- [74. 如何实现webpack的多线程打包?使用什么loader或plugin?](#74. 如何实现webpack的多线程打包?使用什么loader或plugin?)
- [75. thread-loader的作用是什么?如何使用?](#75. thread-loader的作用是什么?如何使用?)
- [76. 什么是webpack的缓存组(cacheGroups)?](#76. 什么是webpack的缓存组(cacheGroups)?)
- [77. 如何在webpack中配置对Node.js内置模块的处理?](#77. 如何在webpack中配置对Node.js内置模块的处理?)
- [78. webpack中如何处理WebAssembly模块?](#78. webpack中如何处理WebAssembly模块?)
- [79. 如何在webpack中配置支持PWA?](#79. 如何在webpack中配置支持PWA?)
- [80. 请描述一下webpack的打包流程。](#80. 请描述一下webpack的打包流程。)
-
一、本文面试题目录
01-40面试题
https://dajianshi.blog.csdn.net/article/details/149673105
41-60面试题
https://dajianshi.blog.csdn.net/article/details/149673328
61. 什么是webpack的profile配置?有什么作用?
-
定义 :
profile
是webpack的一个配置选项,用于收集打包过程的性能数据(如模块构建时间、依赖关系),帮助分析打包瓶颈。 -
作用:
- 分析哪些模块构建耗时最长,优化性能。
- 查看模块间的依赖关系,发现潜在问题(如循环依赖)。
- 比较不同配置下的打包效率,选择最优方案。
-
配置方式:
-
命令行参数 :
bashwebpack --profile --json > stats.json
-
配置文件 :
javascriptmodule.exports = { profile: true, // 启用性能分析 stats: { assets: true, modules: true, moduleTrace: true, timings: true } };
-
-
生成报告:
- 生成的
stats.json
可通过工具可视化,如webpack-bundle-analyzer或官方分析工具。
- 生成的
62. 如何分析webpack的打包结果?使用什么工具?
分析webpack打包结果的常用工具和方法:
-
webpack内置stats:
bashwebpack --json > stats.json # 生成打包统计信息
可通过官方分析工具上传
stats.json
查看可视化结果。 -
webpack-bundle-analyzer:
-
安装 :
bashnpm install webpack-bundle-analyzer --save-dev
-
配置 :
javascriptconst BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { plugins: [ new BundleAnalyzerPlugin() // 构建时自动打开分析页面 ] };
-
-
speed-measure-webpack-plugin:
-
测量每个loader和plugin的执行耗时:
javascriptconst SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); const smp = new SpeedMeasurePlugin(); module.exports = smp.wrap({ // 原始webpack配置 });
-
-
webpackbar:
-
显示打包进度和耗时:
javascriptconst WebpackBar = require('webpackbar'); module.exports = { plugins: [new WebpackBar()] };
-
63. webpack-bundle-analyzer的作用是什么?如何使用?
-
作用 :
webpack-bundle-analyzer
是一个可视化工具,用于分析webpack打包后的文件体积和内容,帮助:- 找出占用空间最大的模块,优化体积。
- 发现未使用的代码(如tree-shaking未生效)。
- 分析第三方库的引入情况,避免重复打包。
-
使用步骤:
-
安装:
bashnpm install webpack-bundle-analyzer --save-dev
-
配置webpack:
javascriptconst BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { plugins: [ new BundleAnalyzerPlugin({ analyzerMode: 'static', // 生成静态HTML文件 reportFilename: 'bundle-report.html', // 报告文件名 openAnalyzer: true // 构建后自动打开报告 }) ] };
-
运行构建:
bashnpm run build
构建完成后会自动打开分析页面,显示各模块的体积占比。
-
-
其他配置选项:
analyzerMode: 'server'
:启动本地服务器查看报告(默认)。analyzerMode: 'disabled'
:生成JSON报告但不打开。generateStatsFile: true
:生成stats.json文件。
64. 如何解决webpack打包后出现的重复代码问题?
解决重复代码问题的常用方法:
-
使用splitChunks提取公共代码:
javascriptoptimization: { splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all' }, common: { minChunks: 2, name: 'common', chunks: 'all' } } } }
-
确保使用相同版本的依赖:
- 检查
package.json
,避免同一依赖安装多个版本。 - 使用
npm dedupe
或yarn deduplicate
合并重复依赖。
- 检查
-
使用DllPlugin预编译第三方库:
-
创建
webpack.dll.js
:javascriptconst webpack = require('webpack'); module.exports = { entry: { vendor: ['react', 'react-dom'] // 预编译这些库 }, output: { filename: '[name].dll.js', library: '[name]_[hash]' }, plugins: [ new webpack.DllPlugin({ name: '[name]_[hash]', path: path.resolve(__dirname, 'dist/[name]-manifest.json') }) ] };
-
在主配置中引用:
javascriptplugins: [ new webpack.DllReferencePlugin({ manifest: path.resolve(__dirname, 'dist/vendor-manifest.json') }) ]
-
-
避免循环依赖:
- 重构代码,拆分公共逻辑到独立模块。
- 使用依赖注入或事件总线解耦模块。
-
使用Module Federation(webpack 5+):
- 在多个应用间共享模块,避免重复打包。
javascript// 应用A配置 new ModuleFederationPlugin({ remotes: { appB: 'appB@http://localhost:3001/remoteEntry.js' } }) // 应用B配置 new ModuleFederationPlugin({ exposes: { './Button': './src/components/Button' } })
-
配置别名统一模块路径:
javascriptresolve: { alias: { 'react': path.resolve(__dirname, 'node_modules/react') } }
-
检查tree-shaking配置:
-
确保使用ES6模块语法(而非CommonJS)。
-
配置
package.json
的sideEffects
字段:json{ "sideEffects": false }
-
-
使用ProvidePlugin自动注入模块:
javascriptplugins: [ new webpack.ProvidePlugin({ $: 'jquery', _: 'lodash' }) ]
65. 什么是tree-shaking失效的情况?如何避免?
-
Tree-shaking失效场景:
-
使用CommonJS模块 :
javascriptconst utils = require('./utils'); // CommonJS语法,tree-shaking不生效
-
模块存在副作用 :
javascript// utils.js export const add = (a, b) => a + b; console.log('Side effect'); // 副作用代码,整个模块不会被移除
-
动态导入或条件导入 :
javascriptif (condition) { import('./moduleA'); // 动态导入会保留整个模块 }
-
第三方库不支持 :
javascriptimport { debounce } from 'lodash'; // lodash使用CommonJS,tree-shaking有限
-
配置错误 :
- 未设置
mode: 'production'
。 - 未在
package.json
中声明sideEffects
。
- 未设置
-
-
避免方法:
-
使用ES6模块语法 :
javascriptimport { add } from './utils'; // ES6语法,支持tree-shaking
-
标记无副作用的模块 :
json// package.json { "sideEffects": false // 所有文件无副作用 }
或指定有副作用的文件:
json{ "sideEffects": [ "./src/side-effect.js", "*.css" ] }
-
使用支持tree-shaking的库 :
javascriptimport { debounce } from 'lodash-es'; // lodash-es使用ES6模块
-
避免副作用代码 :
javascript// 错误:直接执行有副作用的代码 export const init = () => { console.log('Initialized'); }; // 正确:将副作用封装在函数中 init(); // 主动调用,明确依赖
-
优化配置 :
javascript// webpack.config.js module.exports = { mode: 'production', // 启用生产模式优化 optimization: { usedExports: true, // 标记未使用的导出 sideEffects: true // 识别sideEffects配置 } };
-
66. webpack中如何配置公共路径(publicPath)?
-
作用 :
publicPath
用于指定打包后资源的加载路径,影响CSS、JS、图片等资源的引用地址。 -
配置方式:
-
在output中静态配置:
javascriptmodule.exports = { output: { publicPath: '/static/' // 所有资源路径前缀为/static/ } };
生成的资源路径:
html<script src="/static/main.js"></script> <link href="/static/styles.css" rel="stylesheet">
-
动态配置(运行时):
javascriptoutput: { publicPath: 'auto' // 自动根据当前URL确定路径 }
或通过全局变量动态设置:
javascriptoutput: { publicPath: 'window.MyApp.publicPath' // 运行时由window.MyApp.publicPath决定 }
-
基于环境配置:
javascriptconst isProduction = process.env.NODE_ENV === 'production'; module.exports = { output: { publicPath: isProduction ? 'https://cdn.example.com/' : '/' } };
-
-
特殊场景:
-
相对路径 :
javascriptoutput: { publicPath: './' // 相对于HTML文件的路径 }
-
动态导入的资源 :
javascriptoutput: { publicPath: 'async-public-path' // 专门为动态导入设置路径 }
-
67. 如何在webpack中配置不同环境的全局变量?
配置不同环境的全局变量可通过DefinePlugin
实现,步骤如下:
-
安装cross-env(可选):
bashnpm install cross-env --save-dev
-
配置package.json脚本:
json{ "scripts": { "dev": "cross-env NODE_ENV=development webpack serve", "build": "cross-env NODE_ENV=production webpack" } }
-
使用DefinePlugin注入变量:
javascriptconst webpack = require('webpack'); const isProduction = process.env.NODE_ENV === 'production'; module.exports = { plugins: [ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV), API_URL: JSON.stringify(isProduction ? 'https://api.prod.com' : 'https://api.dev.com') }, __DEV__: !isProduction }) ] };
-
在代码中使用:
javascriptif (process.env.NODE_ENV === 'development') { console.log('开发环境'); } fetch(`${process.env.API_URL}/users`); if (__DEV__) { console.log('仅在开发环境显示'); }
- 注意 :
DefinePlugin
会直接替换代码中的变量名,因此值必须用JSON.stringify()
包裹(或写成'"value"'
)。- 避免暴露敏感信息(如API密钥),建议通过服务器端代理访问。
68. 什么是webpack的模块解析规则?
-
定义 :模块解析规则是webpack在处理
import
和require
语句时,如何定位和加载模块的规则。 -
核心规则:
-
绝对路径 :直接加载,无需解析。
javascriptimport '/path/to/module';
-
相对路径 :相对于当前文件解析。
javascriptimport '../utils/module'; // 从当前目录上一级的utils文件夹查找
-
模块路径 :
- 从
node_modules
目录查找。 - 按
resolve.modules
配置的路径查找(默认['node_modules']
)。
javascriptimport 'lodash'; // 从node_modules/lodash查找
- 从
-
文件扩展名 :
- 按
resolve.extensions
配置的顺序尝试(默认['.js', '.json', '.wasm']
)。
javascriptimport './module'; // 尝试加载module.js、module.json等
- 按
-
目录作为模块 :
- 查找目录下的
package.json
的main
字段指定的文件。 - 若无
package.json
或main
字段,按resolve.mainFiles
配置查找(默认['index']
)。
- 查找目录下的
-
-
配置示例:
javascriptmodule.exports = { resolve: { modules: [path.resolve(__dirname, 'src'), 'node_modules'], // 优先从src目录查找 extensions: ['.ts', '.tsx', '.js', '.json'], // 尝试的扩展名顺序 mainFiles: ['index', 'main'], // 目录作为模块时的默认文件名 alias: { // 别名配置 '@components': path.resolve(__dirname, 'src/components') } } };
69. 如何处理webpack中的循环依赖?
循环依赖指模块A依赖模块B,同时模块B依赖模块A,可能导致运行时错误。处理方法:
-
重构代码,拆分公共逻辑:
- 将A和B的公共依赖提取到新模块C。
javascript// 原循环依赖 // A.js → B.js → A.js // 重构后 // A.js → C.js ← B.js
-
延迟导入(动态导入):
javascript// 模块A export const funcA = () => { // 在函数内部动态导入,避免初始化时循环依赖 const { funcB } = require('./B'); return funcB(); }; // 模块B export const funcB = () => 'Hello';
-
使用依赖注入:
javascript// 模块A let bModule; export const setBModule = (b) => { bModule = b; }; export const funcA = () => bModule.funcB(); // 模块B import { funcA } from './A'; export const funcB = () => 'Hello'; // 初始化时注入依赖 import { setBModule } from './A'; import { funcB } from './B'; setBModule({ funcB });
-
检查并优化依赖结构:
- 使用
webpack-bundle-analyzer
分析模块依赖图。 - 遵循单向依赖原则(如上层模块不依赖下层模块)。
- 使用
70. webpack中如何配置图片的base64编码转换的阈值?
配置图片base64编码阈值可通过asset/inline
或url-loader
实现,步骤如下:
-
使用webpack 5内置的asset模块:
javascriptmodule.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/i, type: 'asset', // 自动在resource和inline之间选择 parser: { dataUrlCondition: { maxSize: 8 * 1024 // 小于8KB的图片转为base64(默认8KB) } } } ] } };
-
使用url-loader(适用于webpack 4及以下):
bashnpm install url-loader file-loader --save-dev
javascriptmodule.exports = { module: { rules: [ { test: /\.(png|jpg|gif)$/i, use: [ { loader: 'url-loader', options: { limit: 8192, // 小于8KB的图片转为base64 fallback: 'file-loader' // 超过限制时使用file-loader } } ] } ] } };
-
在代码中使用 :
javascriptimport smallImage from './small.png'; // 小于阈值,返回base64字符串 import largeImage from './large.png'; // 大于阈值,返回文件路径
No. | 大剑师精品GIS教程推荐 |
---|---|
0 | 地图渲染基础- 【WebGL 教程】 - 【Canvas 教程】 - 【SVG 教程】 |
1 | Openlayers 【入门教程】 - 【源代码+示例 300+】 |
2 | Leaflet 【入门教程】 - 【源代码+图文示例 150+】 |
3 | MapboxGL 【入门教程】 - 【源代码+图文示例150+】 |
4 | Cesium 【入门教程】 - 【源代码+综合教程 200+】 |
5 | threejs 【中文API】 - 【源代码+图文示例200+】 |
6 | Shader 编程 【图文示例 100+】 |
71. 如何在webpack中禁用AMD和CommonJS模块语法?
禁用AMD和CommonJS模块语法可避免webpack错误解析模块,步骤如下:
-
禁用AMD:
javascriptmodule.exports = { module: { parser: { amd: false // 禁用AMD语法解析 } } };
-
禁用CommonJS:
javascriptmodule.exports = { module: { parser: { commonjs: false // 禁用CommonJS语法解析 } } };
-
同时禁用两者:
javascriptmodule.exports = { module: { rules: [ { test: /\.js$/, parser: { amd: false, commonjs: false } } ] } };
- 注意 :
-
禁用后,使用AMD或CommonJS语法的模块可能会报错,需确保项目仅使用ES6模块语法。
-
若需兼容部分模块,可使用
noParse
跳过特定文件的解析:javascriptmodule.exports = { module: { noParse: /jquery|lodash/ // 不解析这些模块中的任何语法 } };
-
72. 什么是webpack的noEmitOnErrors配置?
-
作用 :
noEmitOnErrors
(webpack 4及以下)或optimization.emitOnErrors
(webpack 5+)用于在编译出错时阻止生成输出文件,避免生成错误的打包文件。 -
配置示例:
-
webpack 4 :
javascriptmodule.exports = { stats: { errors: true // 显示错误信息 }, noEmitOnErrors: true // 出错时不生成输出文件 };
-
webpack 5 :
javascriptmodule.exports = { optimization: { emitOnErrors: false // 出错时不生成输出文件 } };
-
-
效果:
- 编译出错时,控制台会显示错误信息,且不会生成
dist
目录下的文件。 - 适用于生产环境构建,确保只有无错误的代码被部署。
- 编译出错时,控制台会显示错误信息,且不会生成
73. 如何在webpack中配置打包后的文件名?
配置打包后的文件名可通过output.filename
和output.chunkFilename
实现:
-
入口文件命名:
javascriptmodule.exports = { output: { filename: 'js/[name].[contenthash].js' // 如main.123abc.js } };
-
动态导入的异步chunk命名:
javascriptmodule.exports = { output: { chunkFilename: 'js/[name].[contenthash].chunk.js' // 如async-chunk.456def.js } };
-
基于内容哈希的命名:
javascriptoutput: { filename: '[contenthash].js' // 使用内容哈希作为文件名 }
-
自定义文件名:
javascriptoutput: { filename: (pathData) => { return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].[contenthash].js'; } }
-
开发环境使用易调试的文件名:
javascriptconst isProduction = process.env.NODE_ENV === 'production'; module.exports = { output: { filename: isProduction ? '[name].[contenthash].js' : '[name].js' } };
74. 如何实现webpack的多线程打包?使用什么loader或plugin?
实现多线程打包可显著提升大型项目的构建速度,常用工具:
-
thread-loader:
-
安装 :
bashnpm install thread-loader --save-dev
-
配置 :
javascriptmodule.exports = { module: { rules: [ { test: /\.js$/, include: path.resolve('src'), use: [ 'thread-loader', // 开启多线程 'babel-loader' ] } ] } };
-
配置参数 :
javascript{ loader: 'thread-loader', options: { workers: 3, // 开启3个worker(默认:CPU核心数-1) workerParallelJobs: 50, // 每个worker处理的最大任务数 poolRespawn: false, // 处理完任务后是否销毁worker name: 'my-pool' // 池名称,用于调试 } }
-
-
parallel-webpack:
-
适用于多入口项目,并行构建多个入口:
javascriptconst ParallelWebpack = require('parallel-webpack'); module.exports = new ParallelWebpack({ // 多个配置 configs: [ { entry: './src/index.js' }, { entry: './src/admin.js' } ] });
-
-
terser-webpack-plugin:
-
并行压缩JS代码:
javascriptconst TerserPlugin = require('terser-webpack-plugin'); module.exports = { optimization: { minimizer: [ new TerserPlugin({ parallel: true // 开启并行压缩(默认:CPU核心数-1) }) ] } };
-
75. thread-loader的作用是什么?如何使用?
-
作用 :
thread-loader
将耗时的loader(如Babel、TypeScript编译)放到独立的worker线程池中执行,利用多核CPU加速构建。 -
使用场景:
- 大型项目的编译优化。
- 处理大量JS、TS文件时。
-
配置步骤:
-
安装:
bashnpm install thread-loader --save-dev
-
在loader链中添加thread-loader:
javascriptmodule.exports = { module: { rules: [ { test: /\.js$/, include: path.resolve('src'), use: [ 'thread-loader', // 必须放在耗时loader之前 'babel-loader' // 耗时的loader ] } ] } };
-
配置thread-loader参数:
javascript{ loader: 'thread-loader', options: { workers: 3, // 开启3个worker workerParallelJobs: 50, // 每个worker处理的最大任务数 poolTimeout: 2000, // 闲置时保持worker的时间(毫秒) name: 'my-pool' // 池名称,用于调试 } }
-
-
注意事项:
- thread-loader会增加一些初始化开销,仅对耗时的loader使用。
- 避免在开发环境频繁重启worker,可设置
poolTimeout: Infinity
。 - 不适用于需要共享状态的loader(如style-loader)。
76. 什么是webpack的缓存组(cacheGroups)?
-
定义 :
cacheGroups
是splitChunks
配置的一部分,用于按规则分组拆分代码块,提取公共模块或第三方库。 -
作用:
- 控制哪些模块应该被拆分成独立的chunk。
- 优化缓存策略(如将不常变化的第三方库单独打包)。
-
配置示例:
javascriptoptimization: { splitChunks: { cacheGroups: { // 提取node_modules中的模块到vendor chunk vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendors', chunks: 'all', priority: -10 // 优先级 }, // 提取至少被引用2次的公共模块 common: { minChunks: 2, name: 'common', chunks: 'all', priority: -20, reuseExistingChunk: true // 复用已有的chunk }, // 提取CSS到单独文件 styles: { test: /\.css$/, name: 'styles', chunks: 'all', enforce: true } } } }
-
常用配置项:
test
:匹配模块的规则(如正则表达式)。name
:生成的chunk名称。chunks
:适用的chunk类型(async
、initial
、all
)。priority
:优先级(数字越大越优先)。minChunks
:模块被引用的最小次数。reuseExistingChunk
:是否复用已有的chunk。
77. 如何在webpack中配置对Node.js内置模块的处理?
配置Node.js内置模块的处理需通过resolve.fallback
和node
选项,步骤如下:
-
webpack 5+配置:
javascriptconst path = require('path'); module.exports = { resolve: { fallback: { // 按需配置需要的内置模块 fs: false, // 不 polyfill fs 模块 path: require.resolve('path-browserify'), // 使用path-browserify替代 crypto: require.resolve('crypto-browserify'), stream: require.resolve('stream-browserify') } }, plugins: [ // 为某些模块提供全局变量 new webpack.ProvidePlugin({ process: 'process/browser', Buffer: ['buffer', 'Buffer'] }) ] };
-
安装必要的polyfill包:
bashnpm install path-browserify crypto-browserify stream-browserify process buffer --save-dev
-
webpack 4及以下配置:
javascriptmodule.exports = { node: { fs: 'empty', // 不打包fs模块 path: 'mock', // 使用模拟的path模块 process: true // 包含process全局变量 } };
- 注意 :
- 浏览器环境不支持Node.js的所有内置模块(如
fs
、child_process
),需谨慎使用。 - 过度使用polyfill会增加打包体积,优先考虑使用纯前端替代方案。
- 浏览器环境不支持Node.js的所有内置模块(如
78. webpack中如何处理WebAssembly模块?
处理WebAssembly(.wasm)模块需配置适当的loader或使用webpack 5的内置支持,步骤如下:
-
webpack 5+内置支持:
javascriptmodule.exports = { experiments: { asyncWebAssembly: true // 启用异步WebAssembly支持 } };
在代码中使用:
javascriptimport init from './module.wasm'; async function run() { const instance = await init(); console.log(instance.exports.add(1, 2)); // 调用Wasm导出的函数 } run();
-
使用file-loader(适用于webpack 4及以下):
bashnpm install file-loader --save-dev
javascriptmodule.exports = { module: { rules: [ { test: /\.wasm$/, loader: 'file-loader', type: 'javascript/auto' // 防止webpack默认处理 } ] } };
在代码中使用:
javascriptimport wasmModule from './module.wasm'; fetch(wasmModule) .then(response => response.arrayBuffer()) .then(bytes => WebAssembly.instantiate(bytes)) .then(results => { console.log(results.instance.exports.add(1, 2)); });
-
同步WebAssembly(旧版):
javascriptmodule.exports = { experiments: { syncWebAssembly: true // 启用同步WebAssembly(不推荐,性能较差) } };
在代码中使用:
javascriptimport('./module.wasm').then(({ instance }) => { console.log(instance.exports.add(1, 2)); });
79. 如何在webpack中配置支持PWA?
配置PWA(渐进式Web应用)需添加Service Worker和相关配置,步骤如下:
-
安装workbox-webpack-plugin:
bashnpm install workbox-webpack-plugin --save-dev
-
配置webpack:
javascriptconst WorkboxPlugin = require('workbox-webpack-plugin'); module.exports = { plugins: [ new WorkboxPlugin.GenerateSW({ clientsClaim: true, // 立即控制所有客户端 skipWaiting: true, // 跳过等待阶段 exclude: [/\.map$/, /asset-manifest\.json$/], // 排除不需要缓存的文件 runtimeCaching: [ { urlPattern: /^https:\/\/api\.example\.com/, // API请求缓存策略 handler: 'NetworkFirst' }, { urlPattern: /\.(?:png|jpg|jpeg|svg|gif)$/, // 图片缓存策略 handler: 'CacheFirst', options: { cacheName: 'images', expiration: { maxEntries: 100, maxAgeSeconds: 30 * 24 * 60 * 60 // 30天 } } } ] }) ] };
-
注册Service Worker:
javascript// src/index.js if ('serviceWorker' in navigator && process.env.NODE_ENV === 'production') { window.addEventListener('load', () => { navigator.serviceWorker.register('/service-worker.js') .then(registration => { console.log('Service Worker registered with scope:', registration.scope); }) .catch(error => { console.error('Service Worker registration failed:', error); }); }); }
-
添加manifest.json:
json{ "name": "My PWA", "short_name": "PWA", "icons": [ { "src": "icon-192x192.png", "sizes": "192x192", "type": "image/png" } ], "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#000000" }
-
在HTML中引用manifest:
html<link rel="manifest" href="/manifest.json">
80. 请描述一下webpack的打包流程。
webpack的打包流程可分为以下核心阶段:
-
初始化:
- 读取并解析webpack配置文件(如
webpack.config.js
)。 - 创建
Compiler
和Compilation
对象,初始化插件和配置参数。
- 读取并解析webpack配置文件(如
-
解析入口:
- 从入口文件(如
src/index.js
)开始,递归解析所有依赖的模块。 - 使用配置的loader处理不同类型的文件(如Babel处理JS,sass-loader处理SCSS)。
- 从入口文件(如
-
构建模块关系图:
- 分析模块间的依赖关系,构建抽象语法树(AST)。
- 处理动态导入(如
import('./module.js')
),创建新的代码块。
-
优化与分割:
- 应用
splitChunks
配置,提取公共模块和第三方库。 - 执行Tree-shaking,移除未使用的代码。
- 压缩和混淆代码(生产环境)。
- 应用
-
生成资源:
- 将处理后的模块合并为一个或多个bundle文件。
- 处理静态资源(如图片、字体),生成对应的输出文件。
-
输出文件:
- 根据配置的输出路径(如
dist/
),将生成的文件写入磁盘。
- 根据配置的输出路径(如
-
插件执行:
- 在打包过程的不同阶段触发插件钩子(如
compile
、emit
、done
)。 - 插件可修改打包结果(如添加额外文件、生成HTML模板)。
- 在打包过程的不同阶段触发插件钩子(如
-
关键概念:
- Loader:处理不同类型的文件(如将SCSS转为CSS)。
- Plugin:在打包生命周期的特定阶段执行自定义逻辑。
- Chunk:打包后的逻辑代码块,可能包含多个模块。
- Module:源代码中的模块(如一个JS文件)。
-
简化流程示意图:
入口文件 → 模块解析 → 依赖图构建 → 模块转换 → 代码分割 → 资源生成 → 输出文件