如何在Angular应用app2中不注入ngRoute即可复用app1的路由配置?
解决Angular模块依赖传递与RequireJS加载问题
看起来你遇到的核心问题是模块依赖的传递性在RequireJS环境下没有被正确处理,同时还要注意跨域加载的阻碍。让我一步步帮你理清思路并解决:
问题根源
Angular本身的模块依赖是传递的——app2依赖app1,而app1依赖ngRoute,理论上app2应该自动继承ngRoute的依赖。但RequireJS是独立的模块加载器,它不会自动识别Angular内部的模块依赖关系,所以如果你的RequireJS配置没把angular-route设为app1的依赖,就会出现必须在app2里手动注入ngRoute才能正常工作的情况。另外,app1和app2运行在不同端口,跨域请求也可能是潜在的坑。
解决方案步骤
1. 修正RequireJS配置,明确依赖加载顺序
你需要在RequireJS的shim配置里明确app1依赖angular-route,这样RequireJS会先加载ngRoute,再加载app1,最后加载app2。示例配置如下:
require.config({ paths: { 'angular': 'path/to/your/angular.min', // 替换成你本地Angular的实际路径 'angular-route': 'path/to/your/angular-route.min', // 对应版本的ngRoute文件 'app1': 'http://localhost:40/app1', // 远程加载app1.js 'app2': './app2' // 本地的app2.js路径 }, shim: { 'angular': { exports: 'angular' }, 'angular-route': { deps: ['angular'], // ngRoute必须依赖Angular才能正常加载 exports: 'angular.module("ngRoute").name' }, 'app1': { deps: ['angular', 'angular-route'], // 告诉RequireJS加载app1前先加载Angular和ngRoute exports: 'angular.module("app1").name' }, 'app2': { deps: ['angular', 'app1'], // app2只需要依赖Angular和app1即可 exports: 'angular.module("app2").name' } } }); // 手动启动app2,避免ng-app指令的加载顺序问题 require(['app2'], function(angular) { angular.bootstrap(document, ['app2']); });
2. 配置CORS解决跨域问题
因为app1运行在localhost:40,app2在localhost:50,属于不同源,你需要在localhost:40的服务器上开启CORS(跨域资源共享),允许来自http://localhost:50的请求。比如在Node.js Express服务器中可以这样设置:
const express = require('express'); const app = express(); // 允许localhost:50的跨域请求 app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', 'http://localhost:50'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); }); // 托管app1的静态文件(如app1.js、partials模板) app.use(express.static('./public')); app.listen(40, () => console.log('App1 running on port 40'));
如果是Apache或Nginx服务器,也需要对应配置CORS规则,否则浏览器会拦截RequireJS对app1.js的跨域请求。
3. 保持app1和app2的模块声明不变
你的app1和app2的代码已经是正确的,不需要修改:
- app1.js:
var app = angular.module("app1", ["ngRoute"]); app.config(['$routeProvider', function ($routeProvider) { $routeProvider.when('/view3', { templateUrl: 'http://localhost:40/partials/partial3.html', controller: 'MyCtrl1 as self' }); $routeProvider.otherwise({ redirectTo: '/view3' }); }]);
- app2.js:
var app = angular.module("app2", ["app1"]); // 这里可以直接使用app1的路由配置,不需要再手动注入ngRoute
为什么这样能解决问题?
- RequireJS的shim配置明确了加载顺序,确保ngRoute在app1之前被加载,Angular就能正确识别app1对ngRoute的依赖。
- Angular的模块依赖传递性会生效:app2依赖app1,app1依赖ngRoute,所以ngRoute会被自动加入app2的依赖模块列表中,不需要手动在app2里注入。
- CORS配置解决了跨域加载app1.js的问题,保证RequireJS能成功获取远程的app1模块。
额外注意事项
- 确保Angular和ngRoute的版本匹配,比如Angular 1.7.x对应ngRoute 1.7.x,版本不兼容可能导致奇怪的错误。
- 尽量用
angular.bootstrap手动启动app2,避免ng-app指令因为依赖未加载完成而提前执行的问题。
内容的提问来源于stack exchange,提问作者Maher
相关产品推荐
相关产品推荐

