共享上下文之间的共同依赖关系
Share common dependencies between contexts
前提
假设我有两个不同的基于 AMD 的 AngularJS 应用程序,每个应用程序都有自己的一组控制器、指令、服务等。它们中的每一个都捆绑在自己的dist/{app-name}.min.js
中,并加载在同一 HTML 页面中的<script>
标签中(这一切都在 CMS 的上下文中,然后包含这些应用程序等(
现在应用程序最终共享了一些服务、指令和供应商库,如angular
本身、moment
、jQuery
等,所以我为所有这些资源制作了另一个文件夹,这导致一个捆绑包将被添加到应用程序的 js 捆绑包之前的页面中:
<script src="/some-path/dist/shared-resources.min.js"></script>
<script src="/some-path/dist/first-app.min.js"></script>
<script src="/some-path/dist/second-app.min.js"></script>
这是生成的文件夹结构:
.
├── shared-resources/
│ ├── dist/
│ ├── src/
│ │ └── common/
│ │ ├── directives/
│ │ ├── modules/
│ │ ├── services/
│ │ └── vendor/
│ └── build.js
│
├── first-app
│ ├── dist/
│ ├── src/
│ │ ├── first-app/
│ │ │ ├── controllers/
│ │ │ ├── modules/
│ │ │ ├── services/
│ │ │ ├── directives/
│ │ │ └── app.js
│ │ └── first-app.js
│ └── build.js
│
└── second-app
├── dist/
├── src/
│ ├── second-app/
│ │ ├── controllers/
│ │ ├── modules/
│ │ ├── services/
│ │ ├── vendor/
│ │ └── app.js
│ └── second-app.js
└── build.js
这是常见模块的build.js
文件的示例
({
baseUrl: 'src',
removeCombined: true,
out: 'dist/shared-resources.min.js',
paths: { // forcing a `common/{modulename}` convention
'common/jquery': 'common/vendor/jquery.min',
'common/moment': 'common/vendor/moment.min',
'common/angular': 'common/vendor/angular/angular.min',
},
shim: {
'common/angular': {
exports: 'angular',
}
},
include: [
'common/modules/vendors', // Just a bundle of every vendor modules
'common/directives/common-directive',
'common/services/common-service'
],
})
现在我的目的是让所有共享模块都使用 common/
命名,因此每个应用程序都可能需要 common/angular
、 common/directives/common-directive
等,然后在创建其捆绑包时排除common
路径(因为所有公共模块都已存在于shared-resources.js
捆绑包中(,例如:
// first-app/src/first-app/controllers/app-controller.js
define([
'first-app/modules/controllers',
'first-app/services/app-service',
'common/services/common-service'
], function (controllers) {
'use strict';
controllers.controller('AppController', ['CommonService', 'AppService', function (CommonService, AppService) {
CommonService.call();
AppService.call();
}]);
});
// first-app/build.js
({
baseUrl: 'src',
out: 'dist/first-app.min.js',
paths: {
'common': 'empty:'
},
name: 'first-app',
deps: ['first-app/app']
})
问题
问题是这两个应用程序,它们再次加载到页面上(这是无法避免的(,应该如何正确查找这些公共模块。
鉴于每个应用程序显然具有不同的baseUrl
,它们被放置在不同的 RequireJS 上下文中,否则第二个应用程序的baseUrl
将覆盖第一个应用程序的baseUrl
,从而导致其模块加载不正确:
// first-app/src/first-app.js
require.config({
context: 'first-app',
baseUrl: 'first-app/src',
})(['fist-app/app']);
// first-app/src/second-app.js
require.config({
context: 'second-app',
baseUrl: 'second-app/src',
})(['second-app/app']);
但是将它们放在上下文中会导致对公共模块的查找失败,因为模块是在上下文baseUrl
中查找的。实际上,这仅适用于第二个应用程序(按加载顺序排列的第二个应用程序(,而要包含在页面中的第一个应用程序可以很好地加载公共模块
问题
那么我应该如何使应用程序正确共享公共模块呢?我的做法错了吗?我应该使用RequireJS以外的其他东西吗?
RequireJS 的上下文功能实际上是用来处理您必须在同一页面上加载两个冲突的应用程序并且无法解决冲突的情况。到目前为止,您编写代码的方式可能导致您希望有两个baseUrl
值,但您的问题中没有任何内容表明您必须有两个baseUrl
值。有一些方法可以避免它:
-
作为逻辑模块集一部分的模块应使用相对路径相互加载。例如,您作为示例给出的模块可以是:
// first-app/src/first-app/controllers/app-controller.js define([ '../modules/controllers', '../services/app-service', 'common/services/common-service' ], function (controllers) {
-
paths
可以设置为使其看起来像模块直接在baseUrl
下,即使它不是。您可以拥有:paths: { 'first-app': 'first-app/src' 'second-app': 'second-app/src' }
是的,加载
first-app/app
将起作用。RequireJS 会将路径转换为first-app/src/app.js
。
- 单元测试依赖关系没有被嘲笑
- FRP 中 EventStreams 的循环依赖关系
- 节点模块依赖关系
- 在Meteor中使用具有依赖关系的NPM包
- requirejs定义:嵌套依赖关系
- Django管道和javascript依赖关系
- 在Aurelia computeds中,当设置依赖关系时,如何声明对对象属性的依赖关系
- Npm未满足对等依赖关系
- Node.JS处理重复的可传递依赖关系
- 在Firefox上使用聚合物的javascript依赖关系的HTML导入困难;Safari
- 库中的匿名定义()模块's的依赖关系导致库损坏'的家属
- 使用Require.js按照依赖关系的顺序加载JavaScript
- GraphQL代码中的Javascript循环依赖关系
- 使用 grunt 检查单个 javascript 文件时如何解决依赖关系
- 与超类的依赖关系
- 在 Angular JS 业力测试中管理依赖关系
- 在 webpack 中管理 jQuery 插件依赖关系
- requirejs+bower,bower组件中的路径和依赖关系
- 预构建的NPM包:如何为用户省去依赖关系
- 聚合物种子-自定义元素依赖关系