【问题标题】:Webpack: how does Webpack work internally? [closed]Webpack:Webpack 内部是如何工作的? [关闭]
【发布时间】:2017-03-26 12:19:26
【问题描述】:

据我了解,Webpack 是一个在项目中组织资产的工具。但是,我不明白它内部是如何工作的,看起来有点神奇。

  • 是否有某种运行时引擎解析模块或依赖项?
  • 它是在服务器上运行还是在客户端浏览器中运行?
    • 如果它在服务器上运行,它是否必须在某种webpack-*-server 上运行?
    • 如果它在浏览器中运行,它如何构建模块加载器映射?它是如何发送到浏览器的?

【问题讨论】:

  • 查看源代码:github.com/webpack 并阅读文档!
  • 我希望您能提供一个具体的文档位置。我已经深入那里,但我无法解决最后的问题。
  • 最后一点,它将您的javascript在本地处理成一个“包”。据我所知,没有客户端-服务器关系。
  • @PaulCollingwood 老实说,那些文档真的很糟糕。
  • 看看这个 50 分钟学习 webpack 视频教程youtube.com/watch?v=Lzh8A0p3z8g

标签: webpack


【解决方案1】:

Webpack - 为什么和如何

不要让自己对 Webpack 所做的所有花哨的东西感到困惑。 那么什么是 Webpack?好吧,它是一个模块捆绑器,我们开始了。开个玩笑,这根本不能告诉初学者。我相信为什么对于获取 webpack 很重要,所以这个答案的大部分内容将集中在这一点上。

Webpack 的核心允许我们在浏览器中使用 javascript 模块,方法是获取多个文件和资产并将它们组合成一个大文件,如下图所示,来自Webpack 2 的新文档。

所有额外的亮点,例如将 es6/7 编译为 es5 或允许我们使用 css 模块,都是 Webpack 为我们提供的很好的附加功能

强大的 Webpack 插件和附加功能生态系统让 Webpack 看起来很混乱,因为它似乎做了很多事情。虽然通过插件为我们提供的附加功能很棒,但我们需要专注于 Webpack 存在的核心原因 - 模块捆绑。因此,加载器和插件不在本次关于 Webpack 帮助解决的基本问题的高级讨论范围内。

Webpack 是一个用于创建资源包(代码和文件)的命令行工具。 Webpack 不在服务器或浏览器上运行。 Webpack 获取所有 javascript 文件和任何其他资产,然后转换为一个巨大的文件。

然后服务器可以将这个大文件发送到客户端的浏览器。 请记住,浏览器和服务器并不关心这个大文件是使用 Webpack 生成的,它只是像对待任何其他文件一样对待它。

webpack-dev-server vs webpack cli

webpack-dev-server 是一个与上面描述的 webpack cli(命令行工具)完全不同的工具。它是一个运行在 node/express 上的开发服务器。当这个服务器运行时,我们从这个开发服务器上的一个端口加载我们的应用程序,我们可以在开发我们的应用程序时访问其他功能,使我们的生活更轻松,例如热模块重新加载和自动捆绑(运行 webpack cli 以在文件时自动捆绑变化)。热模块重新加载的优点是我们可以保持应用程序运行并注入在运行时编辑的文件的新版本。因此,我们可以在不丢失整个应用程序状态的情况下看到应用程序中某些文件的变化情况。

原因

传统的服务器渲染应用

传统上,应用程序是在服务器端呈现的。这意味着客户端向服务器发出请求,所有逻辑都在服务器上。服务器将静态 html 页面返回给客户端,这是他们在浏览器中看到的内容。这就是为什么每当您在旧的服务器端呈现的应用程序中导航时,您都会看到页面在刷新时闪烁。

单页应用 - SPA

然而,如今单页应用程序风靡一时。在单页应用程序中,我们的应用程序在一个 url 中窗口化,我们永远不需要刷新。这对用户来说被认为是一种更好的体验,因为它不需要刷新就感觉更流畅。在 SPA 中,如果我们想从主页导航到登录页面,我们将导航到登录页面的 url。然而,与传统的服务器端呈现的页面不同,当客户端的浏览器发出此请求时,页面不会刷新。相反,应用程序将动态更新自身以显示登录内容。虽然这在我们的单页应用程序中看起来像是一个单独的页面,但我们的应用只是针对不同的页面动态更新。

动态 SPA 意味着浏览器中有更多代码

因此,在包含所有这些动态内容的 SPA 中,浏览器中的 JavaScript 代码要多得多。当我们说动态时,我们指的是以 javascript 形式存在于客户端浏览器中的逻辑数量。我们的服务器端渲染的应用程序会吐出非动态的静态页面。动态都发生在服务器中,同时生成静态页面,但是一旦它到达浏览器,它就相对静态(其中没有很多 javascript)

方法

管理大量新的浏览器逻辑,即更多的 Javascript

Webpack 的主要设计目的是应对客户端中包含越来越多 javascript 的新兴趋势。

好的,那么我们浏览器中有很多 javascript 为什么会出现这个问题?

我们需要在客户端将代码拆分成多个文件,以便应用更容易运行

好吧,我们把它放在哪里?我们可以将它们全部放在一个大文件中。但是,如果我们这样做,那么涉水并了解所有部分的工作原理将是一场噩梦。相反,我们需要根据每个块的功能将这一大块代码拆分成更小的块——即将代码拆分到多个文件中。

您可能知道,当我们谈论“使某物模块化”时,将大事物分解为按功能分组的小事物是我们的意思。你可能在想为什么不把一大块代码分成小块并完成它。问题是客户端并不神奇地知道哪些文件从其他文件导入内容。所以我们可以在没有 Webpack 的情况下拥有多个独立的文件,但是 该应用程序将无法正常工作,因为它很可能在大块代码中大部分代码将依赖于大块中的其他代码部分块工作

我们需要类似 Webpack 或其替代品之一(浏览器)来创建模块系统。 在服务器端 Node 有一个内置的模块解析器,您可以在其中“请求”模块。但是浏览器不具备此功能。

但是,如果我们有多个文件,一些文件会相互导入,我们需要一种方法来了解哪些文件相互依赖或依赖。 Webpack 允许我们通过从 入口点 遍历文件然后映射它们的依赖关系来在前端使用 JavaScript 模块。 将入口点视为相互依赖的文件链中层次结构的顶部。

Webpack 中的模块/依赖解析

通过绘制依赖关系图,Webpack 能够以正确的顺序异步和并行加载不同的模块。 Webpack 内部有自己的解析器,用于找出不同模块之间的依赖关系图。 webpack 文档声明

解析器帮助webpack找到需要的模块代码 包含在每个此类 require/import 语句的包中。

然后文档解释说,解析器根据 Webpack 捆绑的文件中导入引用的路径类型采用不同的方法。

解析过程非常简单,可以区分三种 请求类型:

  • 绝对路径:require("/home/me/file"), require("C:\Home\me\file")
  • 相对路径:require("../src/file"), require("./file") 模块路径:
  • require("module"), require("module/lib/file")

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 2016-07-04
  • 1970-01-01
  • 2016-04-13
相关资源
最近更新 更多