【问题标题】:Angular Universal: exclude node-only dependencies from bundlingAngular Universal:从捆绑中排除仅节点依赖项
【发布时间】:2020-06-05 04:31:25
【问题描述】:

我有一个使用 Angular 通用 "@nguniversal/express-engine": "^9.1.1" 构建的应用程序。我正在尝试添加服务器端节点画布 ("canvas": "^2.6.1") 以在服务器上呈现某些图像。我不需要此库在客户端可用,因此希望将其从捆绑包中排除。

当尝试使用 npm run dev:ssr 运行应用程序时 - 我收到与该库相关的错误:

ERROR in ./node_modules/canvas/build/Release/canvas.node 1:0
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are 
configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
this.debug is not a function

经过一些研究,我发现externalDependencies 选项已添加到angular.json 服务器构建选项中。我试图将canvas 库路径添加到externalDependencies 的数组中,但这并没有给出任何结果。错误仍然存​​在。构建失败。

如果平台是server,目前我正在使用动态import() 将画布库加载到角度服务之一中。出于某种原因,我认为默认情况下它不会尝试捆绑动态导入的脚本。 也许还有其他解决方法。

因此,总而言之,理想情况下,我希望有一个仅在服务器端可用的服务,并且将使用其中的 canvas 库。并且不会破坏角度构建。

【问题讨论】:

    标签: angular server-side-rendering angular-universal


    【解决方案1】:

    仅包含在服务器包中

    如果平台是服务器,目前我正在使用动态 import() 将画布库加载到角度服务之一

    这会将这个依赖包含到任何使用你的服务的包中(带有画布的块可能仍然是延迟加载的 - 但无论如何 webpack 必须处理它)。

    在 Angular 中的一种惯用方式是通过依赖注入:

    // no side effect here - safe to import in browser or server files
    // canvas-polyfill.token.ts
    export type PolyfillLoader = () => Promise<any>;
    export const CANVAS_POLYFILL_LOADER = new InjectionToken<PolyfillLoader>();
    
    // app.server.module.ts
    const canvasLoader = () => import('canvas');
    
    @NgModule({
       ...
       providers: [{provide: CANVAS_POLYFILL_LOADER, useValue: canvasLoader}]
    })
    export class AppServerModule {}
    
    // your service
    @Injectable()
    class MyService {
      constructor(@Optional() @Inject(CANVAS_POLYFILL_LOADER) private polyfillLoader: PolyfillLoader) {}
    
      doYourStuff() {
        const whenReady = this.polyfillLoader ? this.polyfillLoader() : Promise.resolve();
    
        return whenReady.then(() => {
          // do something useful
        })
      }
    }
    

    Webpack 问题

    说了这么多——仍然不能保证 Angular 的 webpack 在构建服务器包时能够处理这种依赖关系。 如果您想避免将其包含在您的捆绑包中并保留在外部,您可以在angular.json 中为您的服务器构建器设置bundleDependencies: false 选项。 不过,它的副作用是不会从 Angular 库中删除任何调试代码 - 因此您需要采取额外的步骤来准备您的应用程序以进行生产(请参阅 https://angular.io/guide/ivy-compatibility#payload-size-debugging 以获取一些提示)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-20
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 2015-10-04
      • 2019-04-16
      • 2019-02-14
      相关资源
      最近更新 更多