模块化 JavaScript - 除了 CommonJS 和 AMD 之外,还有啥方法可以考虑吗?

Posted

技术标签:

【中文标题】模块化 JavaScript - 除了 CommonJS 和 AMD 之外,还有啥方法可以考虑吗?【英文标题】:Modular JavaScript - are there any approaches apart CommonJS and AMD to consider?模块化 JavaScript - 除了 CommonJS 和 AMD 之外,还有什么方法可以考虑吗? 【发布时间】:2015-01-14 03:54:50 【问题描述】:

我目前正在为我的公司准备评估 javascript 模块化方法。我们正在为我们的项目定义“JavaScript 最佳实践”,模块化是核心问题之一。

到目前为止,我的研究揭示了两种主要方法:

amd commonjs

周围有大量的加载器、插件、库等。

除此之外还有来自Google Closure Library的goog.provide/goog.require

还有其他方法可以考虑吗?我错过了任何重要/相关的规范吗?

我们的要求,简要:

在单独的文件中构建 JavaScript 代码。 在运行时加载相关模块。 ...无需将每个文件都包含为脚本标签。 不必维护 JavaScript 文件的索引。 支持聚合和缩小 - 能够构建和使用单个缩小/优化的 JavaScript 文件。 能够以不同的组合使用模块 - 通常有不同的网页/客户端需要不同的模块子集。 支持文档(带有 JSDoc?)。 适合测试。 适用于网页、跨浏览器。 合理的 IDE 支持。

可能:

与 ES6 模块保持一致。 适用于 Node.js 和移动平台(如 PhoneGap/Cordova)。

来自答案的新建议:

ecmascript-harmony 加上额外的编译器。 angularjs(请参阅下面的注释)。 extjs(请参阅下面的注释)。

旁注:

问题不是关于哪种方法更好。 我要求的不是特定的库和工具,而是方法和规范。 我并不是专门要求提供场外资源。 (如果没有SO标签,我们可能不合理考虑。) 关于angualjs 或extjs 等框架的说明。这在 this 问题的框架中并不合适。如果项目需要一个框架(无论是 AngularJS 还是 ExtJS),那么几乎没有模块化问题,因为框架必须提供模块化 OOTB。如果项目不需要框架,由于模块化,带框架就大材小用了。这是我特别询问库/工具的原因之一。

【问题讨论】:

@closer 我特别不征求意见。 这个问题属于 Programmers.Stackexchange 见medium.com/@trek/…。另外,我不太清楚为什么您将“与 ES6 模块对齐”作为“潜在要求”,而它本身就是一个解决方案,与 Traceur 等 ES6 转译器配合使用。 您是否考虑过“什么都不做”满足您所有要求的可能性? @self 我没有发明另一种模式,我想评估现有模式。为此,我必须知道存在哪些模式。我个人知识有限,所以我问社区。​​span> 【参考方案1】:

ES Harmony 怎么样?

从这里引用:http://addyosmani.com/writing-modular-js/

注意:虽然 Harmony 仍处于提案阶段,但您可以 已经尝试了 ES.next 的(部分)特性来解决原生问题 感谢 Google 的 Traceur,支持编写模块化 JavaScript 编译器。要在一分钟内启动并运行 Traceur,请阅读 本入门指南。还有一个关于 JSConf 的演示文稿 如果您有兴趣了解更多关于 项目。

希望帮助

【讨论】:

一个很好的链接,谢谢。 ES Harmony 是要考虑的。缺点是一个额外的构建步骤,对于 JS 文件少且受众少的项目(我们有一个由 1Mio 项目)来说,这可能是一种过度杀伤。 从我的 PoV 来看,这是最好的答案。您提出了问题中未考虑的方法。【参考方案2】:

另一种选择:AngularJS 模块系统,如 here 所述。然而,这实际上只在客户端有用。

【讨论】:

请在框架上查看this comment。 (响应 ExtJS 的建议,但也适用于 AngularJS。)【参考方案3】:

您写道:“我不是要特定的库和工具,而是要方法和规范。”但是,您可以更接近满足您所有要求的 ExtJS 5 环境。

如果您对此类商业产品不感兴趣,您可以了解其中的模式和解决方案。

与您的要求有关:

在单独的文件中构建 JavaScript 代码。

它实现了面向对象的编程范式,因此您可以创建类、子类、对象、mixin、插件。它连接class-based programming and prototype-based programming。

值得注意的 MVVM 架构(视图、控制器、ViewModel)、数据绑定、数据会话(记录/实体客户端管理)。

配置系统也很有趣。它非常方便。 config 属性从父类合并到子类,并且在对象创建期间您也可以传递将被合并的配置。当我们想要拥有可定制和灵活的组件时,它非常有用。

在运行时加载相关模块。

每个类可能有requiresuses 指令,用于将应用程序构建到一个文件中。您也可以手动加载文件。

...不必将每个文件都包含为脚本标签。

在 dev env 文件中动态加载(异步或同步)。

在 prod env 中,必要的文件已构建到一个缩小文件中。

支持聚合和缩小 - 能够构建和使用单个缩小/优化的 JavaScript 文件。

您可以使用Sencha cmd 工具构建应用程序(并做一些其他事情)。

您可以使用三个预定义的环境(开发、测试、生产)或创建自己的环境(基于配置文件和 ant)。

能够以不同的组合使用模块 - 通常有不同的网页/客户端需要不同的模块子集。

您可以使用workspaces 和packages。

支持文档(带有 JSDoc?)。

JS Duck, tutorial

适合测试。

你可以做unit tests(PhantomJS、JSLint、PhantomLint、Jasmine)。

您可以使用 Siesta 等专用框架或 Selenium 等其他流行的测试框架。

适合网页,跨浏览器。

来自官方网站:

在最广泛的浏览器和操作系统上提供应用程序 使用单一代码库。 Ext JS 5 利用现代的 html5 特性 浏览器,同时保持旧版的兼容性和功能 浏览器。自信地向您的最终用户交付应用程序,无论 他们使用的是什么浏览器。

支持: Safari 6+、Firefox、IE 8+、Chrome、Opera 12+、Safari/ios、Safari/iOS 6+、Chrome/android、Chrome/Android 4.1+、IE 10+/Win 8

支持Cordova and PhoneGap application。

合理的 IDE 支持。

我不知道专门支持 ExtJS 的非常好的 IDE,但我在 Webstorm 上工作,这很好。库源位于项目内部,因此自动完成功能有效(但不是 100% 完美)。

结论

我不想赞美 ExtJS 5。环境相当成熟和稳定,但最新版本的框架 (v5) 有几个错误,并不是一切都很好。但是,我可以更深入地了解该框架的原则,这些原则是合理的,朝着好的方向发展,但有时实施得不好;)

【讨论】:

感谢您的详尽回答。恐怕,在模块化问题的框架中,ExtJS 太大而无法考虑。它是一个成熟的框架。 “哪个框架?”是另一个问题。如果项目需要一个框架(无论是 AngularJS 还是 ExtJS),那么就不存在模块化问题,因为该框架提供了模块化 OOTB。如果项目不需要框架,由于模块化,带框架就大材小用了。 @lexicore 我同意,但是如果你知道一些框架,那么你的应用程序有多大没有区别。大多数框架都可以用于小型和大型项目。您的要求非常复杂,只能通过许多工具或一个好的框架来满足;)【参考方案4】:

RequireJS 是一个很好的方法,因为它支持动态 javascript 模块加载以及保持代码整洁。您还可以缩小整个模块,它实际上执行得非常快。它还允许称为 shimming 的东西,您可以在其中指定库或任何 js 文件的依赖项,这样每当您尝试加载它时,所有依赖项也会遵循

【讨论】:

谢谢。 RequireJS 是amd,所以在问题中涵盖。【参考方案5】:

看看systemJS:

符合规范的通用模块加载器 - 加载 ES6 模块、AMD、 CommonJS 和全局脚本。

设计为 ES6 规范的小型扩展集合 系统加载器,也可以单独应用。

通过自动检测格式加载任何模块格式。 模块还可以使用元配置指定它们的格式。提供 AMD、CommonJS 和 ES6 循环的全面而准确的复制 参考处理。加载编译成的 ES6 模块 System.注册表生产,保持完整的循环 参考支持。支持 RequireJS 风格的地图、路径、包、垫片 和插件。跟踪包版本,并解决 semver-compatibile 通过包版本语法请求 - package@x.y.z, 包^@x.y.z。加载器插件允许通过模块加载资产 命名系统,例如 CSS、JSON 或图像。旨在与 ES6 Module Loader polyfill (9KB) 的总占用空间为 16KB 压缩和压缩。将来,通过本机实现, 不再需要 ES6 模块加载器 polyfill。作为 jQuery 提供了 DOM,这个库可以平滑不一致的地方 并且缺少原生系统提供的实用功能 装载机。

在 IE8+ 和 NodeJS 中运行。

lib 的创建者 Guy Bedford 也是一位出色的演示者:systemJS presentation。

【讨论】:

@lexicore 它不同于常规的现代浏览器。看看 Bedford 的演示文稿 - 它非常棒。 感谢您的澄清。它应该在页面上更正,我会提出一个问题。这显然是误导...【参考方案6】:

看看browserify。它实现了有趣的方法。使用 browserify,您可以编写使用 require 的代码,就像在 Node 中使用它一样。

【讨论】:

Browserify 主要是 CJS 加上 AMD via deamdify,所以已经在问题中讨论过了。 Browserify 是个好东西。【参考方案7】:

有多种可用于模块化开发的库, 其中一些完全符合您的标准。

System.js System.js 是模块化开发库,具有一些基本功能,可用于 IE8+ 和 nodejs。它还提供开发模块的功能,您可以将其包含在主文件中。有关 System.js 的更多信息,请关注https://github.com/systemjs/systemjs Require.js 模块化开发的最佳库。提供各种有用的功能并支持旧版浏览器。它支持 IE 6+。 require.js 的另一个有用特性是它可以与 Rhinojs 和 nodejs 一起使用。实现很简单,就像在 nodejs 中包含模块一样。

【讨论】:

以上是关于模块化 JavaScript - 除了 CommonJS 和 AMD 之外,还有啥方法可以考虑吗?的主要内容,如果未能解决你的问题,请参考以下文章

webpack

require与import的区别和使用(CommonJS规范和es6规范)

java 11 移除的一些其他内容,更简化的编译运行程序,Unicode 10,移除了不太使用的JavaEE模块和CORBA技术,废除Nashorn javascript引擎,不建议使用Pack200

造轮子和用轮子:快速入门JavaScript模块化

JavaScript架构设计 1.种子模块

java Examples-src-Main-Utilities-CommonProperties.java