如何使用NodeJS组织构建、服务器、客户端和共享JavaScript代码。
如何使用NodeJS组织构建、服务器、客户端和共享JavaScript代码。
我一直认为在服务器上使用NodeJS的一个重要好处是可以在服务器和客户端之间共享代码片段(例如输入验证)。现在我真正在使用NodeJS进行开发时,我发现一个困难是确定每个代码块在哪个责任和上下文中执行。下面我将列举一些我遇到的困难,希望能获得一些关于惯例或指导的启示,以帮助解决这些问题。\n构建时代码:\n使用Gulp、Grunt或原始NPM的项目的构建时代码通常很容易遵循基本文档。大多数较小的项目倾向于将所有代码放在一个文件中,并且该文件通常以类似gulpfile.js这样的传统名称命名,然而在较大的项目中,我看到这些脚本开始被拆分出来。我见过一些情况,gulp文件被拆分成多个文件并放在一个单独的目录下。更糟糕的是,我发现有些gulpfile.js文件甚至没有被命名为gulpfile,这导致新开发人员需要四处寻找gulpfile的位置,而且每次运行gulp命令都必须使用特定的--gulpfile选项。\n运行时服务器端代码:\n基本的Node应用程序的入口点似乎只需在运行node命令时指定一个特定的JavaScript文件(例如node script.js)。对于Web服务器应用程序,如使用Express的应用程序,我注意到按照惯例,入口点文件通常被称为server.js,并且通常可以在应用程序的根目录中找到。然而,在其他情况下,例如在开发环境中运行Web服务器时,我看到gulp任务承担了启动Node的责任。在这些情况下,似乎有多种方法来包含入口点,但我找到的一个例子是启动webpack编译器,然后使用require语句引入入口点脚本。在这种类型的设置中,要弄清楚如何结合通常的node debug命令的正常指导是非常困难的。除了应用程序的入口点外,似乎没有关于NodeJS/Express应用程序的目录结构的一般指导,以帮助定位和将服务器端特定代码与构建时和客户端代码分离。\n当服务器端代码同时用于提供静态内容、服务器端生成的视图(例如MVC)以及为客户端提供API时,服务器端的情况变得更加复杂。我更喜欢将API与应用程序项目分开,但我感觉到其他人认为这样做会导致过度复杂,而我认为这是一个合理的关注分离。\n运行时客户端代码:\n由于客户端代码通常可以根据请求的第一个页面具有不同的入口点,这可能有些棘手。然而,由于URL的一般透明性以及现代浏览器中调试工具的强大功能,跟踪脚本的流程并不太麻烦。相反,客户端代码的困难更多地出现在典型的构建过程中,这些构建过程通常会复制文件并将它们放在一个不同名称的生产结构下。一个例子是一个项目有一个名为src或js的文件夹,其中包含了客户端和服务器端代码,除了只有部分文件被包含在构建任务中进行转换和合并,并将它们放在分发文件夹中。我见过的这些分发文件夹的常见名称有dist、public、www和wwwroot。通常,如果不是总是这些目录都在项目的根目录下,这至少使得定位它变得稍微容易一些,而不需要查看构建脚本。\n我希望有一些关于如何以合理的方式将所有这些内容整合在一起的一般指导,可能是由权威的来源提供的,主要是为了为像我这样的人提供指导,让他们能够从一开始就站稳脚跟。作为一个副作用,也许能够引用一些标准,即使是宽松的标准,也可以减少团队在开始时需要发明和讨论的样板代码的数量。在上述每个上下文中,显然会有一些特定于技术的惯例,例如在客户端使用AngularJS、Meteor或ReactJS时遵循的惯例。我寻找的惯例更具体,用于在端到端JavaScript应用程序中分离主要高级上下文的方式,其中语言和平台不再是明显区分每个上下文的方法。
如何使用NodeJS组织构建、服务器、客户端和共享JavaScript代码
原因:
1. 构建时代码过于庞大和复杂,需要对项目的构建时代码进行模块化和拆分。
2. 服务器端代码和静态内容服务的复杂性,需要简化和标准化处理。
3. 客户端代码和服务器端代码的分离和组合方式,需要一些通用的指导原则。
解决方法:
1. 对于构建时代码,建议将其模块化并拆分为独立的项目,每个项目以独立的npm包形式发布。
2. 对于运行时的服务器端代码,可以将其作为独立的npm包发布,或者与客户端代码混合在同一个模块中,以便根据耦合关系进行分组。
3. 对于运行时的客户端代码,可以参考采用“惯例优先配置”的方法,使用类似SailsJS、EmberJS、Yeoman generators等工具进行开发。
4. 对于服务器端代码用于提供静态内容的情况,应尽量简化代码,使其不超过5行。
在NodeJS和JavaScript社区,通常采用小型的npm包和明确的文件布局来组织代码,而不是追求“标准化”。对于构建时代码、服务器端代码和客户端代码的组织,应根据项目的实际情况进行模块化和拆分,并借鉴一些通用的指导原则和工具。随着ES6模块成为官方规范,未来可能会有更多的标准化,但目前仍需处理已经存在的CommonJS和RequireJS/AMD等模块系统。