您忘记导入 "NgxsSelectSnapshotModule" // NGXS 模块
You've forgotten to import "NgxsSelectSnapshotModule" // the NGXS module
[更新:好的。我们找到了如何复制,参见最小复制]
描述
我们在服务器日志中看到生产环境和非生产环境中的许多这 2 个致命错误:
- 致命 [main.js:xx] NgxsSelectSnapshotModuleIsNotImported [错误]:您忘记导入“NgxsSelectSnapshotModule”!在 assertDefined (/opt/app/dist/server/main.js:xx:yy) 在 getStore
- 致命 [main.js:xx] 错误:您忘记导入 NGXS 模块!在 createSelectObservable (/opt/app/dist/server/main.js:1:yy)
我们显然已经在 AppModule 和功能模块中导入了两个 ngxs 模块。
在应用程序模块中:
NgxsModule.forRoot(
[
xxx....
],
{
developmentMode: !environment.production,
},
),
NgxsRouterPluginModule.forRoot(),
NgxsFormPluginModule.forRoot(),
NgxsSelectSnapshotModule.forRoot(),
NgxsStoragePluginModule.forRoot({
...xxx
},
}),
NgxsReduxDevtoolsPluginModule.forRoot({
name: 'xxxx',
disabled: environment.production,
}),
在功能模块中:
NgxsModule.forFeature([xxx, yyy]),
NgxsSelectSnapshotModule,
这是一个非常庞大的项目,包含许多模块和组件...错误仅通过 SSR 发生,而且在我们的开发机器上很少发生...不过,当它发生时,我们会看到很多连续出现错误语句,而没有其他组件或模块抱怨错误。它只是 ngxs。
看起来,SSR 仍然提供 html,并且 Angular 应用程序在客户端上的加载仍然很好(包括所有 ngxs 的东西)
最小复制
好的。我们发现了如何重现:
- 在浏览器中打开一个页面
- 刷新
- 快速中止加载
- 再次快速刷新
- --> 很多很多致命错误
猜测:这可能是由于 angular 销毁了所有东西,两个 ngxs 模块都会清除 Injector onDestroy。
由于只有当我们在中止后快速重新加载时才会发生错误(只是中止永远不会产生错误),所以它一定是关于 angular 通用仍然(重新?)使用一些组件而 ngxs 已经摆脱了它的注入器引用。
异常或错误
FATAL [main.js:2897] Error: You have forgotten to import the NGXS module!
at createSelectObservable (/opt/app/dist/server/main.js:1:xx)
at AppComponent.get [as progress] (/opt/app/dist/server/main.js:1:xx)
at AppComponent_Template (/opt/app/dist/server/main.js:2897:1625353)
at executeTemplate (/opt/app/dist/server/main.js:2897:xx)
at refreshView (/opt/app/dist/server/main.js:2897:xx)
at refreshComponent (/opt/app/dist/server/main.js:2897:xx)
at refreshChildComponents (/opt/app/dist/server/main.js:2897:xx)
at refreshView (/opt/app/dist/server/main.js:2897:xx)
at renderComponentOrTemplate (/opt/app/dist/server/main.js:2897:xx)
at tickRootContext (/opt/app/dist/server/main.js:2897:xx)
or....
FATAL [main.js:2897] NgxsSelectSnapshotModuleIsNotImported [Error]: You've forgotten to import "NgxsSelectSnapshotModule"!
at assertDefined (/opt/app/dist/server/main.js:2897:xx)
at getStore (/opt/app/dist/server/main.js:2897:xx)
at XXXComponent.get [as isXXX] (/opt/app/dist/server/main.js:2897:xx)
at XXXComponent_Template (/opt/app/dist/server/main.js:2897:xx)
at executeTemplate (/opt/app/dist/server/main.js:2897:xx)
at refreshView (/opt/app/dist/server/main.js:2897:xx)
at refreshComponent (/opt/app/dist/server/main.js:2897:xx)
at refreshChildComponents (/opt/app/dist/server/main.js:2897:xx)
at refreshView (/opt/app/dist/server/main.js:2897:xx)
at refreshComponent (/opt/app/dist/server/main.js:2897:xx)
环境
Libs:
"@angular/core": "^11.0.6",
"@ngxs/store": "^3.7.1",
"@ngxs-labs/select-snapshot": "^2.0.1",
Browser: only on SSR
这个问题的根本原因是这个文件:https://github.com/ngxs/store/blob/master/packages/store/src/decorators/select/select-factory.ts
SelectFactory class 中存在的存储键是整个服务器的单例(它不是 Angular 特定的单例)。从装饰器内部的使用方式可以看出:https://github.com/ngxs/store/blob/8b52ae654c0a707612a8d23bde4737e69cbb8ee9/packages/store/src/decorators/select/symbols.ts#L11
因此,如果某个用户的 NGXS 模块在某个时刻被破坏,而此时另一个用户的服务器端代码仍然是 运行,则会出现错误
我建议重构这个装饰器,使其依赖于每个使用的组件中的商店,而不是依赖于商店,商店是整个服务器的单例。
此外,这个问题也存在于 select-快照存储库中,并且与服务器范围的单例 (https://github.com/ngxs-labs/select-snapshot)
存在相同的潜在问题
[更新:好的。我们找到了如何复制,参见最小复制]
描述
我们在服务器日志中看到生产环境和非生产环境中的许多这 2 个致命错误:
- 致命 [main.js:xx] NgxsSelectSnapshotModuleIsNotImported [错误]:您忘记导入“NgxsSelectSnapshotModule”!在 assertDefined (/opt/app/dist/server/main.js:xx:yy) 在 getStore
- 致命 [main.js:xx] 错误:您忘记导入 NGXS 模块!在 createSelectObservable (/opt/app/dist/server/main.js:1:yy)
我们显然已经在 AppModule 和功能模块中导入了两个 ngxs 模块。 在应用程序模块中:
NgxsModule.forRoot(
[
xxx....
],
{
developmentMode: !environment.production,
},
),
NgxsRouterPluginModule.forRoot(),
NgxsFormPluginModule.forRoot(),
NgxsSelectSnapshotModule.forRoot(),
NgxsStoragePluginModule.forRoot({
...xxx
},
}),
NgxsReduxDevtoolsPluginModule.forRoot({
name: 'xxxx',
disabled: environment.production,
}),
在功能模块中:
NgxsModule.forFeature([xxx, yyy]),
NgxsSelectSnapshotModule,
这是一个非常庞大的项目,包含许多模块和组件...错误仅通过 SSR 发生,而且在我们的开发机器上很少发生...不过,当它发生时,我们会看到很多连续出现错误语句,而没有其他组件或模块抱怨错误。它只是 ngxs。 看起来,SSR 仍然提供 html,并且 Angular 应用程序在客户端上的加载仍然很好(包括所有 ngxs 的东西)
最小复制
好的。我们发现了如何重现:
- 在浏览器中打开一个页面
- 刷新
- 快速中止加载
- 再次快速刷新
- --> 很多很多致命错误
猜测:这可能是由于 angular 销毁了所有东西,两个 ngxs 模块都会清除 Injector onDestroy。 由于只有当我们在中止后快速重新加载时才会发生错误(只是中止永远不会产生错误),所以它一定是关于 angular 通用仍然(重新?)使用一些组件而 ngxs 已经摆脱了它的注入器引用。
异常或错误
FATAL [main.js:2897] Error: You have forgotten to import the NGXS module!
at createSelectObservable (/opt/app/dist/server/main.js:1:xx)
at AppComponent.get [as progress] (/opt/app/dist/server/main.js:1:xx)
at AppComponent_Template (/opt/app/dist/server/main.js:2897:1625353)
at executeTemplate (/opt/app/dist/server/main.js:2897:xx)
at refreshView (/opt/app/dist/server/main.js:2897:xx)
at refreshComponent (/opt/app/dist/server/main.js:2897:xx)
at refreshChildComponents (/opt/app/dist/server/main.js:2897:xx)
at refreshView (/opt/app/dist/server/main.js:2897:xx)
at renderComponentOrTemplate (/opt/app/dist/server/main.js:2897:xx)
at tickRootContext (/opt/app/dist/server/main.js:2897:xx)
or....
FATAL [main.js:2897] NgxsSelectSnapshotModuleIsNotImported [Error]: You've forgotten to import "NgxsSelectSnapshotModule"!
at assertDefined (/opt/app/dist/server/main.js:2897:xx)
at getStore (/opt/app/dist/server/main.js:2897:xx)
at XXXComponent.get [as isXXX] (/opt/app/dist/server/main.js:2897:xx)
at XXXComponent_Template (/opt/app/dist/server/main.js:2897:xx)
at executeTemplate (/opt/app/dist/server/main.js:2897:xx)
at refreshView (/opt/app/dist/server/main.js:2897:xx)
at refreshComponent (/opt/app/dist/server/main.js:2897:xx)
at refreshChildComponents (/opt/app/dist/server/main.js:2897:xx)
at refreshView (/opt/app/dist/server/main.js:2897:xx)
at refreshComponent (/opt/app/dist/server/main.js:2897:xx)
环境
Libs:
"@angular/core": "^11.0.6",
"@ngxs/store": "^3.7.1",
"@ngxs-labs/select-snapshot": "^2.0.1",
Browser: only on SSR
这个问题的根本原因是这个文件:https://github.com/ngxs/store/blob/master/packages/store/src/decorators/select/select-factory.ts
SelectFactory class 中存在的存储键是整个服务器的单例(它不是 Angular 特定的单例)。从装饰器内部的使用方式可以看出:https://github.com/ngxs/store/blob/8b52ae654c0a707612a8d23bde4737e69cbb8ee9/packages/store/src/decorators/select/symbols.ts#L11
因此,如果某个用户的 NGXS 模块在某个时刻被破坏,而此时另一个用户的服务器端代码仍然是 运行,则会出现错误
我建议重构这个装饰器,使其依赖于每个使用的组件中的商店,而不是依赖于商店,商店是整个服务器的单例。
此外,这个问题也存在于 select-快照存储库中,并且与服务器范围的单例 (https://github.com/ngxs-labs/select-snapshot)
存在相同的潜在问题