Javascript 在上下文之间共享公共依赖关系 前提
假设我有两个不同的基于AMD的AngularJS应用程序,每个应用程序都有自己的控制器、指令、服务等。每个应用程序都捆绑在自己的Javascript 在上下文之间共享公共依赖关系 前提,javascript,requirejs,Javascript,Requirejs,假设我有两个不同的基于AMD的AngularJS应用程序,每个应用程序都有自己的控制器、指令、服务等。每个应用程序都捆绑在自己的dist/{app name}.min.js中,并加载到同一HTML页面的标记中(这一切都是在CMS的上下文中进行的,CMS包含这些应用程序以及其他内容) 现在,这些应用程序最终共享了一些服务、指令和供应商库,如angular本身、moment、jQuery,等等,因此我为所有这些资源创建了另一个文件夹,它将在应用程序的js包之前添加到页面中: <script s
dist/{app name}.min.js
中,并加载到同一HTML页面的
标记中(这一切都是在CMS的上下文中进行的,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>
这是通用模块的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/directive/common directive
,等等,然后在创建包时排除common
路径(因为所有公共模块都已经存在于共享资源.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) {
路径
可以设置为使模块看起来像是直接位于baseUrl
下,即使它不是。您可以:
paths: {
'first-app': 'first-app/src'
'second-app': 'second-app/src'
}
是的,加载first-app/app
会起作用。RequireJS会将路径转换为first-app/src/app.js
paths: {
'first-app': 'first-app/src'
'second-app': 'second-app/src'
}