拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Webpack 5 源码导读:模块打包器 webpack 的安装、核心概念与源码实现

Webpack 5 源码导读模块打包器 webpack 的安装、核心概念与源码实现【免费下载链接】webpackA bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through loaders, modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff.项目地址: https://gitcode.com/GitHub_Trending/web/webpack本文以 webpack 仓库的 README 为主体系统讲解 webpack 的定位、安装方式、插件与 Loader 两大扩展机制、代码分割与产物优化等核心能力并结合lib/目录下的源码实现入口导出、配置默认值、缓存策略印证文档中的每项描述帮助读者既能快速上手使用又能深入理解其内部工作原理。一、webpack 是什么README 开篇对项目的定位是一句话Webpack is a module bundlerwebpack 是一个模块打包器其主要用途是把 JavaScript 文件打包后供浏览器使用同时它还能够转换、打包或封装几乎任何资源或静态资产。仓库根目录的 package.json 中的描述与之呼应Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand.当前仓库的版本为 5.110.3见 package.json主入口为lib/index.jsCLI 可执行文件由bin/webpack.js提供package.json的main与bin字段。README 中的 TL;DR 部分概括了 webpack 的五项核心能力多模块格式打包支持 ES Modules、CommonJS、AMD 三种模块格式且允许它们在同一个应用中混合使用代码分割可以生成单个 bundle也可以生成多个在运行时按需异步加载的 chunk从而减少首屏加载时间编译期依赖解析依赖关系在编译阶段就被解析确定从而缩减运行时代码体积Loader 预处理Loader 可以在编译期预处理文件例如 TypeScript 转 JavaScript、模板字符串编译为函数、图片转 Base64 等高度模块化的插件系统通过插件完成应用所需的其他一切工作。这五点能力都能在仓库源码中找到对应的实现落点lib/dependencies/目录下有 140 个依赖解析相关的文件Harmony、CommonJS、AMD 各自的依赖类型lib/optimize/SplitChunksPlugin.js负责代码分割lib/NormalModule.js与lib/NormalModuleFactory.js承载 Loader 管线而插件系统的核心抽象散落在 lib/index.js 导出的各类 Plugin 中。二、安装方式README 给出了两种安装命令使用 npmnpm install --save-dev webpack使用 yarnyarn add webpack --dev从 package.json 的engines字段可以看到webpack 要求 Node.js 版本10.13.0。安装完成后CLI 可通过bin/webpack.js直接调用若以编程方式集成则引用lib/index.js导出的 API。编程 API 的最小使用形态是调用webpack(options, callback)。从 lib/webpack.js 的源码可以看到其主流程先通过schemas/WebpackOptions.check.js做快速 schema 校验快速路径失败时再回退到完整的validateSchema然后经config/normalization.js归一化配置、config/defaults.js填充默认值最后由WebpackOptionsApply应用插件并创建Compiler如果传入的是数组配置则委托给MultiCompiler并行处理多个编译器实例。三、插件系统PluginsREADME 强调Webpack has a rich plugin interface. Most of the features within webpack itself use this plugin interface. This makes webpack very flexible.——webpack 内部的大多数功能本身就构建在插件接口之上这正是其灵活性的来源。从 lib/index.js 的导出清单可以直观验证这一点。webpack 以命名空间组织暴露了几乎全部的内置插件顶层BannerPlugin、CleanPlugin、DefinePlugin、IgnorePlugin、HotModuleReplacementPlugin、ProgressPlugin、ProvidePlugin、SourceMapDevToolPlugin、WatchIgnorePlugin、DllPlugin、ManifestPlugin、EntryPlugin等webpack.idsNamedModuleIdsPlugin、DeterministicChunkIdsPlugin等八种模块/chunk ID 策略插件webpack.optimizeModuleConcatenationPlugin即 scope hoisting、SplitChunksPlugin、RuntimeChunkPlugin、SideEffectsFlagPlugin、MinChunkSizePlugin、RealContentHashPlugin等webpack.container/webpack.sharingModule Federation 相关的ModuleFederationPlugin、ContainerPlugin、ConsumeSharedPlugin、ProvideSharedPluginwebpack.web/webpack.esm/webpack.node不同 target 的 chunk loading 运行时模块webpack.css/webpack.html实验性的原生 CSS/HTML 处理模块README 中也明确说明Webpack can generate HTML pages and extract CSS files itself, both experimental其syntax导出标注了experimental标记见 lib/index.js 中css与html命名空间的注释。所有插件都通过统一的 hook 机制基于tapable见package.json依赖挂接到编译流程中。README 还提到一个用于开发调试的工具tapable-tracer可实时追踪 tapable hook 的执行过程并收集结构化调用栈帮助构建高级插件时观察生命周期。仓库中所有内置插件均有对应的 TypeScript 声明文件位于 declarations/plugins 目录如 declarations/plugins/BannerPlugin.d.ts、declarations/plugins/ProgressPlugin.d.ts其 JSON Schema 位于 schemas/plugins39 组 .json/.js/.ts 三元组为第三方插件作者提供了参照样板。四、Loader把任意静态资源纳入打包README 对 Loader 的表述是Webpack enables the use of loaders to preprocess files. This allows you to bundle any static resource way beyond JavaScript. 并说明 Loader 有两种启用方式在require()语句中使用loadername!前缀通过 webpack 配置中的正则即module.rules自动匹配应用。一个典型的规则配置可以参考仓库自带示例 examples/loader/webpack.config.jsuse strict; /** type {import(webpack).Configuration} */ const config { // mode: development || production, module: { rules: [ { test: /\.css$/, loader: css-loader } ] } }; module.exports config;README 还区分了哪些模块类型不需要 LoaderJavaScript、JSON 和 asset modules 是原生支持的CSS 与 HTML 目前为实验性内置支持对应lib/css/与lib/html/目录而预处理器和模板引擎LESS、Sass、Pug、Handlebars、Markdown 等依然走 Loader 生态。仓库的 devDependencies 中实际挂载了css-loader、html-loader、webdiscus/pug-loader、coffee-loader、babel-loader等用于运行 examples/ 下约 70 个可执行示例覆盖 asset、code-splitting、typescript、wasm、worker、module-federation 等场景。Loader 在 webpack 内部由lib/NormalModule.js与lib/NormalModuleFactory.js驱动Loader 上下文类型声明见 declarations/LoaderContext.d.ts。规则匹配、编译器的实现位于 lib/rulesRuleSetCompiler等并有对应单测 test/RuleSetCompiler.unittest.js 与 test/LoaderRunner.unittest.js 验证行为。五、性能异步 I/O 与多级缓存README 在 Performance 一节写道Webpack uses async I/O and has multiple caching levels. This makes webpack fast and incredibly fast on incremental compilations.这句描述在源码中可以得到印证。lib/config/defaults.js 中的applyCacheDefaults函数约第 725 行起展示了缓存的分级逻辑当cache选项为真时根据cache.type区分memory内存缓存供 watch 增量编译使用与filesystem文件系统缓存并自动推导cacheDirectory——普通项目默认为cwd/.cache/webpackYarn PnP 项目则落在.pnp/.cache/webpackF(cache, cacheDirectory, ...)分支。文件级缓存策略的清理行为由FileCacheStrategy相关测试 test/PackFileCacheStrategyCleanup.test.js 与 test/Compiler-filesystem-caching.test.js 覆盖。从源码结构看缓存之上还叠加了模块级别的懒计算如lib/util/memoize.js、lib/util/LazySet.js与 I/O 层面的异步队列lib/util/中的AsyncQueue、Queue、Semaphore对应 test/AsyncQueue.unittest.js、test/Queue.unittest.js共同构成 README 所说的multiple caching levels。六、模块格式支持ES2015、CommonJS 与 AMDREADME 说明 webpack 开箱即用地支持 ES2015、CommonJS 和 AMD 三种模块格式It performs clever static analysis on the AST of your code. It even has an evaluation engine to evaluate simple expressions.这一能力的实现主体是 lib/javascript/JavascriptParser.js 及其配套的 AST 静态分析依赖acorn与es-module-lexer见 package.json。lib/dependencies/目录下按模块格式拆分为HarmonyImportDependency、CommonJsRequireDependency、AMDDefineDependency等约 140 个文件lib/index.js还导出了webpack.javascript.JavascriptParser供第三方直接扩展解析器。仓库自带示例 examples/harmony 与 examples/commonjs 分别演示了 ES Module 与 CommonJS 的打包行为examples/harmony-interop/则专门演示 CJS 与 ESM 互相 re-export 的互操作场景。七、代码分割Code SplittingREADME 的描述是webpack 允许把代码库拆分为多个 chunkchunk 在运行时异步加载从而降低初始加载时间。仓库中最典型的示例是 examples/code-splitting/example.jsvar a require(a); var b require(b); require.ensure([c], function(require) { require(b).xyz(); var d require(d); });其中require.ensure([c], ...)声明了一个异步边界c及边界内引入的d会被切分到独立 chunk 中在调用时通过运行时注入的 chunk loading 逻辑浏览器端默认 jsonp见 lib/web/JsonpChunkLoadingRuntimeModule.js按需加载。该示例的 webpack.config.js 中设置optimization.chunkIds: named目的是在不同构建模式下保持 chunk 文件名一致便于对比输出。更完整的分割能力由webpack.optimize.SplitChunksPlugin提供lib/optimize/SplitChunksPlugin.js支持cacheGroups等配置项仓库示例覆盖了多种切分策略examples/common-chunk-and-vendor-chunk公共 chunk 第三方 vendor、examples/code-splitting-depend-on-advancedchunk 间依赖、examples/extra-async-chunk额外异步 chunk、examples/http2-aggressive-splitting面向 HTTP/2 的激进切分。八、产物优化OptimizationsREADME 指出 webpack 可以通过去重高频使用的模块、压缩minify、以及让你完全控制哪些代码初始加载、哪些运行时加载来减小产物体积并能通过 hash 让 chunk 更利于缓存。对应到仓库实现模块去重与合并scope hoistingwebpack.optimize.ModuleConcatenationPluginlib/optimize/ConcatenatedModule.js把无副作用风险的模块内联合并消除模块包装函数。示例见 examples/scope-hoisting压缩package.json依赖中的minimizer-webpack-plugin提供了默认 Terser 压缩能力optimization.minimize默认在 production 模式开启缓存友好的内容 hashoptimization.realContentHash由 lib/optimize/RealContentHashPlugin.js 实现文件名模板[contenthash]由 lib/TemplatedPathPlugin.js 渲染examples/chunkhash 演示了[chunkhash]占位符的实际效果tree-shaking 基础webpack.optimize.SideEffectsFlagPluginlib/optimize/SideEffectsFlagPlugin.js结合package.json的sideEffects字段裁剪未使用的导出examples/harmony-unused 与 examples/cjs-tree-shaking 给出了对照演示。九、浏览器兼容性README 的 Browser Compatibility 一节给出两条硬性约束webpack 支持所有符合 ES5 规范的浏览器不支持 IE8 及以下使用import()或require.ensure()进行动态加载时浏览器必须提供Promise实现如需兼容老浏览器必须先加载 Promise polyfill。第 2 条在运行时可以得到印证动态 chunk 加载的运行时模块如lib/runtime/下的loadChunk相关实现普遍以 Promise 链组织异步流程。仓库的devDependencies中包含es6-promise-polyfill正是为这类兼容性测试准备的。十、从源码看整体结构对初次接触 webpack 源码的读者可以从以下路径建立全局认知均以仓库根目录为准lib/index.js公共 API 门面。所有导出均采用 getter memoize懒加载主函数webpack()通过lazyFunction(() require(./webpack))延迟初始化避免引入时的重型依赖开销lib/webpack.jsAPI 入口串联 schema 校验 → 配置归一化 → 默认值填充 →WebpackOptionsApply→Compilerlib/Compiler.js / lib/Compilation.js编译生命周期与产物Asset管理核心lib/NormalModule.js普通模块的 Loader 管线执行lib/runtime38 个运行时模块注入产物中的 chunk 加载、publicPath 解析等运行时代码lib/configdefaults.js负责按 mode 填充全部默认值mode: production下默认开启 minimize、hash 文件名等normalization.js负责入口格式等归一化。测试体系同样值得参考test/ 目录包含约 1800 个cases/用例验证各类模块格式与 Loader 组合、约 1 万个configCases/用例验证配置项行为、以及unittest/basictest/longtest三层测试文件package.json的 scripts 提供了test:unit、test:basic、test:integration等分层执行入口。十一、贡献与项目治理README 的 Contributing 部分欢迎文档更新、拼写修正、单元测试、issue 分诊等多种形式的贡献并约定自行开发的 Loader/插件遵循x-loader、x-webpack-plugin的命名规范。仓库内的 CONTRIBUTING.md、GOVERNANCE.md项目治理与 TSC 结构、WORKING_GROUP.mdCore Working Group 维护机制以及 RELEASE_SCHEDULE.md补丁版本随时发布、minor 版本每 4 周周四发布共同构成了完整的协作规范。README 还特别感谢了 GWT、webmake、browserify、require.js 等对 webpack 思想形成有影响的前驱项目。小结webpack 以模块打包器为核心定位通过插件 hook、Loader 规则、AST 静态分析与多级缓存四层机制把 ES Module/CommonJS/AMD 混合代码与任意静态资源统一编译为可按需加载的 chunk。阅读 README.md 建立概念框架后沿着 lib/index.js → lib/webpack.js → lib/Compiler.js 的主链路再结合 examples/ 下可按yarn build:examples运行的完整示例即可自上而下地把文档描述与源码实现逐一对应起来。【免费下载链接】webpackA bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through loaders, modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff.项目地址: https://gitcode.com/GitHub_Trending/web/webpack创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门