Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >webpack 最简静态资源打包及运行时分析

webpack 最简静态资源打包及运行时分析

作者头像
山月
发布于 2022-11-02 08:44:15
发布于 2022-11-02 08:44:15
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

使用 webpack 对最简单的静态资源打包,观察其配置与运行时代码。

我们使用 webpack 打包两个文件,index.jssum.js,并通过脚本文件 build.js 进行打包。

源码见 node-examples:webpack/cjs1

以下是 index.js 文件内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const sum = require('./sum')

console.log(sum(3, 8))

以下是 sum.js 文件内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = (...args) => args.reduce((x, y) => x + y, 0)

同时编写脚本文件 build.js 用以打包。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
webpack({
  entry: './index.js',
  mode: 'none',
  output: {
    iife: false,
    pathinfo: 'verbose'
  }
})

1. webpack 运行时代码

在前端,经常会听到一个词:打包器,而 webpack 是其中影响力最大的打包器。

如以上示例,index.jssum.js 两个文件将被打包成 dist/main.js 一个文件。

dist/main.js 的骨架代码包含了一些 webpack 如何将多个模块集合在一起的代码,被称为运行时代码。

main.js 文件内容见 main.js2,总共 55 行。

为了更好地理解运行时代码,可在 vscode/chrome 中对其文件进行调试,可参考在 VS Code 中如何调试 Node.js3。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/******/ var __webpack_modules__ = ([
/* 0 */,
/* 1 */
/*!****************!*\
  !*** ./sum.js ***!
  \****************/
/*! unknown exports (runtime-defined) */
/*! runtime requirements: module */
/*! CommonJS bailout: module.exports is used directly at 1:0-14 */
/***/ ((module) => {

module.exports = (...args) => args.reduce((x, y) => x + y, 0)

/***/ })
/******/ ]);
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/ 
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/  // Check if module is in cache
/******/  var cachedModule = __webpack_module_cache__[moduleId];
/******/  if (cachedModule !== undefined) {
/******/   return cachedModule.exports;
/******/  }
/******/  // Create a new module (and put it into the cache)
/******/  var module = __webpack_module_cache__[moduleId] = {
/******/   // no module.id needed
/******/   // no module.loaded needed
/******/   exports: {}
/******/  };
/******/ 
/******/  // Execute the module function
/******/  __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 
/******/  // Return the exports of the module
/******/  return module.exports;
/******/ }
/******/ 
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
/*!******************!*\
  !*** ./index.js ***!
  \******************/
/*! unknown exports (runtime-defined) */
/*! runtime requirements: __webpack_require__ */
const sum = __webpack_require__(/*! ./sum */ 1)

sum(3, 8)

})();

2. 运行时代码分析

webpack 的 runtime,也就是 webpack 最后生成的代码,做了以下三件事:

  1. __webpack_modules__: 维护一个所有模块的数组。将入口模块解析为 AST,根据 AST 深度优先搜索所有的模块,并构建出这个模块数组。每个模块都由一个包裹函数 (module, module.exports, __webpack_require__) 对模块进行包裹构成。
  2. __webpack_require__(moduleId): 手动实现加载一个模块。对已加载过的模块进行缓存,对未加载过的模块,执行 id 定位到 __webpack_modules__ 中的包裹函数,执行并返回 module.exports,并缓存。
  3. __webpack_require__(0): 运行第一个模块,即运行入口模块。

Q:你了解 Node.js 中的 module wrapper 吗?

另外,当涉及到多个 chunk 的打包方式中,比如 code spliting,webpack 中会有 jsonp 加载 chunk 的运行时代码。

webpack runtime 做进一步精简,代码如下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const __webpack_modules__ = [() => {}]
const __webpack_require__ = id => {
  const module = { exports: {} }
  const m = __webpack_modules__[id](module, __webpack_require__)
  return module.exports
}

__webpack_require__(0)

3. 作业

  1. webpack 运行时代码进行调试与理解
  2. webpack 的模块加载器是如何实现的
  3. webpack 的运行时代码做了那些事情
  4. 如何根据入口文件搜索出所有需要打包的模块
  5. 如何模拟实现运行时代码的生成

参考资料

[1]

node-examples:webpack/cjs:https://github.com/shfshanyue/node-examples/tree/master/engineering/webpack/cjs

[2]

main.js:https://github.com/shfshanyue/node-examples/blob/master/engineering/webpack/cjs/example/main.js

[3]

在 VS Code 中如何调试 Node.js:https://shanyue.tech/node/vscode-debug.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈成长之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
揭秘webpack5模块打包
​在上一节中我们初步了解了webpack可以利用内置静态模块类型(asset module type)来处理资源文件,我们所知道的本地服务,资源的压缩,代码分割,在webpack构建的工程中有一个比较显著的特征是,模块化,要么commonjs要么esModule,在开发环境我们都是基于这两种,那么通过webpack打包后,如何让其支持浏览器能正常的加载两种不同的模式呢?
Maic
2022/07/28
9900
揭秘webpack5模块打包
Webpack打包commonjs和esmodule混用模块的产物对比
接 Webpack 打包 commonjs 和 esmodule 模块的产物对比 继续,这篇文章来测试下 commonjs 模块和 esmodule 混用的情况,也就是 import 导入 commonjs 的模块,require 导入 esomodule 的模块,看一下它们在 Webpack 下的产物。
windliang
2022/09/23
1.8K0
Webpack打包commonjs和esmodule混用模块的产物对比
《Webpack实战 入门、进阶与调优(第2版)》- 第一章 webpack简介之打包代码分析
用户6256742
2024/06/22
2380
Webpack 原理系列六: 彻底理解 Webpack 运行时
在上一篇文章 有点难的 webpack 知识点:Chunk 分包规则详解 中,我们详细讲解了 Webpack 默认的分包规则,以及一部分 seal 阶段的执行逻辑,现在我们将按 Webpack 的执行流程,继续往下深度分析实现原理,具体内容包括:
Tecvan
2021/12/09
1.6K0
Webpack 原理系列六: 彻底理解 Webpack 运行时
【模块化】:Webpack 是如何将不同规范(ESM、CJS、UMD、AMD、CMD)的模块化代码打包到一起并协调它们运行的?
在一个项目中同时使用 ES6、CJS、CMD、AMD、UMD 5种不同的模块化规范编写代码,并同时应用静态导入、动态导入(Dynamic Import)方法来引用这些模块。观察 Webpack 是如何将这些不同模块化规范的代码打包到一起和协调它们运行的。
WEBJ2EE
2022/03/30
7.4K2
【模块化】:Webpack 是如何将不同规范(ESM、CJS、UMD、AMD、CMD)的模块化代码打包到一起并协调它们运行的?
Webpack 打包 commonjs 和 esmodule 动态引入模块的产物对比
接 Webpack 打包 commonjs 和 esmodule 模块的产物对比 我们来继续分析。这篇文章主要来看一下动态引入,允许我们引入的模块名包含变量。
windliang
2022/09/23
9870
Webpack 打包 commonjs 和 esmodule 动态引入模块的产物对比
webpack学习笔记
原始开发模式各种js文件引入,顺序不能乱,引入的数据太大,各种js之间有关联,可以考虑所有文件复制到一个js文件里,但又有作用域问题、文件太大、可维护性差
kif
2023/02/27
3020
webpack学习笔记
Webpack 打包 commonjs 和 esmodule 模块的产物对比
这篇文章不涉及 Webpack 的原理,只是观察下 Webpack 对 commonjs 和 esmodule 模块打包后的产物,读完后会对模块系统有个更深的了解。
windliang
2022/09/23
6890
Webpack 打包 commonjs 和 esmodule 模块的产物对比
Webpack 模块化原理和SourceMap
原创不易,未经作者允许禁止转载!! Webpack模块化 Webpack打包的代码,允许我们使用各种各样的模块化,但是最常用的是CommonJS、ES Module。 包括如下原理: CommonJS模块化实现原理; ES Module实现原理; CommonJS加载ES Module的原理; ES Module加载CommonJS的原理; CommonJS: 打包前 const { dateFormat, priceFormat } = require('./js/format'); console.
前端LeBron
2021/12/08
5890
Webpack完整打包流程分析
webpack 在前端工程领域起到了中流砥柱的作用,理解它的内部实现机制会对你的工程建设提供很大的帮助(不论是定制功能还是优化打包)。
gogo2027
2022/10/21
1K0
ESM 是如何被 webpack 打包成 CommonJS 格式的
虽然现代主流浏览器已支持 ESM,但 webpack 仍然会将 ESM 转化为 CommonJS,并注入到运行时代码。
山月
2022/11/02
1.7K0
ESM 是如何被 webpack 打包成 CommonJS 格式的
webpack打包出来的文件都是啥
删除掉没用到的 __webpack_require__.d、__webpack_require__.r、 __webpack_require__.t、__webpack_require__.n 、__webpack_require__.o 、 __webpack_require__.p,剩下的代码如下:
用户1515472
2019/07/24
1.3K0
Webapck5核心打包原理全流程解析
Webpack在前端前端构建工具中可以堪称中流砥柱般的存在,日常业务开发、前端基建工具、高级前端面试...任何场景都会出现它的身影。
19组清风
2021/11/18
5790
Webapck5核心打包原理全流程解析
从微组件到代码共享
随着前端应用越来越复杂,越来越庞大。前有巨石应用像滚雪球一般不断的叠高,后有中后台应用随着历史长河不断地积累负债,或者急需得到改善。微前端的工程方案在前端er心中像一道曙光不断的被提起,被实践,多年至今终于有了比较好的指引。它在解决大型应用之间复杂的依赖关系,或是解决我们技术栈的迁移历史负担,都在一定程度上扮演了极其关键的桥梁。
用户6835371
2021/09/03
1.9K0
从微组件到代码共享
构建打包工具Rollup.js入门指南
最近在看Vue源码的时候发现一个新的打包工具Rollup.js,之前没有听说过这个工具,也不了解Rollup.js相比于常用的打包工具webpack有什么异同和优势,随后查了一下了解到Vue,React,D3,Three.js,Moment源码里都有它的身影,Rollup到底什么?这篇文章带你走进Rollup的世界。
用户1462769
2019/08/12
2.9K0
构建打包工具Rollup.js入门指南
自己实现一个简易的模块打包器(干货)
作者:海因斯坦,原文链接:https://juejin.im/post/6893809205183479822
coder_koala
2020/12/17
6430
自己实现一个简易的模块打包器(干货)
webpack打包原理分析和实现(一)
首先,新建一个空文件夹,编辑器(webstrom)打开文件夹,执行npm init -y,生成package.json,在根目录新建webpack.config.js,加入如下代码(webpack 4.0的基础配置)
kiki.
2022/09/29
4110
多图详解,一次性搞懂Webpack Loader
Webpack 是一个模块化打包工具,它被广泛地应用在前端领域的大多数项目中。利用 Webpack 我们不仅可以打包 JS 文件,还可以打包图片、CSS、字体等其他类型的资源文件。而支持打包非 JS 文件的特性是基于 Loader 机制来实现的。因此要学好 Webpack,我们就需要掌握 Loader 机制。本文阿宝哥将带大家一起深入学习 Webpack 的 Loader 机制,阅读完本文你将了解以下内容:
童欧巴
2021/08/20
1.1K0
多图详解,一次性搞懂Webpack Loader
有点难的知识点: Webpack Chunk 分包规则详解
在前面系列文章提到,webpack 实现中,原始的资源模块以 Module 对象形式存在、流转、解析处理。
山月
2021/06/16
1.6K0
有点难的知识点: Webpack Chunk 分包规则详解
关于Rollup那些事
下一代打包工具,这是rollup对自己的定位。如今的前端领域,构建工具并不缺少,每个前端工程师都用过或者听过webpack。可以看到的是像React、Vue等框架的构建工具使用的都是rollup。既然如此,这些框架为什么会选择rollup?它的特性是什么?面对不同场景,我们要怎么选择构建工具?本文将一一为你呈现。
腾讯IVWEB团队
2020/06/24
7350
推荐阅读
相关推荐
揭秘webpack5模块打包
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档