如何为多个AngularJS项目使用相同的代码库

时间:2015-12-29 18:04:33

标签: javascript angularjs code-reuse

此问题与代码 angularJS 中的可重用性有关。

背景信息:我当前的应用程序(application1)在客户端使用angularjs + kendo UI,现在正在生产中。

我们将使用相同的技术开发另外4个应用程序。 即将推出的4个应用程序的功能几乎与应用程序1相似 70-80%

此时,我的管理层并不想创建一个单独的应用程序(它包含所有5个应用程序的功能)。

目前的方法/目标是:

1.创建5个单独的应用程序,服务器端也有5个不同的应用程序

2.尽可能多地使用客户端代码

我目前的计划:

  1. 分隔公共代码并将此代码保留为核心模块(app.js)的一部分。

  2. 代码重构 - 转移到基于功能的目录' this link中建议的结构。

  3. 为每个功能创建一个角度模块(大约10个模块)。

  4. 我怀疑 - 因为我将使用相同的" 常见"所有5个应用程序的代码(现在复制粘贴),

    如何使这个公共代码对不同的应用程序表现不同?

    例如,

    1. 如果application1,服务调用/app1/gettasks或者是application2,服务调用/app2/gettasks,在这种情况下,我如何在运行时传递app1 / app2 / app3 ...这是可配置的吗?

    2. 简单来说,如何将applicationName告知角度代码?之后,我可以检查下面的applicationName ...(伪代码)

      if(applicationName == app1){
         //do app1 specific things
      }else if (applicationName==app2) {
         //do app2 specific things
      }
      
    3. PS:在服务器端,我正在使用 Spring Boot

      请发表你的想法......

      更新

      在我的公共代码中,有服务,指令和过滤器。 指令&过滤器 - 没有特定于应用程序的代码

      1. 但是,在服务中,如何制作特定于应用程序的REST网址

      2. 在用户登录后/之后,"公共代码"知道 当前应用程序名称?是app1还是2还是3?

3 个答案:

答案 0 :(得分:2)

一种可能的解决方案可能是 -

  • 为每个客户端应用维护一个'config'属性文件
  • 根据这些配置值,使用open(IN, "<$file") || die "Could not open file $file"; open(OUT, ">$out") || die "Could not create temporary file $out"; while(<IN>) { print OUT $_ unless /\b$owner\b/ and /\b$type\b/; } close(IN); close(OUT) || die "Could not close temporary file $out"; rename($out, $file) || die "Failed to overwrite $file"; Grunt等构建工具来Gulp html / js / css文件。它基本上是一个文本搜索替换和条件包括。

E.g。 https://github.com/jsoverson/grunt-preprocess

答案 1 :(得分:0)

您可以将控制器创建为对象,然后为每个项目扩展默认控制器以添加特定行为,并使用服务。

喜欢这里: GetPixelData

答案 2 :(得分:0)

感谢@ FrailWords的回答。

我完成了我的建议,为多个角度应用程序使用相同的UI代码库。我在这里分享我的倾向。

有些方法和我在这个问题中提到的方法相同。

此提案中应遵循的策略列表:

1.  Switch to feature based directory structure. 
2.  Create an angular module for each feature.
3.  Separate common code from instance specific code.
4.  Merge duplicate code.
5.  Remove unused code and outdated libraries.
6.  Re-organize codebase.
7.  Make common code as configurable.
8.  Use same configurable common code for all 5 instances.
9.  Use inheritance or similar mechanisms for extended functionality.
10. Identify & Move functions (methods) from instance specific code to common code.
11. Follow naming conventions.
12. Manage future requirements.
13. Use build tools like gulp or grunt and testing frameworks like jasmine.
14. Application specific look & feel.

如何实施这些策略:

我们将在下面看到针对每种策略的解决方案/方法。

<强> 1。切换到基于功能的目录结构。

当前目录结构:

它基于角度层/类型。那就是我们将所有控制器放在一个文件夹中,将所有服务放在另一个文件夹中等等。这是很好的小应用程序。

示例:

enter image description here

建议的目录结构:

/resources
--/ui_core                                                      ui-core or common code
-----/app
-------------------core_module.js                   inject all modules from /ui_core/modules into this 
-------------------config_module.js                declare constants and inject into core_module 
-----/shared_services                                   part of core_module 
-----/shared_directives                                part of core_module – place directive’s js+html here
-----/shared_filters                                       part of core_module 
-----/shared_views                    
-----/shared_interceptors                 
-----/shared_content
------------/images
------------/icons
------------/signatures
-----/modules
 ------------/common_feature1
-------------------common_feature1_module.js
-------------------common_feature1Controller.js
-------------------common_feature1Service.js
-------------------common_feature1Directive.js
-------------------common_feature1Filter.js                                  if any
-------------------common_feature1_view.html
-------------------common_feature1_test.js
-------------------common_feature1.css                                         if any
------------/common_feature2
-------------------common_feature2_module.js
-------------------common_feature2Controller.js
-------------------common_feature2Service.js
-------------------common_feature2Directive.js
-------------------common_feature2Filter.js
-------------------common_feature2_view.html
-------------------common_feature2_test.js
-------------------common_feature2.css
-----/vendor                                                                      downloaded vendor libraries
------------/js
-------------------/angular
-------------------/kendo
-------------------/jquery
------------/css
-------------------/kendo
-------------------/bootstrap
------------/images
-------------------/kendo
-------------------/bootstrap
--/ui_equity                                    application specific code – for example: equity
-----/app                 
-------------------equity_module.js  inject ui_core module/any module as required.
-----/shared_services                     part of equity_module 
-----/shared_directives                  part of equity_module  – place directive’s js+html here
-----/shared_filters                         part of equity_module 
-----/shared_views
-----/interceptors
-----/content
------------/images
------------/icons
------------/signatures
-----/modules
 ------------/feature1
-------------------feature1_module.js
-------------------feature1Controller.js
-------------------feature1Service.js
-------------------feature1Directive.js
-------------------feature1Filter.js
-------------------feature1_view.html
-------------------feature1_test.js
-------------------feature1.css
------------/feature2
-------------------feature2_module.js
-------------------feature2Controller.js
-------------------feature2Service.js
-------------------feature2Directive.js
-------------------feature2Filter.js
-------------------feature2_view.html
-------------------feature2_test.js
-------------------feature2.css
--/minified
-----/ui_core
-----/ui_equity 
/webapp
-----/WEB-INF
------------/jsp
-------------------index.jsp
-------------------jsincludes.jsp
-------------------cssincludes.jsp
-------------------imageviewer.jsp
-------------------unauthorized.jsp

<强> 2。为每个要素创建角度模块。

要使我们的应用程序模块化,请为我们的应用程序的每个主要特性/功能创建一个角度模块。我们可以在任何需要的地方注入这些模块。

<强>优点:

  1. 易于重复使用模块化应用程序。

  2. 提高可读性:无需将单个组件注入其他组件,注入模块就足够了。

  3. 第3。将公共代码与特定于实例的代码分开。

    可以成为ui_core(公共代码)一部分的项目列表

    a.  Most of the directives
    b.  Filters
    c.  Utilities , such as arrayUtilities.js, dateUtilities.js, stringUtilities.js
    d.  Services
    e.  KendoGridServices & relevant controllers.
    To make   kendoGrid as part of common code, below changes are required.
    
    For example,
    -   Create model outside datasource - Currently schema “model” is hardcoded inside abccontroller.js , instead of this create “kendo model” outside abccontroller.js and pass/inject to abccontroller.js
    
    -   Currently “columns” are hardcoded inside kendoabcgridservice.js. Instead of this, create “columns array” outside and inject it into kendoabcgridservice.js .
    
    -   Similarly, move out any other instance specific code from kendo grid.
    

    以下策略不言自明,因此我们可以转到下一个......

        4.  Merge duplicate code.
        5.  Remove unused code and outdated libraries.
        6.  Re-organize codebase.
    

    <强> 7。将公共代码设置为可配置。

    一个。在公共代码

    中创建配置模块

    ( /resources/ui_core/app/ config_module.js).

    湾例如,在该模块中声明常量         APP_NAME = ‘equity’以及任何要求。

    ℃。使用APP_NAME常量修改公共代码(ui_core),  因此,对于不同的应用程序,相同的代码块将表现不同。

    例如,

    而不是$resource(‘/equity/tasks’)使用$resource(‘/APP_NAME/tasks’)

    注意:以上仅用于示例目的(截至目前),服务调用URL中的更改将在服务器/ Java端重新分解后完成。

    示例2:

    If (APP_NAME == ‘equity’){
                 //do ‘equity’ specific things
    } else if (APP_NAME == ‘commodities’){  
               //do ‘commodities’ specific things
    } else {
    ……………..
    }
    

    <强> 8。对所有5个实例使用相同的可配置公共代码。

        As explained earlier
    

    <强> 9。使用继承或类似机制来扩展功能。

    如果我们需要除可用之外的其他功能,而不是复制和放大粘贴现有文件并向该文件添加代码,我们可以在角度中使用继承类型的机制,如下所示。

    使用

    angular.extend 
    Or 
    angular.copy
    

    或类似方法。

    <强> 10。识别&amp;将函数(方法)从特定于实例的代码移动到公共代码。

    As explained earlier
    

    <强> 11。遵循命名惯例

    为了更好的可维护性而且一致性,定义并遵循文件的某些命名约定。

    例如,

    如果功能名称是“user”,则命名可以如下所示。

    /modules
    -----/user
    ----------user_controller.js
    ----------user_service.js
    ----------user_directive.js
    ----------user_view.html
    ----------user_test.js
    

    请关注user_controller.js或user_ctrl .js,但不要同时执行这两项操作。

    <强> 12。管理未来的要求

    当我们生活在现实世界时,变化和增强是生活的一部分。 一旦我们实施了上述提案,就可以非常轻松地修改/增强功能,而不会影响应用程序的其他部分。

    无论如何,在向现有代码库添加任何功能之前,向您自己提出这个非常重要的问题(此应用程序的开发人员)。

    在哪里我要添加此功能,在常用代码或应用程序特定代码中?

    Enjoy and Have Fun :-)