Update to Angular v6 - Module not found: Error: Can't resolve 'fs'

Update to Angular v6 - Module not found: Error: Can't resolve 'fs'

我正在尝试将我的 Angular 通用项目从 Angular v5 迁移到 v6

我有一项服务,我使用 fs 在服务器端加载翻译。一切都适用于 Angular v5.

使用 Angular v6,当我 运行 npm run start 又名 ng serve --proxy-config proxy.conf.json 我遇到以下错误

ERROR in ./src/providers/core/translate/translate-universal-loader.service.ts Module not found: Error: Can't resolve 'fs' in '/Users/me/Documents/projects/myproject/src/providers/core/translate'

在我的服务中,我声明 fs 如下:

declare var require: any;
const fs = require('fs');

我也试过像下面这样声明它,但没有帮助

import * as fs from 'fs';

为了告诉 webpack 忽略 fs,我尝试在我的 webpack.server.config.js 中添加以下内容但没有成功

node: {
    fs: 'empty'
}

也尝试过使用 webpack 插件,均未成功

new webpack.IgnorePlugin(/fs/)

但实际上它可能不是 ng serve 使用的配置,但我不知道我是否仍然可以使用 v6 弹出配置?

有人有想法吗?

更新

如果我将 fs 声明为 any,它可以解决 ng serve 的问题,但不幸的是,在 npm run build:ssr 和 运行 [=23] 之后,它将无法在服务器端工作=].在服务器端我将面临以下错误

ERROR ReferenceError: fs is not defined

p.s.: 我的项目遵循 https://github.com/angular/universal-starter 结构、配置和依赖关系

您也可以通过这样做来声明 fs declare var fs: any;

2020 年更新

参见 Marc 的 for Angular v9.

2019 年更新

查看评论,根据@Tahlil,现在可以了。这适用于 Angular v8(Ivy 编译器)see this answer。它将特定模块设置为 false,以便在 package.json.

中的浏览器中使用

原回答

好吧,几个小时后我得出的结论是我收集到的答案,真正的答案是:

您不能再在 Angular v6

中使用 fs

此外,由于不再可能弹出 webpack 配置,因此无法告诉 webpack 忽略 fs require

关于这个主题有一个未解决的问题:https://github.com/angular/angular-cli/issues/10681

P.S.: 我使用 fs 在服务器端加载翻译,我通过遵循@xuhcc 的解决方案解决了这个问题,参见 https://github.com/ngx-translate/core/issues/754

对于仍在寻找答案的任何人,以下是我在 angular 7 应用程序中设法要求 ('fs') 的方法。或者就此而言,任何其他节点模块。

版本

Angular CLI: 7.0.4
Node: 10.13.0
OS: win32 x64
"@angular/animations": "~7.0.0",
"@angular/common": "~7.0.0",
"@angular/compiler": "~7.0.0",
"@angular/core": "~7.0.0",
"@angular/forms": "~7.0.0",
"@angular/http": "~7.0.0",
"@angular/platform-browser": "~7.0.0",
"@angular/platform-browser-dynamic": "~7.0.0",
"@angular/router": "~7.0.0",
"@angular-devkit/build-angular": "~0.10.0",
"@angular/cli": "~7.0.4",
"@angular/compiler-cli": "~7.0.0",
"@angular/language-service": "~7.0.0",
"electron": "^3.0.7",
"typescript": "~3.1.1"

1。安装@types/node

npm install --save-dev @types/node

2。修改tsconfig.json

记下 "allowSyntheticDefaultImports" 标志。它必须设置为 true。

{
  "compileOnSave": false,
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "types": [
      "node"
    ],
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "strict": false
  }
}

3。需要 fs

import { Component } from '@angular/core';
import { } from 'electron';
import Fs from 'fs';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  constructor() {
    //check if platform is electron
    let isElectron: boolean = window && window['process'] && window['process'].type;

    if (isElectron) {
      let fs: typeof Fs = window['require']('fs');
      let app: Electron.App = window['require']('electron').remote;
      console.log(fs, app, window['process']);
    }
  }
}

注意:文件顶部的导入语句只是为了提供类型信息。使用节点 require.

设置变量值

如需更新,请在此处跟踪问题

https://github.com/angular/angular-cli/issues/9827

编辑:

事实证明,如果您的项目具有 require 'fs', 'path', 'child_process' 等依赖项,angular 编译器将无法编译代码。要解决这个问题,正如有人已经建议的那样,将 (window as any).global = window; 添加到您的 polyfills.ts.

在我的例子中,我有 chokidar, node-pty and electron 作为依赖项。这个工人对我来说。

接受的答案是正确的;在 Angular v6+.

中你不能再使用 fs

但是,这个替代构建器(它是 Angular CLI 的扩展)允许您以 Electron 环境为目标并完全访问 Electron 的功能:

https://github.com/angular-guru/electron-builder

或者 在 NativeScript 中,文件是作为文件系统模块的一部分实现的。 要使用它,您必须将其导入代码隐藏文件中。 例如

import * as fs from "file-system';

var documents = fs.knownFolders.documents();
var path = fs.path.join(documents.path, "FileFromPath.txt");
var file = fs.File.fromPath(path);

// Writing text to the file.
file.writeText("Something")
    .then(function () {
        // Succeeded writing to the file.
    }, function (error) {
        // Failed to write to the file.
    });

显然 advanced-json-path 在 Angular 6 之后解决了这个问题,如果有人在使用 fs

所以必须做一个

npm i advanced-json-path --save-dev

因为它是一个开发依赖项(至少在我的情况下) 截至此消息实例,版本为 1.0.8 然后模块 'fs' not found 不会发生。

package.json
{
    ....
   "advanced-json-path": "^1.0.8",
}

在我们的应用程序中,它消除了模块 'fs' 未找到错误。

我通过添加

解决了这个问题
"types": [
  "node"
]

在tsconfig.app.json

在 Angular 8 中,您现在可以使用 Angular Builders 指定一个 web.config.js 来扩展由 Angular.

生成的虚拟配置

This blogpost 解释得很好。

tldr:

  1. 运行 npm i -D @angular-builders/custom-webpack
  2. 编辑您的 angular.json 文件 architect.servearchitect.build 以告诉它使用 custom-webpack 模块通过您的 webpack.config.js 文件扩展虚拟配置
  3. 创建您的自定义 webpack.config.js - 在本例中它看起来像这样:
module.exports = {
    node: {
        fs: 'empty'
      }
};

我是 运行 Angular 一个 Angular CLI monorepo 中的应用程序,在 Nx schematics. I’m sharing code from a lib directory.

的帮助下设置

当尝试使用 Angular 应用程序中共享库中的 Typescript 枚举时,我得到:

Critical dependency: the request of a dependency is an expression

Can't resolve 'fs'

涉及的错误堆栈:

这很奇怪,因为从表面上看,如果包含 Enum 与 type-graphql 无关。

这个问题原来与 type-graphql 模式和 Typescript 枚举是在同一个库中定义的事实有关。将枚举提取到自己的库中解决了这个问题。我不清楚错误发生的原因,但无论如何解决方案都有效。

编辑

所以问题是根据 this nx issue, and this type-graphql issue,在某个时候,包括来自带有 TypeGraphQL 的库的内容最终试图将整个 TypeGraphQL 捆绑到浏览器应用程序中(@Input() 装饰器似乎是另一个这样的触发器)。

如果您想在前端包含 TypeGraphQL 类,解决方案是 update the webpack config. Doing this is in an AngularCLI app

如果您在规范文件中导入了 jasmine 以避免 tslint 错误,您应该执行以下操作:

  1. 从规范文件中删除 import jasmine;
  2. tsconfig.json
  3. 中添加jasmine
...
...
"compilerOptions": {
  ...
  ...
  "types": [
      "webpack-env",
      "jasmine"
  ]
  ...
  ...
}
...
...

由于以前的答案已经很老了,在这里强调一下 Angular9 的解决方法只是在 package.json 中添加以下内容可能会有所帮助:

"browser": {
    "fs": false,
    "os": false,
    "path": false
  }

这对我来说效果很好。 作为参考,我在官方 tensorflow/tfjs Github 页面 here.

上找到了这个解决方案

在您的 package.json

中添加以下行
  1. “浏览器”:{ “fs”:假的, “os”:错误, “路径”:错误}

Click here to see sample image