AngularJS 模块 + Webpack + ES6 导入 - 依赖注入和连接顺序问题
Posted
技术标签:
【中文标题】AngularJS 模块 + Webpack + ES6 导入 - 依赖注入和连接顺序问题【英文标题】:AngularJS modules + Webpack + ES6 imports - Problem with dependency injection & concat order 【发布时间】:2020-04-24 17:03:07 【问题描述】:问题总结
我正在迁移一个旧的 AngularJS 应用程序以使用 Webpack,我将它分成三个部分,我想将它们表示为 AngularJS 模块:
src-ts-admin src-ts-common src-ts-store例如,我希望 'src-ts-admin' 使用来自 'src-ts-common' 的服务,但不幸的是 webpack 以错误的顺序捆绑文件以进行 AngularJS 依赖注入,所以我最终会遇到类似的错误..
Error: "[$injector:unpr] Unknown provider: filterServiceProvider <- filterService <- initializerService
.. 其中 initializerService 是来自 src-ts-admin 的服务,而 filterService 来自 src-ts-common。问题的核心在于
module("ADMIN").service("initializerService") 之前执行 module("COMMON).service("filterService").. 虽然我无法在依赖项中发现问题。
文件概述
src-ts-admin: app.ts
这是 webpack 的入口点,但不是很有趣。应用路由会触发 app.initializer.ts。
import angular from 'angular';
import appModule from './app.module';
src-ts-admin: app.module.ts
import angular from 'angular';
import commonModuleName from '../src-ts-common/common.module';
var modulezz;
modulezz = [commonModuleName,'ngRoute', 'ui.router', 'ui.multiselect', 'ui.bootstrap', 'ui.bootstrap-slider', 'ui.bootstrap.buttons', 'duScroll',
'ngMessages', 'colorpicker.module', 'angular-bind-html-compile', 'pascalprecht.translate'];
export var appModule = angular.module("ADMIN", modulezz);
export default appModule.name;
src-ts-admin: app.initializer.ts
import angular from "angular";
import appModuleName from "./app.module";
import filterService from "../src-ts-common/service/filter-service-model";
export class InitializerController
static $inject = ...etc...
constructor(...etc...)
/* THIS IS KICKED OFF BY AN ANGULAR ROUTE, THIS KICKS OFF THE InitializerController BELOW */
angular.module(appModuleName).controller("initializerController", InitializerController);
export class InitializerService
static $inject = ["$stateParams", "$window", "$timeout", "filterService", ...etc...];
constructor(private $stateParams, private $window, private $timeout, private filterService: filterService, ...etc...)
/* THIS IS WHERE THE DEPENDENCY INJECTION FAILS */
angular.module(appModuleName).service("initializerService", InitializerService);
src-ts-common: common.module.ts
import angular from 'angular';
export default angular.module("COMMON",[]).name;
src-ts-common: filter.service.ts
import angular from "angular";
import commonModuleName from '../common.module';
export class filterService
static $inject = [];
constructor()
/* ...simplified... */
angular.module(commonModuleName).service("filterService", filterService);
我的想法
我得到的错误是..
Error: "[$injector:unpr] Unknown provider: filterServiceProvider <- filterService <- initializerService
.. 这表明 app.initializer.ts 在 filter.service.ts 之前执行,尽管它正在导入该文件。
你看到我犯了什么明显的错误吗?你有什么最佳实践来构建 AngularJS + Webpack 模块导入和剪切文件吗?
--- 解决方案(更新!)---
感谢https://***.com/a/59631154/5244937 我可以解决我的问题。我应该使用的模式是初始化 app.module.ts
和 common.module.ts
文件中的角度模块(例如 angular.module(commonModuleName).service("filterService", filterService);
),而不是与它们的类实现一起初始化。
这里是更正的文件:
src-ts-admin: app.ts
/* here i am more or less just kicking off the angular application after i import app.module.ts */
import appModule from './app.module';
appModule.run(["$rootScope", "$location", ...,
function ($rootScope, $location, ...)
..
appModule.controller('appController', ['$scope', ..,
function ($scope: any, ...)
..
src-ts-admin: app.module.ts
/** here (1) i am initializing all angular controllers, services, factories from the ADMIN package & (2) importing the COMMON module */
import angular from 'angular';
import ngRoute from 'angular-route';
import uiRouter from 'angular-ui-router';
import 'angular-messages';
import 'angular-translate';
import dptCommonModuleName from '../src-ts-common/common.module';
var modulezz;
modulezz = [dptCommonModuleName, ngRoute, uiRouter, 'ui.multiselect', 'ui.bootstrap', 'ui.bootstrap-slider', 'ui.bootstrap.buttons', 'duScroll',
'ngMessages', 'colorpicker.module', 'angular-bind-html-compile', 'pascalprecht.translate'];
export var appModule = angular.module("DPT", modulezz);
export var appModuleName = appModule.name;
/**
* Services
*/
angular.module(appModuleName).service("systemParameterService", systemParameterService);
angular.module(appModuleName).service("statisticsService", statisticsService);
angular.module(appModuleName).service("deletionCheckService", deletionCheckService);
...
src-ts-admin: app.initializer.ts
/** here i have removed (1) the import of angular.module.ts and (2) the initialization of angular controller and service "initializerController" and "initializationService" */
import angular from "angular";
import filterService from "../src-ts-common/service/filter-service-model";
export class InitializerController
static $inject = ...etc...
constructor(...etc...)
/* THIS IS KICKED OFF BY AN ANGULAR ROUTE, THIS KICKS OFF THE InitializerController BELOW */
export class InitializerService
static $inject = ["$stateParams", "$window", "$timeout", "filterService", ...etc...];
constructor(private $stateParams, private $window, private $timeout, private filterService: filterService, ...etc...)
/* THIS IS WHERE THE DEPENDENCY INJECTION FAILS */
src-ts-common: common.module.ts
/* here i have added the initialization of the angular service filterService and all other services, factories, .. contained in that module */
var moduleName = angular.module("DPT.COMMON",[]).name
export default moduleName;
angular.module(moduleName).factory("filterModel", function () return filterModel; );
angular.module(moduleName).factory("filterPresetModel", function () return filterPresetModel;);
angular.module(moduleName).factory("productModel", function () return productModel;);
angular.module(moduleName).factory("propertyProfileModel", [function () return propertyProfileModel;]);
angular.module(moduleName).factory("propertyValueModel",function () return propertyValueModel;);
src-ts-common: filter.service.ts
/** 这里我 (1) 删除了 common.module 的导入和 (2) angular.module(..).service("filterService", ..) 的初始化 */
import angular from "angular";
export class filterService
static $inject = [];
constructor()
/* ...simplified... */
【问题讨论】:
请问您如何导入import angular from "angular"
。我在导入 angularjs v1.3.7 时遇到了挑战
【参考方案1】:
您的依赖项倒置,Module
应导入其依赖项(其他模块或过滤器/服务/组件)。
如果您遵循此操作,您的 AppModule
将导入其子模块,然后再导入其服务。
这意味着您的服务应该只导出类。 相关模块应导入服务类,并在模块上注册并导出模块名称。 父模块应导入其子模块。
// serviceX.js
export class serviceX
static $inject=[];
...
// childModule.js
import serviceX from './services/serviceX.js';
import componentY from './components/componentY.js';
import angular from 'angular';
export default angular.module('childModule', [])
.service('serviceX', serviceX)
.component('componentY', componentY)
// ... rest of the childModule deps
.name;
// appModule.js
import externalDep from 'external-dep';
import childModule from './modules/childModule';
import angular from 'angular';
const appModule = anguler.module('appModule', [externalDep, childModule]).name;
angular.bootstrap(document, [appModule]);
【讨论】:
你是对的。连同下面的教程,我已经更正了导入和文件的结构。 angular-tips.com/blog/2015/06/…我会用我现在的状态更新我原来的帖子以上是关于AngularJS 模块 + Webpack + ES6 导入 - 依赖注入和连接顺序问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 webpack 导入 angularjs 的最佳实践是啥?
使用 Typescript 和 Webpack 管理依赖项的 AngularJS
在 Heroku 上部署 AngularJs + webpack + gulp