Angular 如何在没有自定义网页包配置的情况下进行条件导入?

Angular 如何在没有自定义网页包配置的情况下进行条件导入?,angular,typescript,ionic-framework,webpack,electron,Angular,Typescript,Ionic Framework,Webpack,Electron,我们有一个从单个代码库为Cordova和Electron构建的项目,因此它需要在Electron中导入节点API和节点特定模块,并在Cordova中忽略它们。到目前为止,我们一直在使用自定义的webpack配置来实现这一点,通过传递一个环境变量来告诉它是将节点内容视为externals(Cordova)还是requireit(Electron)。然而,现在我们使用Angular 9,构建器需要运行自定义网页包(@Angular builders/custom webpack)与Ionic dev

我们有一个从单个代码库为Cordova和Electron构建的项目,因此它需要在Electron中导入节点API和节点特定模块,并在Cordova中忽略它们。到目前为止,我们一直在使用自定义的webpack配置来实现这一点,通过传递一个环境变量来告诉它是将节点内容视为
externals
(Cordova)还是
require
it(Electron)。然而,现在我们使用Angular 9,构建器需要运行自定义网页包(
@Angular builders/custom webpack
)与Ionic dev服务器构建器(
@Ionic/Angular toolkit:cordova serve
)冲突,集成它们看起来很痛苦。如果没有自定义的webpack脚本,我们怎么能做到这一点呢?

我终于发现webpack提供了
\uuuu非\uWebpack\u require\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
,它只是转换成运行时
require
。这样就可以编写一个best-effort导入,用TypeScript维护类型安全:

declare function __non_webpack_require__(path: string): any;

import * as node_hid_typeonly from 'node-hid';
let node_hid: typeof node_hid_typeonly;
try { node_hid = __non_webpack_require__('node-hid'); } catch { }
这样做的目的如下:

  • 告诉TypeScript存在
    \u非\u网页包\u require()
  • 导入
    节点hid
    仅用于类型批注(如果导入仅用于类型信息,
    tsc
    将其删除)
  • 尽最大努力将
    节点hid
    导入到使用适当类型声明的变量中
  • 你最终能够写:

    private device: node_hid_typeonly.HID;
    
    后来呢,

    this.device = new node_hid.HID(path);
    
    我们还在一个非网页包项目中重用了其中一些代码,我采用了:

    global['__non_webpack_require__'] = require;
    

    在导入任何具有
    \uuuu非\uu网页包\uu require\uuuu

    的内容之前,在
    index.ts
    中创建一个全局变量,假设require存在,并且依赖于网页包的实现细节可能对您来说很好,但这很难推广。有很多方法可以有条件地导入内容
    \uuuuuuu non\uu webpack\u require\uuuuuuuuu
    是webpack公共API,而不是实现细节。不过,我对其他策略感兴趣……你有什么建议?这是库代码(内部使用),需要在Electron和Cordova中使用Angular+webpack,以及在节点下使用这两种代码。