Webpack:webpack如何运作?

时间:2016-11-12 10:44:50

标签: webpack

到目前为止,我已经弄清楚了,webpack是一个工具,用于组织我们项目中的任何资产类型。不过,我不太猜测内部是如何工作的。对我来说,这似乎是一种神奇的东西,所以现在有点危险。

  • 是否有一些运行时引擎的王者正在解析模块或依赖项?
  • 它在哪里运行?在服务器上?在客户端浏览器上?
  • 如果它在服务器上运行,则必须运行某种相关的webpack-*-server
  • 如果它在客户端浏览器上运行,它如何构建任何类型的模块< - > loader< - > map?它是如何在浏览器上发送的?

1 个答案:

答案 0 :(得分:51)

Webpack - 为什么以及如何

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

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

Overview of Webpack

所有额外闪亮的东西,例如将es6 / 7转换为es5或允许我们使用css模块,都是Webpack提供给我们的很好的 extras

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

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

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

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

如何

管理这种新的丰富浏览器逻辑,即更多Javascript

Webpack主要用于处理客户端中越来越多javascript的新兴趋势。

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

我们需要将代码拆分为客户端上的多个文件,以便应用程序更易于使用

那么,我们把它放在哪里?我们可以把它全部放在一个大文件中。但是,如果我们这样做,那么通过它来理解所有部分的工作方式将是一场噩梦。相反,我们需要根据每个块的功能将这一大块代码拆分成更小的块 - 即将代码分割成多个文件。

正如你可能知道的那样,将大型事物分解为按功能分组的较小事物是我们在谈论“制造模块化事物”时的意思。您可能正在考虑为什么不将大块代码分成小块并完成它。问题是客户端并不神奇地知道哪些文件从其他文件导入内容。所以我们可以有多个没有Webpack的孤立文件,但应用程序不会正常工作,因为它很可能在大块代码中,其中大部分代码将依赖于其他代码部分工作的重要组成部分

我们需要像Webpack或其中一个替代品(browserify)来创建模块系统。 在服务器端,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")
  •