create-react-app,webpack配置超强解析
0 条评论【create-react-app,webpack配置超强解析】【建议收藏】😎这一次再也不怕webpack面试了
掘金作者:吃饺子不吃馅原文链接:https://juejin.cn/post/7459740471654023220
Create React App (CRA) 是 React 官方推荐的脚手架工具,它封装了 Webpack、Babel、ESLint
等工具,提供了开箱即用的开发环境。虽然 CRA 隐藏了大部分配置细节,但在某些情况下,我们可能需要自定义 Webpack 配置。本文将详细解读 CRA 的
Webpack 配置文件,帮助你理解其工作原理和核心配置。
1. 配置文件概览
我们先用create-react-app创建一个项目,然后npm run eject,可以看到webpack的配置文件webpack.config.js
CRA 的 Webpack 配置它是一个函数,接收 webpackEnv 参数(表示当前环境,如 development 或production),并返回一个 Webpack 配置对象。
配置文件的主要部分包括:
- 入口和输出配置
- 模块解析规则
- 插件配置
- 优化配置
- 开发和生产环境的差异处理
- 缓存配置
2. 核心配置解析
2.1 入口和输出配置
入口(Entry)
1 | javascript 代码解读复制代码entry: paths.appIndexJs, |
paths.appIndexJs是应用的入口文件,通常是src/index.js或src/index.tsx。
输出(Output)
1 | javascript 代码解读复制代码output: { |
path:构建输出的目录,通常是build。filename:主 bundle 的文件名,生产环境使用哈希值以支持缓存。chunkFilename:异步加载的 chunk 文件名。assetModuleFilename:静态资源(如图片、字体)的输出路径和文件名。publicPath:静态资源的公共路径,通常与homepage配置相关。
2.2 模块解析规则【loader】
模块解析(resolve)
源码如下:
1 | javascript 代码解读复制代码resolve: { |
modules:模块查找路径,优先从node_modules和项目根目录的node_modules中查找。extensions:支持的扩展名,如.js、.jsx、.ts、.tsx。alias:路径别名,支持 React Native Web 和自定义别名。ModuleScopePlugin:限制模块导入范围,防止从src目录外导入模块。paths.appPackageJson:项目的package.json文件。reactRefreshRuntimeEntry:React 热更新的运行时入口文件。reactRefreshWebpackPluginRuntimeEntry:React 热更新插件的运行时入口文件。babelRuntimeEntry:Babel 运行时的入口文件。babelRuntimeEntryHelpers:Babel 运行时的辅助函数文件。babelRuntimeRegenerator:Babel 运行时的 regenerator 文件。
模块规则(Module Rules)
源码如下:
1 | javascript 代码解读复制代码 module: { |
module 是 Webpack 配置的核心部分,用于定义如何处理不同类型的文件(模块)。它包含两个主要属性:
strictExportPresence:设置为true,表示如果模块导出不存在,Webpack 会抛出错误。rules:定义了一系列规则(rules),每个规则指定了如何处理特定类型的文件。
接下来一个一个分析其作用
处理 Source Maps
1 | javascript 代码解读复制代码shouldUseSourceMap && { |
作用:在开发环境中,使用
source-map-loader加载 Source Maps,以便在调试时能够定位到源代码。enforce: 'pre':确保该 loader 在其他 loader 之前执行。exclude:排除@babel/runtime中的文件,避免重复处理。test:匹配 JavaScript、TypeScript 和 CSS 文件。
oneOf 规则
oneOf 是 Webpack 的一种优化机制,它会按顺序遍历规则列表,直到找到匹配的规则。如果没有匹配的规则,则使用最后的 file-loader。
处理 AVIF 图片
1 | javascript 代码解读复制代码{ |
作用:处理 AVIF 格式的图片。
type: 'asset':将文件作为资源处理,小于imageInlineSizeLimit的图片会转为 Base64 编码。mimetype:指定文件的 MIME 类型。
处理常见图片格式
1 | javascript 代码解读复制代码{ |
作用:处理 BMP、GIF、JPEG、PNG 等常见图片格式。
type: 'asset':将文件作为资源处理,小于imageInlineSizeLimit的图片会转为 Base64 编码。
处理 SVG 图片
1 | javascript 代码解读复制代码{ |
作用:处理 SVG 图片,并使用
@svgr/webpack将其转换为 React 组件。@svgr/webpack:将 SVG 文件转换为 React 组件。file-loader:处理 SVG 文件的静态资源路径。
处理应用代码(JavaScript/TypeScript)
1 | javascript 代码解读复制代码{ |
作用:使用 Babel 编译应用代码(JavaScript 和 TypeScript)。
include:仅处理src/目录下的文件。babel-loader:使用 Babel 编译代码。presets:使用babel-preset-react-app预设,支持 React 和 TypeScript。plugins:react-refresh/babel:在开发环境中启用 React 热更新。babel-plugin-transform-antd-resize-table:自定义插件,用于处理 Ant Design 表格组件的调整大小功能。
cacheDirectory:启用 Babel 缓存,加快构建速度。
处理第三方库代码
1 | javascript 代码解读复制代码{ |
作用:使用 Babel 编译第三方库代码。
exclude:排除@babel/runtime中的文件。presets:使用babel-preset-react-app/dependencies预设,仅编译标准的 ES 特性。
处理 CSS 文件
1 | javascript 代码解读复制代码{ |
- 作用:处理普通的 CSS 文件。
getStyleLoaders:返回一组 loader,包括style-loader、css-loader和
postcss-loader。
modules.mode: 'icss':启用 ICSS(Interoperable CSS)模式。
处理 CSS Modules
1 | javascript 代码解读复制代码{ |
作用:处理 CSS Modules 文件。
modules.mode: 'local':启用 CSS Modules 的局部作用域。getLocalIdent: 使用 CRA 的类名生成规则
处理 Sass 文件
1 | javascript 代码解读复制代码{ |
作用:处理普通的 Sass 文件。
sass-loader:将 Sass 编译为 CSS。
处理 Sass Modules
1 | javascript 代码解读复制代码{ |
作用:处理 Sass Modules 文件。
modules.mode: 'local':启用 CSS Modules 的局部作用域。
处理其他文件
1 | javascript 代码解读复制代码{ |
- 作用:处理其他类型的文件(如图片、字体等)。
type: 'asset/resource':将文件作为静态资源处理,并输出到指定目录。
2.3 插件配置【plugin】
源码如下:
1 | javascript 代码解读复制代码plugins: [ |
HtmlWebpackPlugin
1 | javascript 代码解读复制代码new HtmlWebpackPlugin( |
作用:生成
index.html文件,并自动注入打包后的 JavaScript 和 CSS 文件。配置:
inject: true:自动将生成的资源文件注入到 HTML 中。template: paths.appHtml:使用指定的 HTML 模板文件(通常是public/index.html)。minify:在生产环境中启用 HTML 压缩,移除注释、空白字符等。
InlineChunkHtmlPlugin
1 | javascript 代码解读复制代码isEnvProduction && |
作用:将 Webpack 的 runtime 代码内联到 HTML 中,减少网络请求。
条件:仅在生产环境且
shouldInlineRuntimeChunk为true时启用。参数:
HtmlWebpackPlugin:指定要操作的 HTML 插件。[/runtime-.+[.]js/]:匹配需要内联的 runtime 文件。
InterpolateHtmlPlugin
1 | javascript 代码解读复制代码new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw) |
作用:在 HTML 中插入环境变量。例如,
%PUBLIC_URL%会被替换为publicUrlOrPath。参数:
HtmlWebpackPlugin:指定要操作的 HTML 插件。env.raw:环境变量对象。
ModuleNotFoundPlugin
1 | javascript 代码解读复制代码new ModuleNotFoundPlugin(paths.appPath) |
作用:在模块未找到时提供更友好的错误提示,帮助开发者快速定位问题。
参数:
paths.appPath:项目的根目录。
DefinePlugin
1 | javascript 代码解读复制代码new webpack.DefinePlugin(env.stringified) |
- 作用:在编译时将环境变量注入到代码中。例如,
process.env.NODE_ENV会被替换为"production"或
"development"。
参数:
env.stringified:环境变量对象,键值对会被注入到代码中。
ReactRefreshWebpackPlugin
1 | javascript 代码解读复制代码isEnvDevelopment && |
作用:在开发环境中启用 React 组件的热更新(Hot Module Replacement, HMR)。
条件:仅在开发环境且
shouldUseReactRefresh为true时启用。参数:
overlay: false:禁用错误覆盖层。
CaseSensitivePathsPlugin
1 | javascript 代码解读复制代码isEnvDevelopment && new CaseSensitivePathsPlugin() |
作用:在开发环境中检查文件路径的大小写敏感性,避免因路径大小写不一致导致的错误。
条件:仅在开发环境中启用。
MiniCssExtractPlugin
1 | javascript 代码解读复制代码isEnvProduction && |
作用:将 CSS 提取为单独的文件,而不是内联到 JavaScript 中。
条件:仅在生产环境中启用。
参数:
filename:主 CSS 文件的输出路径和名称。chunkFilename:异步加载的 CSS 文件的输出路径和名称。
WebpackManifestPlugin
1 | javascript 代码解读复制代码new WebpackManifestPlugin({ |
作用:生成资源清单文件(
asset-manifest.json),记录所有打包后的资源文件及其路径。参数:
fileName:清单文件的名称。publicPath:资源的公共路径。generate:自定义清单文件的生成逻辑。
IgnorePlugin
1 | javascript 代码解读复制代码new webpack.IgnorePlugin({ |
作用:忽略
moment.js中的本地化文件,减少打包体积。参数:
resourceRegExp:匹配要忽略的资源。contextRegExp:匹配资源的上下文。
WorkboxWebpackPlugin.InjectManifest
1 | javascript 代码解读复制代码isEnvProduction && |
作用:生成 Service Worker 文件,支持 PWA(渐进式 Web 应用)。
条件:仅在生产环境且
swSrc文件存在时启用。参数:
swSrc:Service Worker 的源文件路径。dontCacheBustURLsMatching:匹配不需要缓存的文件。exclude:排除不需要缓存的文件。maximumFileSizeToCacheInBytes:设置缓存文件的最大大小。
ForkTsCheckerWebpackPlugin
1 | javascript 代码解读复制代码useTypeScript && |
作用:在单独的进程中检查 TypeScript 类型错误,提升构建速度。
条件:仅在项目使用 TypeScript 时启用。
参数:
async: isEnvDevelopment:在开发环境中异步检查类型错误。typescript:TypeScript 配置,包括路径、编译器选项等。issue:指定需要检查的文件范围。logger:控制日志输出。
ESLintPlugin
1 | javascript 代码解读复制代码!disableESLintPlugin && |
作用:在 Webpack 构建过程中运行 ESLint,检查代码规范。
条件:仅在未禁用 ESLint 时启用。
参数:
extensions:需要检查的文件扩展名。formatter:指定 ESLint 的输出格式。failOnError:在发现错误时是否终止构建。context:指定 ESLint 的工作目录。cache:启用 ESLint 缓存,提升检查速度。baseConfig:指定 ESLint 的基础配置。
2.4 优化配置
代码压缩
1 | javascript 代码解读复制代码optimization: { |
TerserPlugin:压缩 JavaScript 代码。CssMinimizerPlugin:压缩 CSS 代码。
代码分割
1 | javascript 代码解读复制代码splitChunks: { |
splitChunks:将公共代码提取到单独的 chunk 中。runtimeChunk:提取 Webpack 的 runtime 代码,减少重复加载。
2.5 缓存配置
1 | js 代码解读复制代码 cache: { |
缓存的作用
Webpack 的缓存机制可以显著提升构建性能,尤其是在大型项目中。它的核心作用包括:
减少重复编译:通过缓存已编译的模块,避免重复处理未变化的文件。
加快构建速度:在后续构建中直接使用缓存结果,减少构建时间。
支持增量构建:只重新编译变化的文件,而不是整个项目。
配置详解
type: 'filesystem'
1 | javascript 代码解读复制代码type: 'filesystem' |
作用:启用文件系统缓存,将缓存数据存储到磁盘中。
说明:
- Webpack 5 引入了持久化缓存功能,支持将缓存数据存储到文件系统中。
- 与内存缓存(
memory)相比,文件系统缓存在重启构建后仍然有效。
version: createEnvironmentHash(env.raw)
1 | javascript 代码解读复制代码version: createEnvironmentHash(env.raw) |
作用:为缓存生成一个唯一的版本标识符。
说明:
createEnvironmentHash是一个工具函数,用于根据环境变量(env.raw)生成哈希值。- 当环境变量发生变化时,缓存版本会更新,确保缓存数据的有效性。
cacheDirectory: paths.appWebpackCache
1 | javascript 代码解读复制代码cacheDirectory: paths.appWebpackCache |
作用:指定缓存文件的存储目录。
说明:
paths.appWebpackCache是缓存目录的路径,通常是node_modules/.cache/webpack。- 缓存文件会存储在该目录下,以便后续构建时复用。
store: 'pack'
1 | javascript 代码解读复制代码store: 'pack' |
作用:指定缓存存储的方式。
说明:
pack是 Webpack 5 中的一种缓存存储方式,它会将缓存数据打包成一个文件。- 这种方式可以减少文件数量,提升缓存读写效率。
buildDependencies
1 | javascript 代码解读复制代码buildDependencies: { |
- 作用:指定构建依赖,当这些依赖发生变化时,缓存会失效。
- 说明:
defaultWebpack: ['webpack/lib/']:将 Webpack 的核心库作为构建依赖。如果 Webpack
版本发生变化,缓存会失效。
- **`config:
[__filename]**:将当前配置文件(webpack.config.js`)作为构建依赖。如果配置文件发生变化,缓存会失效。
tsconfig: [paths.appTsConfig, paths.appJsConfig]:将 TypeScript
配置文件(tsconfig.json)和 JavaScript 配置文件(jsconfig.json)作为构建依赖。如果这些文件发生变化,缓存会失效。
- 本文链接:https://xuehuayu.cn/article/a91910b6.html
- 版权声明:① 标为原创的文章为博主原创,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接。② 部分文章内容由 AI 生成,内容仅供参考,请仔细甄别。③ 标为转载的文章来自网络,已标明出处,侵删。

