0

让我们考虑一个 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.jsonStorybook 使用的:

{
  "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 中寻找答案,但显然,我迷路了。也许答案很简单,就在我面前,但我看不到。所以,我希望能在这个问题上提供一些帮助。

4

0 回答 0