【问题标题】:Update to Angular v6 - Module not found: Error: Can't resolve 'fs'更新到 Angular v6 - 找不到模块:错误:无法解析“fs”
【发布时间】:2018-10-16 14:17:23
【问题描述】:

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

我有一项服务,我使用fs 在服务器端加载翻译。 Angular v5 一切正常。

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

错误 ./src/providers/core/translate/translate-universal-loader.service.ts 找不到模块:错误:无法解析“fs” '/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 并运行npm run serve 之后,它将无法在服务器端运行。在服务器端,我将面临以下错误

ERROR ReferenceError: fs is not defined

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

【问题讨论】:

  • 尝试同时声明fs,declare var fs: any;
  • 很酷,这是一个很好的解决方法,很有效,谢谢@JohnVelasquez - 我让你回答这个问题,然后将其标记为解决方案
  • 在使用fs时尝试设置此条件-> if(typeof window !== 'undefined')
  • 那没用,问题出在服务器端,代码也只能在服务器端使用(isPlatformServer)

标签: angular webpack angular-universal angular6


【解决方案1】:

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

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

这对我来说非常有效。 作为参考,我在官方的tensorflow/tfjs Github页面here找到了这个解决方案。

【讨论】:

  • 酷利欧。使用您的参考更新了已接受的答案。
  • Angular 9+ 的最佳答案
  • 希望我能对我发现的每个误报解决方案都支持一次。就我而言,它解决了错误ERROR in ./node_modules/foo/foo.js Module not found: Error: Can't resolve 'path' in 'my-app/node_modules/foo,其中foo 是一个使用path 的模块。 :)。就我而言,只需要"browser": { "path": false }。
  • 检查“浏览器”字段的规范以了解其工作(或不工作)的原因:github.com/defunctzombie/package-browser-field-spec
  • 解决构建问题;但是,我的应用程序不再正确加载 Uncaught ReferenceError: __dirname is not defined at Object.vbkW (index.js:4)
【解决方案2】:

2020 年更新

请参阅 Marc 的 answer Angular v9。

2019 年更新

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

原答案

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

你不能在 Angular v6 中使用 fs

此外,由于无法再弹出 webpack 配置,因此无法告诉 webpack 忽略 fs 要求

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

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

【讨论】:

【解决方案3】:

对于仍在寻找答案的任何人,以下是我设法在我的 Angular 7 应用程序中使用 require('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']);
    }
  }
}

注意:文件顶部的 import 语句只是为了提供类型信息。变量值使用节点 require 设置。

有关更新,请在此处跟踪问题

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

编辑:

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

就我而言,我有 chokidar、node-pty 和 electron 作为依赖项。这个工人给我。

【讨论】:

  • 我有一个项目,其依赖项使用path 和fs。我执行了上述步骤,但似乎无法解决问题。
  • 在没有任何信息的情况下很难判断,你使用的 angular、electron、nodejs 的版本是什么?
  • 我比以前更接近了,但是在尝试使用 window['require'] 时出现错误 TypeError: window.require is not a function。不知道如何解决这个问题
  • @ntgCleaner 试试这个:declare global { interface Window { require: NodeRequire; } } 然后,使用 window['require']。如果是打字稿编译器错误,必须用这个来解决。如果这不起作用,试试这个:window['require']=eval('require')。而使用window['require']。
  • @NishkalKashyap 在尝试了您提到的内容并更多地使用它之后,我似乎无法让它工作。我正在尝试使用cheerio 和request-promise 进行一些简单的网络抓取,但它们都需要require 才能使用。我会继续尝试的东西
【解决方案4】:

在 Angular 8 中,您现在可以使用 Angular Builders 指定一个 web.config.js,它扩展了 Angular 生成的虚拟配置。

This blogpost 解释得很好。

tldr:

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

【讨论】:

    【解决方案5】:

    你也可以通过declare var fs: any;来声明fs

    【讨论】:

    • 实际上,不幸的是,它并没有完全解决问题。这解决了ng serve 但如果我构建我的项目npm run build:ssr 然后运行它npm run serve,我将在服务端遇到错误fs is not defined :(
    【解决方案6】:

    接受的答案是正确的;你不能在 Angular v6+ 中使用 fs。

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

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

    【讨论】:

      【解决方案7】:

      我通过添加解决了这个问题

      "types": [
        "node"
      ]
      

      在 tsconfig.app.json 中

      【讨论】:

        【解决方案8】:

        或者 在 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.
            });
        

        【讨论】:

          【解决方案9】:

          我在 Angular CLI monorepo 中运行一个 Angular 应用程序,在 Nx schematics 的帮助下设置。我是sharing code from a lib directory。

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

          严重依赖:依赖的请求是一个表达式

          无法解析“fs”

          涉及的错误堆栈:

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

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

          编辑

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

          如果你想在前端包含 TypeGraphQL 类,解决方案是update the webpack config。在 AngularCLI 应用程序involves quite a few steps 中执行此操作。

          【讨论】:

            【解决方案10】:

            如果您在规范文件中导入了 jasmine 以避免出现 tslint 错误,您应该遵循:

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

            【讨论】:

              【解决方案11】:

              在您的 package.json 中添加以下行

              1. “浏览器”:{ “fs”:假, “操作系统”:错误, “路径”:假}

              Click here to see sample image

              【讨论】:

                【解决方案12】:

                如果有人使用 fs,显然 advanced-json-path 在 Angular 6 及更高版本中解决了这个问题

                所以必须做一个

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

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

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

                在我们的应用程序中,它消除了 Module 'fs' not found 错误。

                【讨论】:

                • 为什么 advanced-json-path 与此有关?
                猜你喜欢
                • 2019-12-01
                • 2018-06-29
                • 2019-05-31
                • 2017-04-18
                • 1970-01-01
                • 2020-02-24
                • 2022-06-27
                相关资源
                最近更新 更多