架构:结合多个JavaScript项目(模块化)

时间:2016-05-28 23:43:17

标签: javascript build architecture gruntjs multi-project

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

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

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

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

4 个答案:

答案 0 :(得分:3)

恕我直言,它不是 与任务管理器工作相关(也就是gulp,grunt甚至webpack,它在这里并不重要)。社区去了一个你拥有很多(相对)微小节点模块的地方,这些模块做了一件事并做得很好,所以它与你的第一个建议非常相关。

VCS回购可能看起来像这样的结构:

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

...然后你使用npm link在模块中自己创建符号链接,这样你就不必发布模块来获取更新。

还有一个名为lerna的新软件包,可以自动执行此npm link项操作(它会检测您的"本地"模块中的依赖关系图并创建链接在他们之间),你需要做的就是遵循他们的结构。此外,它可以巧妙地进行发布,您可以在所有包中运行命令以及其他相关内容。

BabelReact是此模块的一个很好的例子 - 关注点分离。 Babel与lerna配合使用以自动执行包here are their reasons to have a monorepo

之间的链接

答案 1 :(得分:1)

我通常完全按照你在1中描述的那样做。但我使用的是本地依赖项,它将由我的构建链连接。

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

这样你就不需要一直推动它了。您只需删除node_module / sub_project文件夹并在构建链中再次运行npm install

使用browserify,您可以将依赖项添加到角度项目中。

  

插件本身无法运行。

我通常将我的服务或指令作为常规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();
            })
        }
    };
}];

通过这种方式,您可以运行它们并从角度独立测试它们。使用WebWorkers时,这也很有用。因为它们不能(完全)与角度1.X一起使用。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

几个月前我遇到过类似的问题。由于您熟悉Grunt或Gulp等流式传输构建系统,因此可以非常轻松地解决安装动态依赖关系。

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