忽略 Angular 中的导入

Ignore import in Angular

我想使用 Angular 中的库。 (npm 包是cubing 供参考)。这个库可以 运行 既可以在浏览器中也可以在节点中,并且有一些针对两者的特定代码。我想让它在浏览器中运行,但是Angular编译不起作用,因为它找不到worker_threads。我问了库所有者,他说预期的解决方案是告诉你的构建系统应该忽略这个导入,因为它只与代码的节点变体相关。

但我不知道怎么说 Angular 这个。我怎么告诉它:请忽略此节点模块中的此导入,我们永远不会到达使用它的代码?

Error: Can't resolve 'worker_threads' in REDACTED/node_modules/cubing/dist/esm

如果那不可能,我想我可以考虑做一个 node_modules 补丁,但我不喜欢这个想法,原因很明显。而且我听说很难让它在生产环境中工作。

供参考,这是github项目(针对手头的问题切换到分支争夺):https://github.com/Lykos/cube_trainer.git

这里是最相关的文件:

Package.json:

{
  "name": "cube-trainer",
  "private": true,
  "author": "Bernhard F. Brodowsky",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/Lykos/cube_trainer.git"
  },
  "engines": {
    "node": "16.x",
    "npm": "8.x"
  },
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --configuration production",
    "build_development": "ng build --configuration development",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "test_ci": "ng test --karma-config client/karma-ci.conf.js",
    "lint": "ng lint"
  },
  "dependencies": {
    "@angular/animations": "^13.0.2",
    "@angular/cdk": "^13.0.2",
    "@angular/common": "^13.0.2",
    "@angular/compiler": "^13.0.2",
    "@angular/core": "^13.0.2",
    "@angular/forms": "^13.0.2",
    "@angular/material": "^13.0.2",
    "@angular/platform-browser": "^13.0.2",
    "@angular/platform-browser-dynamic": "^13.0.2",
    "@angular/router": "^13.0.2",
    "@ngrx/component-store": "^13.0.2",
    "@ngrx/effects": "^13.0.2",
    "@ngrx/store": "^13.0.2",
    "@ngrx/store-devtools": "^13.0.2",
    "@rxweb/reactive-form-validators": "^2.1.6",
    "actioncable": "^5.2.6",
    "angular-token": "^7.0.1",
    "cubing": "^0.22.0",
    "file-saver": "^2.0.5",
    "ngx-cookie-service": "^13.0.1",
    "ngx-filesaver": "^12.0.0",
    "rxjs": "~7.4.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~13.0.1",
    "@angular-eslint/builder": "12.6.1",
    "@angular-eslint/eslint-plugin": "12.6.1",
    "@angular-eslint/eslint-plugin-template": "12.6.1",
    "@angular-eslint/schematics": "12.6.1",
    "@angular-eslint/template-parser": "12.6.1",
    "@angular/cli": "~13.0.1",
    "@angular/compiler-cli": "~13.0.0",
    "@ngrx/schematics": "^13.0.2",
    "@types/actioncable": "^5.2.7",
    "@types/chai": "^4.2.22",
    "@types/file-saver": "^2.0.4",
    "@types/jasmine": "~3.10.0",
    "@types/node": "^12.11.1",
    "@typescript-eslint/eslint-plugin": "4.28.2",
    "@typescript-eslint/parser": "4.28.2",
    "angular-http-server": "^1.10.0",
    "chai": "^4.3.4",
    "eslint": "^7.26.0",
    "jasmine-core": "~3.10.0",
    "karma": "~6.3.0",
    "karma-chai": "^0.1.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "karma-mocha": "^2.0.1",
    "mocha": "^9.1.3",
    "typescript": "~4.4.4"
  }
}

angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "cube-trainer": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:application": {
          "strict": true
        }
      },
      "root": "",
      "sourceRoot": "client/src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "./public",
            "index": "client/src/index.html",
            "main": "client/src/main.ts",
            "polyfills": "client/src/polyfills.ts",
            "tsConfig": "client/tsconfig.app.json",
            "assets": [
              "client/src/favicon.ico",
              "client/src/assets"
            ],
            "styles": [
              "./node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css",
              "client/src/styles.css"
            ],
            "scripts": [],
            "webWorkerTsConfig": "client/tsconfig.worker.json"
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "4mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "fileReplacements": [
                {
                  "replace": "client/src/environments/environment.ts",
                  "with": "client/src/environments/environment.prod.ts"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true,
              "outputHashing": "none"
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "proxyConfig": "client/src/proxy.conf.json"
          },
          "configurations": {
            "production": {
              "browserTarget": "cube-trainer:build:production"
            },
            "development": {
              "browserTarget": "cube-trainer:build:development"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "cube-trainer:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "client/src/test.ts",
            "polyfills": "client/src/polyfills.ts",
            "tsConfig": "client/tsconfig.spec.json",
            "karmaConfig": "client/karma.conf.js",
            "assets": [
              "client/src/favicon.ico",
              "client/src/assets"
            ],
            "styles": [
              "./node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css",
              "client/src/styles.css"
            ],
            "scripts": []
          }
        },
        "lint": {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "lintFilePatterns": [
              "client/src/**/*.ts",
              "client/src/**/*.html"
            ]
          }
        }
      }
    }
  },
  "defaultProject": "cube-trainer",
  "cli": {
    "defaultCollection": "@ngrx/schematics"
  }
}

tsconfig.json

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "src/",
    "paths": {
      "@environment": ["environments/environment"],
      "@shared/*": ["app/shared/*"],
      "@utils/*": ["app/utils/*"],
      "@store/*": ["app/store/*"],
      "@effects/*": ["app/effects/*"],
      "@core/*": ["app/core/*"],
      "@training/*": ["app/training/*"]
    },
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2017",
    "module": "es2020",
    "lib": [
      "es2020",
      "dom"
    ],
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "strict": true,
    "skipLibCheck": true
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

tsconfig.app.json

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": []
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

看起来您可以在 tsconfig 或 angular.json 中排除它,也许两者都试试?

Exclude files from build in Angular 2

// tsconfig
{
   "exclude": [
       "node_modules/thepath/tothedependency/orfile/using/worker_threads/I_guess",
   ]
}
// angular.json
...
          "configurations": {
            "production": {
              "assets": [
                {
                  "ignore": [
                    "**/test.json",
                    "**/test"
                  ],
                },
...

类似的东西

您还可以为 worker_threads 安装浏览器包装器,然后配置 angular build / webpack 以将旧导入替换为新导入。

如果您决定修补它,那可能还不错。在 github 上分叉并从 github 分叉安装非常简单。或者为更改保存一个 git 补丁文件并在安装步骤中自动应用该补丁也不是疯狂的。

在 esbuild 和 rollup 之类的东西中,这种事情通常很麻烦。

您还可以修改您的 webpack 配置,我认为 ng build 正在使用它,它可能在 /node_modules/angular/somejunk/config/webpack.config.json 或其他地方并添加:

module.exports = {
  //...
  externals: {
    fetch: 'cross-fetch'
  }
};

但是你又回到应用补丁或使用 git 分支