我有一个 Angular 16 应用程序,使用 Angular Fire、firebaseui,并且我最近安装了 Angular Universal。
每当我运行
npm run dev:ssr
来启用 SSR 时,我都会收到此错误 -
./node_modules/dialog-polyfill/dialog-polyfill.js:4
var supportCustomEvent = window.CustomEvent;
^
ReferenceError: window is not defined
at <anonymous> (./node_modules/dialog-polyfill/dialog-polyfill.js:4:28)
at Object.44252 (./node_modules/dialog-polyfill/dialog-polyfill.js:738:2)
at __webpack_require__ (./webpack/bootstrap:19:1)
at Module.73697 (./node_modules/express/node_modules/serve-static/index.js:210:1)
at __webpack_require__ (./webpack/bootstrap:19:1)
at Module.10388 (./src/app/components/home/home.component.html:46:10)
at __webpack_require__ (./webpack/bootstrap:19:1)
at Module.11838 (./server.ts:74:35)
at __webpack_require__ (./webpack/bootstrap:19:1)
at Module.50041 (./src/app/app.component.html:3:8)
Node.js v20.9.0
A server error has occurred.
node exited with 1 code.
dialog-polyfill 包作为 firebaseui 的依赖项引入。它没有在其他地方使用。
我尝试使用 platformBrowser 和 domino 包来缓解这个问题,但仍然面临同样的错误。有什么想法吗?
登录.组件.ts
isBrowser: boolean = false;
constructor(
@Inject(PLATFORM_ID) private platformId: Object
) {
this.isBrowser = isPlatformBrowser(platformId);
}
ngOnInit(): void {
if (isPlatformBrowser(this.platformId)) {
if (!this.ui) {
this.ui = new firebaseui.auth.AuthUI(this.auth as any);
}
const uiConfig: firebaseui.auth.Config = {
signInOptions: [
EmailAuthProvider.PROVIDER_ID,
],
signInSuccessUrl: '/',
credentialHelper: firebaseui.auth.CredentialHelper.NONE,
tosUrl: '/privacy-policy',
privacyPolicyUrl: '/privacy-policy',
callbacks: {
signInSuccessWithAuthResult: (authResult: { user: User | null; }, redirectUrl: any) => {
this.onLoginSuccessful(authResult.user);
return false;
},
uiShown: () => {
const loader = document.getElementById('loader');
if (loader) {
loader.style.display = 'none';
}
},
signInFailure: (error: any) => {
console.error(error);
alert('Sign-in failed. Please try again with correct username & password.');
return Promise.resolve();
}
},
signInFlow: 'popup',
autoUpgradeAnonymousUsers: true,
siteName: 'My App'
};
this.ui.start('#firebaseui-auth-container', uiConfig);
this.auth.onAuthStateChanged((user: any) => {
if (!user && this.ui.isPendingRedirect()) {
this.ui.start('#firebaseui-auth-container', uiConfig);
}
});
}
}
登录.component.html
<div *ngIf="isBrowser" id="firebaseui-auth-container" class="auth-container">
服务器.ts
// domino to create dom in server
const domino = require('domino');
const fs = require('fs');
const path = require('path');
// Use the browser index.html as template for the mock window
const template = fs
.readFileSync(path.join(join(process.cwd(), 'dist/<PROJECTNAME>/browser'), 'index.html'))
.toString();
// Shim for the global window and document objects.
const window = domino.createWindow(template);
global['window'] = window;
global['document'] = window.document;
package.json
"@angular/fire": "~7.6.1",
"@nguniversal/express-engine": "^16.2.0",
"domino": "^2.1.6",
"firebase": "^9.23.0",
"firebaseui": "^6.1.0",
在进行并保存更改后,我已使用
npm run build:ssr
重建了 server.ts 文件。
我还没有看到它明确说明,但我已经通过其他库和 Firebaseui GitHub 存储库隐含地暗示了 Firebaseui 不适用于 SSR。我建议使用另一个与你的 Angular 应用程序兼容的库,或者自己编写接口和 TS 代码,但要确保监控安全问题。