webpack:// 到底是什么意思?

Ste*_*ett 3 javascript module firefox-developer-tools webpack

多年来,我一直使用捆绑 Webpack 的 Vue-CLI 构建应用程序。我看到这个前缀(协议?),webpack://但我实际上不知道它意味着什么。

例如,在为 app.xxx.js.map 生成的源映射中,我看到:

{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/App.vue?797c",...
Run Code Online (Sandbox Code Playgroud)

那么这webpack://到底是什么意思呢?这显然不是浏览器可以解析的真正协议。那么解决了吗?如何?

我遇到的具体问题导致我想要理解这一点,我生成的内容是chunk-vendors.8c348425.js.map这样开始的:

{"version":3,"sources":["webpack:///js/chunk-vendors.68249437.js"],...
Run Code Online (Sandbox Code Playgroud)

在这种情况下,任何地方都没有生成的chunk-vendors.68249437.js文件。应该有吗?或者这是一个抽象生成的名称,实际上并不引用真实的文件?

我在 FireFox 中看到一些错误,但我在解释时遇到了一些困难:

在此输入图像描述

我认为它是说它(以某种方式)运行不存在的 chunk-vendors.68249437.js 文件,并且无法获取某些(身份不明的)资源?

sup*_*610 7

tl;dr -webpack://是一个任意协议名称,可以与浏览器的源地图查看器很好地配合。在此前缀下嵌套每个文件名会将它们显示在单独的下拉列表中(webpack-demo在本例中):

chrome-source-map-filetree

Webpack(实际上是大多数 JS 捆绑器)采用一些未压缩的源文件,并将它们组合成一个*压缩的**捆绑文件,该文件可以由浏览器在单个网络请求中加载。

在较高级别上,源映射的存在允许开发人员轻松地将控制台消息和堆栈跟踪从包中的文件行/列号转换回源文件中的原始位置。这可能是简单的事情,比如“包中的第 1001 行实际上是 foo.js 中的第 500 行”,也可能是更棘手的事情,比如“第 1001-1021 行是 MyComponent.vue 中第 20 行的编译输出的一部分”。您可以阅读源映射的最新规范,但本质上它们包含三件事:

  1. 输出包文件的名称
  2. 用于生成捆绑包的输入文件的名称
  3. 将 (1) 中的每一行连接回 (2) 中的文件的编码映射数据

最简单的源映射看起来像这样(省略了除相关部分之外的所有部分):

{
  "file": "bundle.js",
  "sourceRoot": "/",
  "sources": ["foo.js", "bar.js"],
  "mappings": "..."
}
Run Code Online (Sandbox Code Playgroud)

foo.js当两个源文件和bar.js组合成单个捆绑文件 .时,会生成此映射bundle.js/foo.js当浏览器呈现此源映射时,它期望分别在和处找到原始源文件/bar.js

源映射可以包含文件的内容本身,而不是单独托管文件:

{
  "file": "bundle.js",
  "sources": ["foo.js", "bar.js"],
  "sourcesContent": ["/* foo.js contents */", "/* bar.js contents */"],
  "mappings": "..."
}
Run Code Online (Sandbox Code Playgroud)

渲染此源映射时,浏览器只是直接读取文件内容,而不是向另一个 URL 发出请求。中的文件名的sources顺序应与sourcesContent.

好吧,我们快到了。

只要文件内联在源映射中(sourcesContent已设置),文件名是任意的。换句话说,foo.js不必对应于名为 的真实文件foo.js,您可以轻松调用它foo/bar/baz/garply.xyz,并且任何源地图查看器渲染它都不会出现问题(请记住,文件内容按数组索引存储)。

大多数源地图查看器(我特别检查了 Chrome 和 Firefox)将根据其协议前缀在单独的下拉列表中显示源。webpack-demo上面的屏幕截图显示了嵌套在;下的许多文件。他们的所有sources条目都以 开头webpack://webpack-demo/...。协议是什么并不重要;协议是什么并不重要。foobar://工作原理也一样,但需要注意的是,每个唯一的协议前缀都会在源映射文件树中获得自己的下拉列表。事实上,你可以通过设置来自定义这个前缀devtoolModuleFilenameTemplate(参见这里)。

因此,简而言之 -webpack://是一个任意的、唯一的前缀,用于将源文件嵌套在源映射文件树中自己的下拉列表中。后面的文件名通常webpack://与文件系统中的实际文件是1:1,但情况并非总是如此***。

* 好吧,代码分割是一件事,但在简单的情况下是单个捆绑文件。

** 捆绑包文件不必被压缩,它可以简单地将每个源文件一个接一个地连接起来,但实际上捆绑包通常通过一个或多个缩小/丑化过程运行。

*** Webpack 可以执行一个或多个中间压缩过程,将供应商文件集组合成块node_modules。我并不是 100% 了解这里的具体细节,但避免这种情况的一种方法是使用不同的devtool(请参见此处)。

  • 非常感谢,这真是一个非常好的答案。 (2认同)