如何使用 NodeJS 组织构建、服务器、客户端和共享 JavaScript 代码
How to organize build, server, client and shared JavaScript code with NodeJS
我一直认为在服务器上使用 NodeJS 的一大好处是可以在服务器端和客户端之间共享代码位(例如输入验证)。现在我实际上是在使用 NodeJS 进行开发,我发现的一个困难是确定执行每个代码体的职责和上下文。下面我将列出一些我遇到的困难,希望能从我可能忽略的惯例或指南中获得一些启发,这可能有助于提升这些问题。
构建时代码
以遵循基本文档的方式使用 Gulp、G运行t 或 vanilla NPM 的项目的构建时间代码通常很容易理解。大多数较小的项目倾向于将所有代码保存在一个文件中,并且该文件往往被命名为常规名称,如 gulpfile.js,但是对于较大的项目,我已经看到这些脚本开始被拆分。我见过一些 gulp 文件被拆分成多个文件并放在单独目录下的情况。更糟糕的是,我发现 gulpfile.js 文件甚至没有这样命名的情况导致新开发人员四处寻找 gulp 文件所在的位置,一旦找到 gulp 命令始终必须是 运行 和特定的 --gulpfile 选项。
运行-时间服务器端代码
基本节点应用程序的入口点似乎只需要在 运行 执行节点命令(例如 node script.js
)时指出特定的 JavaScript 文件。对于 Web 服务器应用程序,例如那些使用 Express, I've noticed that by convention the entry point file is often called server.js and can usually be found in the root directory of the application. In some other cases however such as when running the web server in a developer environment I've seen gulp tasks take on the responsibility of launching Node. In these cases there seems to be multiple ways to include the entry point but one example I've found is just starting up the webpack complier followed by a require statement for the entry point script. Figuring out how to incorporate normal guidance on how to accomplish a typical node debug 命令的应用程序在这种类型的设置中是非常重要的。除了应用程序的入口点之外,似乎没有关于 NodeJS/Express 应用程序目录结构的任何通用指南,这些指南将服务器端特定代码保留在其位置以帮助找到它并将其与构建分开-时间和客户端代码。
如果服务器端代码用于提供静态内容、服务器端生成的视图(例如使用 MVC)以及提供API 到客户端。我的偏好是将 API 与应用程序项目分开,但我从其他人那里得到的感觉是,这样做会让人感觉过于复杂,我认为这是一种合理的关注点分离。
运行-时间客户端代码
由于客户端代码通常可以根据请求的第一个页面有不同的入口点,这可能很棘手。然而,由于 URL 在典型情况下如何映射到资源以及调试工具在现代浏览器中变得多么强大是普遍透明的,因此遵循脚本并不会太麻烦。对于客户端代码来说,困难更多的是典型的构建过程,这些过程通常最终会复制文件并以不同的名称将它们放入类似产品的结构中。一个例子是一个项目,它有一个名为 src 或 js 的文件夹,其中混合了客户端和服务器端代码,除了只有一个部分文件恰好包含在构建任务中,该任务会转换并经常连接文件并将它们放置在分发文件夹中。我见过的这些分发文件夹的通用名称是 dist、public、www,以及 wwwroot。通常(如果不是总是)这些目录位于项目的根目录,这至少可以更容易地找到它,而不必询问构建脚本。
我希望有一些关于如何以理智的方式将所有这些放在一起的一般指导,也许是由权威来源提供的,主要是为像我这样可能希望从右脚开始的人提供指导。作为一个副作用,也许能够引用某种标准,即使它是一个松散的标准,也可能减少团队在开始时必须发明和讨论的样板文件的数量。在上面列出的每个上下文中,显然会有一些特定于技术的约定,例如 AngularJS、Meteor 或客户端的 ReactJS 所遵循的约定。我正在寻找的约定更具体地用于在端到端 JavaScript 应用程序中分离主要的高级上下文,在这些应用程序中,语言和平台不再成为区分它们的明显方式。
构建时代码
恕我直言,如果您的构建时代码太多以至于超过 1000 行并且需要的文件不多,那么 rails 就有些问题了。要么你不知道如何充分利用 npm 中的现有包,要么你不了解如何重构通用代码并将其发布为独立的 npm 包。如果你觉得你需要有关项目构建时代码的指导,因为它是如此庞大和复杂,我的建议是模块化并拆分成单独的项目——每个独立发布到 npm。也只需检查您的整体方法。你在做什么,那么习惯,需要那么多机器?
运行-时间服务器端代码
请看我对ExpressJS How to structure an application?
的另一个回答
一般来说,我宁愿看到客户端代码和服务器端代码完全独立的 npm 包(独立的 git 回购,独立的 package.json 文件,独立发布)(如果它们足够大)或者以其他方式混合在同一个模块中并通过耦合分组(与功能相关的所有代码都放在一起,包括前端和后端代码),特别是如果您的代码库有大量代码可以在两种环境中工作。
我有一个名为 mjournal 的开源全栈 node/JS 应用程序,它将浏览器代码和节点代码放在一起。你可以看看它是否符合你的逻辑并且容易理解代码所在的位置。这绝不是一种流行的方法,所以很多人会不喜欢它,但我个人感觉很好,因为我已经接受了 "group by coupling" 作为一般原则。
Figuring out how to incorporate normal guidance on how to accomplish a typical node debug command is non-trivial in this type of setup
是的,那是胡说八道。您的应用程序应以 npm start
或类似 node server.js
的名称开头。使新开发人员感到困惑的详细 [=49=] 设置是您应该消除的不必要的复杂性。
The server-side story becomes even more complex in cases where the server side code is used both for the purpose for serving up static content
根据我的经验,提供静态内容的代码可以归结为 5 行或更少,所以没什么大不了的。如果您有大量处理静态内容服务的代码,那么 rails.
又出现了一些问题
运行-时间客户端代码
My hope is that there is that there is some general guidance on how to put all of this together in a sane way perhaps by an authoritative source mainly to give guidance to those like myself who may want start off on the right foot.
Node 社区中有些人采用了 Ruby 在 Rails、EmberJS 和其他一些大型项目上使用的 "convention over configuration" 方法。如果您喜欢这种方法,请查看使用它的工具,如 SailsJS、EmberJS、Yeoman 生成器等。
但总的来说,寻找一个 "standard" 节点并不是这样。js/javascript/web 社区滚动。小型 npm 包。由于体积小而被迫显而易见的文件布局。我在这里感受到你的挫败感,因为前端工具链是如此复杂,但归根结底是因为浏览器中的 JavaScript 花了太多年才创建一个合理的模块系统。既然 ES6 模块是官方规范,事情可能会在未来几年内开始标准化,但是已经用 CommonJS 编写了如此多的代码,而且它是像 RequireJS/AMD 这样可怕的前身,我们可能会在可预见的时间内处理它们未来。
我一直认为在服务器上使用 NodeJS 的一大好处是可以在服务器端和客户端之间共享代码位(例如输入验证)。现在我实际上是在使用 NodeJS 进行开发,我发现的一个困难是确定执行每个代码体的职责和上下文。下面我将列出一些我遇到的困难,希望能从我可能忽略的惯例或指南中获得一些启发,这可能有助于提升这些问题。
构建时代码
以遵循基本文档的方式使用 Gulp、G运行t 或 vanilla NPM 的项目的构建时间代码通常很容易理解。大多数较小的项目倾向于将所有代码保存在一个文件中,并且该文件往往被命名为常规名称,如 gulpfile.js,但是对于较大的项目,我已经看到这些脚本开始被拆分。我见过一些 gulp 文件被拆分成多个文件并放在单独目录下的情况。更糟糕的是,我发现 gulpfile.js 文件甚至没有这样命名的情况导致新开发人员四处寻找 gulp 文件所在的位置,一旦找到 gulp 命令始终必须是 运行 和特定的 --gulpfile 选项。
运行-时间服务器端代码
基本节点应用程序的入口点似乎只需要在 运行 执行节点命令(例如 node script.js
)时指出特定的 JavaScript 文件。对于 Web 服务器应用程序,例如那些使用 Express, I've noticed that by convention the entry point file is often called server.js and can usually be found in the root directory of the application. In some other cases however such as when running the web server in a developer environment I've seen gulp tasks take on the responsibility of launching Node. In these cases there seems to be multiple ways to include the entry point but one example I've found is just starting up the webpack complier followed by a require statement for the entry point script. Figuring out how to incorporate normal guidance on how to accomplish a typical node debug 命令的应用程序在这种类型的设置中是非常重要的。除了应用程序的入口点之外,似乎没有关于 NodeJS/Express 应用程序目录结构的任何通用指南,这些指南将服务器端特定代码保留在其位置以帮助找到它并将其与构建分开-时间和客户端代码。
如果服务器端代码用于提供静态内容、服务器端生成的视图(例如使用 MVC)以及提供API 到客户端。我的偏好是将 API 与应用程序项目分开,但我从其他人那里得到的感觉是,这样做会让人感觉过于复杂,我认为这是一种合理的关注点分离。
运行-时间客户端代码
由于客户端代码通常可以根据请求的第一个页面有不同的入口点,这可能很棘手。然而,由于 URL 在典型情况下如何映射到资源以及调试工具在现代浏览器中变得多么强大是普遍透明的,因此遵循脚本并不会太麻烦。对于客户端代码来说,困难更多的是典型的构建过程,这些过程通常最终会复制文件并以不同的名称将它们放入类似产品的结构中。一个例子是一个项目,它有一个名为 src 或 js 的文件夹,其中混合了客户端和服务器端代码,除了只有一个部分文件恰好包含在构建任务中,该任务会转换并经常连接文件并将它们放置在分发文件夹中。我见过的这些分发文件夹的通用名称是 dist、public、www,以及 wwwroot。通常(如果不是总是)这些目录位于项目的根目录,这至少可以更容易地找到它,而不必询问构建脚本。
我希望有一些关于如何以理智的方式将所有这些放在一起的一般指导,也许是由权威来源提供的,主要是为像我这样可能希望从右脚开始的人提供指导。作为一个副作用,也许能够引用某种标准,即使它是一个松散的标准,也可能减少团队在开始时必须发明和讨论的样板文件的数量。在上面列出的每个上下文中,显然会有一些特定于技术的约定,例如 AngularJS、Meteor 或客户端的 ReactJS 所遵循的约定。我正在寻找的约定更具体地用于在端到端 JavaScript 应用程序中分离主要的高级上下文,在这些应用程序中,语言和平台不再成为区分它们的明显方式。
构建时代码
恕我直言,如果您的构建时代码太多以至于超过 1000 行并且需要的文件不多,那么 rails 就有些问题了。要么你不知道如何充分利用 npm 中的现有包,要么你不了解如何重构通用代码并将其发布为独立的 npm 包。如果你觉得你需要有关项目构建时代码的指导,因为它是如此庞大和复杂,我的建议是模块化并拆分成单独的项目——每个独立发布到 npm。也只需检查您的整体方法。你在做什么,那么习惯,需要那么多机器?
运行-时间服务器端代码
请看我对ExpressJS How to structure an application?
的另一个回答一般来说,我宁愿看到客户端代码和服务器端代码完全独立的 npm 包(独立的 git 回购,独立的 package.json 文件,独立发布)(如果它们足够大)或者以其他方式混合在同一个模块中并通过耦合分组(与功能相关的所有代码都放在一起,包括前端和后端代码),特别是如果您的代码库有大量代码可以在两种环境中工作。
我有一个名为 mjournal 的开源全栈 node/JS 应用程序,它将浏览器代码和节点代码放在一起。你可以看看它是否符合你的逻辑并且容易理解代码所在的位置。这绝不是一种流行的方法,所以很多人会不喜欢它,但我个人感觉很好,因为我已经接受了 "group by coupling" 作为一般原则。
Figuring out how to incorporate normal guidance on how to accomplish a typical node debug command is non-trivial in this type of setup
是的,那是胡说八道。您的应用程序应以 npm start
或类似 node server.js
的名称开头。使新开发人员感到困惑的详细 [=49=] 设置是您应该消除的不必要的复杂性。
The server-side story becomes even more complex in cases where the server side code is used both for the purpose for serving up static content
根据我的经验,提供静态内容的代码可以归结为 5 行或更少,所以没什么大不了的。如果您有大量处理静态内容服务的代码,那么 rails.
又出现了一些问题运行-时间客户端代码
My hope is that there is that there is some general guidance on how to put all of this together in a sane way perhaps by an authoritative source mainly to give guidance to those like myself who may want start off on the right foot.
Node 社区中有些人采用了 Ruby 在 Rails、EmberJS 和其他一些大型项目上使用的 "convention over configuration" 方法。如果您喜欢这种方法,请查看使用它的工具,如 SailsJS、EmberJS、Yeoman 生成器等。
但总的来说,寻找一个 "standard" 节点并不是这样。js/javascript/web 社区滚动。小型 npm 包。由于体积小而被迫显而易见的文件布局。我在这里感受到你的挫败感,因为前端工具链是如此复杂,但归根结底是因为浏览器中的 JavaScript 花了太多年才创建一个合理的模块系统。既然 ES6 模块是官方规范,事情可能会在未来几年内开始标准化,但是已经用 CommonJS 编写了如此多的代码,而且它是像 RequireJS/AMD 这样可怕的前身,我们可能会在可预见的时间内处理它们未来。