更新到 Angular v6 - 找不到模块:错误:无法解析“fs”

Posted

技术标签:

【中文标题】更新到 Angular v6 - 找不到模块:错误:无法解析“fs”【英文标题】:Update to Angular v6 - Module not found: Error: Can't resolve '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:s-s-r 并运行npm run serve 之后,它将无法在服务器端运行。在服务器端,我将面临以下错误

ERROR ReferenceError: fs is not defined

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

【问题讨论】:

尝试同时声明fsdeclare var fs: any; 很酷,这是一个很好的解决方法,很有效,谢谢@JohnVelasquez - 我让你回答这个问题,然后将其标记为解决方案 在使用fs时尝试设置此条件-> if(typeof window !== 'undefined') 那没用,问题出在服务器端,代码也只能在服务器端使用(isPlatformServer) 看到这个答案***.com/a/57506728/11127383 【参考方案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

【讨论】:

原来你可以***.com/questions/51087330/… 我的回答是一年多了。我在其中添加了一条评论。【参考方案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 作为依赖项。这个工人给我。

【讨论】:

我有一个项目,其依赖项使用pathfs。我执行了上述步骤,但似乎无法解决问题。 在没有任何信息的情况下很难判断,你使用的 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:

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

【讨论】:

【参考方案5】:

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

【讨论】:

实际上,不幸的是,它并没有完全解决问题。这解决了ng serve 但如果我构建我的项目npm run build:s-s-r 然后运行它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”

涉及的错误堆栈:

type-graphql,特别是loadResolversFromGlob glob fs.realpath

这很奇怪,因为从表面上看,如果包含 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 错误,您应该遵循:

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

...
...

【讨论】:

【参考方案11】:

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

    “浏览器”: “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 与此有关?

以上是关于更新到 Angular v6 - 找不到模块:错误:无法解析“fs”的主要内容,如果未能解决你的问题,请参考以下文章

Angular 6 服务器端错误:找不到模块:错误:无法解析“./dist/server/main.bundle”

Angular 5 和 TS2307 在 Visual Studio 2015 中找不到模块

升级到 RC5 后,Angular2 通用错误找不到模块“@angular/compiler/src/template_parser”

错误找不到模块'@angular/material

运行 ng serve 时找不到模块“@angular/compiler”

找不到模块角度