让我们考虑一个 Angular (12.2.12) 项目,它使用 Angular Universal 和 Node.js Express Web 服务器进行一些服务器端渲染。基本上我们可以在SSR Angular 文档中找到。它还使用Storybook (6.3.12)。
在我想在 Storybook 中使用的其他组件中,这里是http-error.component.ts:
import { isPlatformServer } from '@angular/common';
import { Component, Inject, Input, OnChanges, Optional, PLATFORM_ID, SimpleChanges } from '@angular/core';
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
import { Request, Response } from 'express';
@Component({
selector: 'app-http-error',
templateUrl: './http-error.component.html',
styleUrls: ['./http-error.component.scss']
})
export class HttpErrorComponent implements OnChanges {
@Input() error;
@Input() type: string;
// [...] Some methods
constructor(
// [...] Some services
private metaTagsService: MetaTagsService,
@Optional() @Inject(REQUEST) private request: Request,
@Optional() @Inject(RESPONSE) private response: Response,
@Inject(PLATFORM_ID) private platformId: any) {
}
ngOnChanges(changes: SimpleChanges) {
if (changes.error && this.error) {
// [...]
if (isPlatformServer(this.platformId)) {
this.response.status(404);
}
}
}
}
该组件在应用程序中执行时运行良好。但是最近,在运行之后npm run storybook
,这个组件没有显示在 Storybook 菜单栏中,我可以在控制台中看到以下错误:
Unexpected error while loading ./app/http-error/http-error.stories.ts: TypeError: express__WEBPACK_IMPORTED_MODULE_1__ is undefined
这是tsconfig.json
Storybook 使用的:
{
"extends": "../tsconfig.app.json",
"compilerOptions": {
"types": [
"node"
]
},
"exclude": [
"../src/test.ts",
"../src/**/*.spec.ts",
"../projects/**/*.spec.ts"
],
"include": [
"../src/**/*",
"../projects/**/*"
],
"files": [
"./typings.d.ts",
]
}
我的.storybook/main.js看起来像这样:
module.exports = {
"stories": [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
"addons": [
"@storybook/addon-essentials",
"@storybook/addon-links",
],
// See https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#angular-12-upgrade
core: {
builder: 'webpack5'
},
webpackFinal: async (config, { configType }) => {
// Patch
// import { Request, Response } from 'express'; in http-error.component.ts breaks the build:
// ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/home/xx/project/node_modules/destroy'
// ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/home/xx/project/node_modules/etag'
// ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/home/xx/project/node_modules/express/lib'
// ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/home/xx/project/node_modules/mime'
// ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/home/xx/project/node_modules/send'
// ModuleNotFoundError: Module not found: Error: Can't resolve 'net' in '/home/xx/project/node_modules/express/lib'
config.externals = [{ 'express': { commonjs: 'express' } }]
return config;
}
}
其中的webpackFinal
内容对 Webpack 4 处理express
以及来自它的一些错误很有用。我倾向于相信我需要找到一种方法来做同样的事情,但使用 Webpack 5;但我的分析可能不对。
到目前为止,我已经尝试了很多事情,但没有通过config.externals
手动修改它成功,使用webpack-node-externals,在 SO 或 GitHub 中寻找答案,但显然,我迷路了。也许答案很简单,就在我面前,但我看不到。所以,我希望能在这个问题上提供一些帮助。