架构:组合几个 JavaScript 项目(模块化)

Architecture: Combine several JavaScript projects (modular)

我想为我的 JavaScript 项目创建一个干净的架构。该项目由一个 Node.js 服务器和两个具有不同用途的独立 Angular.js 前端组成。为了构建前端,我分别使用自定义的 grunt 构建。构建结果为每个项目一个 HTML 文件和两个 minified/uglified CSS 和 JavaScript 文件。然后每个前端 运行 在一个单独的最小版本的节点服务器上(仅提供静态文件)。

到目前为止,很清楚。现在的目标是可以将插件模块添加到三个核心项目中的每一个。一个模块应该扩展任一项目的 JavaScript。这意味着例如在一个前端的情况下,向 angular 配置添加一个额外的 angular 模块。我已经知道在哪里以及如何将 angular 模块代码添加到核心应用程序中。

现在的问题是:如何在同样依赖于插件模块的多个项目上创建合理的构建过程?我想到了两个解决方案。

  1. 我可以将插件作为 NPM 依赖项添加到核心项目之一。然而,这有一个缺点,即模块中的每个更改都需要推送到 NPM,并且这样开发插件模块不是很方便。插件无法单独运行。
  2. 我可以在其中一个核心项目的 Gruntfile 中找到一个插件列表。该列表将包含模块的本地文件路径。在构建核心模块时,将执行插件的构建。然而,这将包括观察插件构建文件的变化。这是一个不干净的解决方案。
  3. 我可以有另一个项目,其中包含对核心项目和所有插件的依赖项,并将它们一起构建。如何添加依赖的问题仍然存在(案例1或案例2)

你会如何解决这个问题?

我通常完全按照您在第 1 条中描述的那样进行操作。但是我使用本地依赖项,这些依赖项将由我的构建链连接起来。

npm install ~/project_root/sub_project --save-dev

这样就不用一直按了。您只需在构建链中再次删除 node_module/sub_project 文件夹和 运行 npm install

使用 browserify,您可以将依赖项添加到您的 angular 项目。

A plugin is not runnable on its own.

我通常按照常规 JavaScript 类 开发我的服务或指令,并用 angular 包装它们。

var Service = require("./path/to/service.js")
module.exports = [function() {
    return {
        restrict: 'AC',
        link: function($scope, $element) {
            var someService = new Service();
            $scope.$watch("whatever",function(value){
                service.doSomething();
            })
        }
    };
}];

这样您就可以 运行 它们并独立于 angular 测试它们。这在使用 WebWorkers 时也有优势。因为它们不能真正(完全)与 angular 1.X.

一起使用

您正在为您的 MEAN 项目添加不必要的复杂性。
为什么要通过 grunt 连接两个 html 部分 ???
您应该使用 AngularJS 的 SPA 架构,他们采用该架构是有原因的..在此类问题中,其中一个不是 运行。
无需连接文件,只需配置 SPA 的状态即可从 html file.THAT'S IT 调用所需的部分模板!
并在您的后端使用网络服务(尽管我认为您正在这样做)这样您就独立于数据的来源,因为无论它来自哪个服务器,您都在使用 URI。
关于依赖项,您可以在前端或后端使用 --save 标志无缝地使用 npm,以便将它们添加到 package.json 文件,然后将该文件复制到相应的应用程序目录和 npm install。
但是我真的不明白你要处理所有这些,如果你能多解释一下有助于理解它的功能需求的话..

几个月前我遇到过类似的问题。安装动态依赖项可以很容易地解决,因为您熟悉流式构建系统,如 Grunt 或 Gulp.

  1. 你可以在你的 package.json 中分配一个 属性 像依赖项或 devdependencies 来保存你需要的所有额外信息,bower.json 甚至是自定义的 JSON 文件也可以解决问题。我更喜欢 NPM 打包清单或 Bower 清单,因为它们为每个模块提供了一个有效的入口点。
  2. 使用 grunt-auto-install 您可以为构建过程动态安装任何其他模块依赖项,您可以从项目的主 package.json 文件中解析这些依赖项。
  3. 使用来自每个附加 package.json 的每个模块的 main 属性 将为您提供一个文件列表来初始化 uglify 或连接任务。

恕我直言, 与任务管理器工作无关(又名 gulp、g运行t 甚至 webpack,这并不重要这里)。社区去一个地方,在那里你拥有很多(相对)微小的节点模块,这些模块只做一件事并且做得很好,所以它与你的第一个建议非常相关。

VCS 存储库可能类似于以下结构:

my-repo/
  package-1/
    package.json
  package-2/
    package.json
  package-3/
    package.json
  ...

... 然后你使用 npm link 在模块本身内部创建 symlinks,这样你就不必发布模块来获取更新。

有一个名为 lerna 的全新软件包可以自动完成 npm link 事情(它会检测 "local" 模块中的依赖关系图并生成 link它们之间),您需要做的就是遵循它们的结构。此外,它可以智能地发布,您可以 运行 在所有包和其他相关的东西中执行命令。

Babel, React are great examples of this modules-separation-of-concern. Babel works with lerna to automate the linking between the packages, here are their reasons to have a monorepo.