前端开发学习指南
程序包管理器,任务运行器和模块捆绑器是可用于依赖性管理的构建工具。 在本文中,我们将研究它们之间的区别以及在前端开发中使用它们可以实现什么。
什么是依赖管理?
依赖关系管理是自动化安装,更新,配置和删除应用程序依赖的库,程序包和工具的过程。 每种编程语言都有其自己的依赖性管理工具。 从Java,PHP到JavaScript。
我们将研究高层 前端开发中依赖管理的前景。 我们将分别讨论以下几组构建工具:
- 程序包管理器(npm,Yarn,pnpm)。
- 任务运行程序(Grunt,Gulp)—尽管这些不是依赖关系管理工具,但我们将简短地了解它们之间的区别。
- JavaScript模块加载器(RequireJS,Browserify)。
- 静态模块捆绑器(Webpack,Parcel)。
请注意,本文没有提供对特定工具的详细评论,而是打算展示不同类型的依赖项管理工具之间的相互关系。
前端的依赖管理
在前端,我们使用JavaScript依赖关系管理工具来保持依赖关系的控制。 这些工具大多数都是Node.js模块,可以与npm一起安装。npm是Node.js的默认程序包管理器,Node.js是一种运行时环境,可让您在Web浏览器之外执行脚本。
随着前端开发的进展,依赖管理变得越来越复杂。 市场上有许多竞争工具,它们执行相似的任务,但在某些方面也有所不同。 有时,依赖项管理工具在功能上也会与其他构建工具(例如自动任务运行器)重叠。
凉亭(RIP)
让我们从一些令人头疼的消息开始,这些消息显示了依赖管理的快速变化。 如果您遵循前端趋势,那么您肯定已经听说过曾经流行的前端软件包管理器Bower的弃用。 尽管Bower仍处于维护状态(因此您不必担心现有项目),但不建议将其用于新项目。
简而言之,Bower失去了与其他流行的依赖项管理解决方案的竞争,例如:
- npm和Browserify的强大结合,
- 性能优化的软件包管理器,例如Yarn和pnpm,
- 以及自动化的静态模块打包器,例如Webpack和Parcel。
结果,现在Bower团队还推荐了Yarn,Webpack和Parcel,甚至帮助从Bower迁移 。
包装经理
包管理器允许您以正确的顺序加载应用程序所依赖的所有依赖项(包,库,模块)。 它们还使您可以根据应用程序需求的变化来管理,更新,修改和删除软件包。 大多数软件包管理器借助依赖关系树来跟踪依赖关系。
npm
npm软件包管理器是大多数其他前端依赖项管理工具的基础。 这是因为它们大多数是可以使用npm安装的Node.js软件包。
npm很容易上手,因为它与Node.js打包在一起,您可以通过从Node.js的“下载”页面下载相应的安装程序(Windows,macOS,Linux)将其安装在操作系统上 。 在系统上安装Node.js后,您可以从命令行界面运行npm。
除了作为程序包管理器之外,npm还是开源Node程序包的注册表。 来自世界各地的开发人员可以上传npm软件包,您可以使用几个命令将其添加到应用程序中。 这样前端开发人员可以轻松访问高级工具,例如PostCSS和Grunt任务运行器。
关于npm的另一件重要事情是,它与Node.js生态系统相关。 结果,您可以使用它仅将Node.js包添加到您的应用程序。
当npm在Web浏览器外部建立其依赖关系树时,您需要将所有依赖关系添加到node_modules
文件夹中的应用程序。 由于此文件夹可以包含数百甚至数千个文件,因此npm经常与JavaScript模块捆绑器(如Browserify)一起使用,该捆绑器捆绑所有依赖项并将其作为静态文件提供给浏览器。
为了使包管理更有效,npm3引入了平面依赖树 ,该树取代了以前使用的嵌套树npm。 新功能导致更少的冗余和更时尚的node_modules
文件夹。 这就是Bower使用的依赖关系结构-通过npm采用该功能,Bower变得过时了。
纱线和pnpm
但是,npm仍然有很强的竞争力。 大多数替代软件包管理器(例如Yarn和pnpm )主要旨在提高性能,因为npm在这方面仍有改进的余地。 Yarn和pnpm也是Node.js软件包,因此您可以使用npm install
命令安装它们。 他们使用不同的技术可以加快完成时间。
当Yarn缓存程序包并并行化操作时,pnpm 返回嵌套的依赖关系,但方式不同。 它使用硬链接和符号链接的组合来保存每个模块的仅一个版本,这导致node_modules
文件夹小得多。
任务运行器(不用于依赖管理)
尽管诸如Grunt和Gulp之类的任务运行器无法处理依赖项,但它们经常与依赖项管理器混淆,因此让我们快速了解一下它们之间的区别。 任务运行程序和依赖项管理器都是构建工具,但是它们解决了一系列不同的问题。 当依赖关系管理器构建应用程序的依赖关系树并加载(有时捆绑)依赖关系时,任务运行程序会自动执行常规任务。
构建过程通常包含您需要定期执行的相同重复性任务,例如缩小,图像优化,CSS自动前缀,整理,单元测试等。 任务运行器使此过程自动化,并允许您创建一组自动化任务以节省手动工作。
混乱的根源
与依赖项管理器工具的混淆主要源于以下事实:任务运行程序还要求您以某种方式定义依赖项。 例如,如果您使用Grunt,则需要通过以下方式将依赖项添加到package.json
文件:
{
"name": "my-project-name",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.5",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-nodeunit": "~0.4.1",
"grunt-contrib-uglify": "~0.5.0"
},
"dependencies": {
"bootstrap": "^4.2.1",
"jquery": "^3.3.1"
}
}
但是, package.json
文件不管理依赖关系,它仅加载Grunt所需的Node.js模块,以执行Gruntfile中定义的任务列表。
JavaScript模块加载器
现在,让我们回到依赖管理工具,特别是JavaScript模块加载器。 Node.js具有方便的require()
方法,可让您轻松地将模块添加到应用程序中。 但是,由于Node.js在服务器端运行,因此您不能直接在浏览器中需要Node模块。 JavaScript模块加载程序(例如RequireJS和Browserify)提供了解决此问题的方法。
JavaScript模块加载器使您可以在客户端加载JavaScript依赖项。 这意味着巨大的性能提升,因为用户的浏览器是由包含所有依赖项并可以快速加载的静态JavaScript文件提供服务的。
RequireJS和Browserify
有趣的是, RequireJS在Node.js之前存在。 遵循AMD模块规范 ,将require()
方法引入浏览器。 Node.js在CommonJS之后实现了require()
功能, CommonJS是另一种JavaScript模块规范。
随着npm的出现,RequireJS的使用开始下降,但是它仍在开发中。 同样重要的是,默认情况下RequireJS 不是 Node模块(尽管它具有Node.js的实现 ),因此您还可以在Rhino等其他JavaScript环境中使用它。
与Node.js相似, Browserify也是CommonJS API的实现。 作为一个Node模块,Browserify使用Node.js的require()
方法,这就是为什么它经常与npm一起使用的原因。 要为用户提供静态依赖关系,您可以使用npm加载依赖关系,将其与Browserify捆绑在一起,然后将该捆绑包作为标记添加到HTML页面。
静态模块捆绑器
虽然JavaScript模块加载程序只能加载JavaScript模块,但是静态模块捆绑程序(例如Webpack和Parcel)可以捆绑任何种类的前端资产,例如图像,HTML,CSS,Sass和其他文件。 他们的目标是创建可以轻而易举地在用户浏览器中运行的静态资产。
在下面的屏幕截图中,您可以看到Webpack工作原理的逻辑:
Webpack和包裹
Webpack检查您的整个项目,生成依赖关系图,并创建一个或多个捆绑包,您可以将其添加到HTML文件中。 它具有许多高级功能,例如消除死代码,CSS文件的require()
方法,代码拆分等。
过去,Webpack的最大缺点是所需的配置量。 正确地建立Webpack项目需要大量的时间和知识。 新型的静态模块捆绑器Parcel提出了解决此问题的方法。 它引入了零配置模型,后来Webpack 4.0.0也采用了该模型。
要使用零配置功能,只需运行命令( webpack
或parcel build
),传递条目文件,然后捆绑程序会自动完成整个构建过程,与其他任何方法相比,可以节省大量时间和精力依赖管理解决方案。
结论
当前,静态模块捆绑包(例如Webpack和Parcel)是前端开发中最先进的依赖管理工具,因为它们使您可以快速捆绑所需的所有资产。 但是,对于更简单的应用程序或网站,您不一定需要它们。
如果您要使用的依赖项管理工具能够解决您需要的一切,那么继续使用它而不是选择新工具仍然是一个不错的决定!
翻译自: https://webdesign.tutsplus.com/tutorials/a-guide-to-dependency-management-in-front-end-development--cms-33963
前端开发学习指南