Angular-cli: Error: Module not found: Error: Can't resolve 'fs'

Created on 1 Nov 2017  路  21Comments  路  Source: angular/angular-cli

Bug Report or Feature Request (mark with an x)

- [ x ] bug report -> please search issues before submitting
- [ ] feature request

Versions.

Angular CLI: 1.5.0-rc.6
Node: 6.11.0
OS: darwin x64
Angular: 5.0.0-rc.9
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router

@angular/cli: 1.5.0-rc.6
@angular-devkit/build-optimizer: 0.0.31
@angular-devkit/core: 0.0.20
@angular-devkit/schematics: 0.0.34
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.8.0-rc.6
@schematics/angular: 0.0.49
typescript: 2.6.1
webpack: 3.8.1

Repro steps.

Put some node module inside one file
ng test --code-coverage --watch=false

The log given by the failure.

Error: Module not found: Error: Can't resolve 'fs' in '/Users/luca/src/app/core/service/config'

Desired functionality.

Prior to update the new version of angular cli and angular 5 the error didn't happen.
When I build or serve, no errors.
Fix this functionality before release the final version.

Most helpful comment

You can fix it, just add to the "package.json"

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

All 21 comments

yes, i have the same issue when i run ng test because i have jsonpath package and it use require('fs')

Same here

@Lughino can you show the offending code? are you trying to use nodes fs module?

@deebloo sure!
This is the code:

import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { readFile } from 'fs';
import { join } from 'path';
import { IEnvConfig } from './env.config';
import { RestApiClient } from '../rest-api-client/rest-api-client';

@Injectable()
export class ConfigService {

  private envConfig: IEnvConfig;

  constructor(@Inject(PLATFORM_ID) private platformId: Object, private restApiClient: RestApiClient) {
  }

  load() {
    if (isPlatformBrowser(this.platformId)) {
      return this.loadUsingHttpClient();
    } else {
      return this.loadFromFileSystem();
    }
  }

  private loadUsingHttpClient()  {
    return new Promise((resolve, reject) => {
      const DIVISOR = 1000;
      const cacheBuster = Math.round(new Date().getTime() / DIVISOR);

      this.restApiClient.get(`app/config/env.json?v=${cacheBuster}`)
        .catch(error => {
          reject(`Error loading env.json file: ${JSON.stringify(error)}`);
          return 'Server error';
        })
        .subscribe(envConfig => {
          this.envConfig = envConfig as IEnvConfig;
          resolve();
        });
    });
  }

  private loadFromFileSystem() {
    return new Promise((resolve) => {
      const DIST_FOLDER = join(process.cwd(), 'dist');
      readFile(`${DIST_FOLDER}/browser/app/config/env.json`, 'utf8', (err, data) => {
        if (err) {
          return this.handleError(err);
        }
        this.envConfig = JSON.parse(data);
        resolve();
      });
    }).catch(this.handleError);
  }

  private handleError(err) {
    console.log(`Error loading env.json file: ${JSON.stringify(err)}`);
    return 'Server error';
  }

  get (): IEnvConfig {
    return this.envConfig;
  }
}

Before upgrading to the new cli / angular 5, it was working fine.

Angular apps such as the ones Angular CLI creates are browser apps. fs isn't available on the browser, it's only available on node apps.

Even if it worked before this was never a supported feature. I'm sorry but this is working as intended :/

@filipesilva thanks for the feedback, but Angular applications are supposed to work in a "universal" context, so using different strategy between client and server is reasonable.
Also webpack support the ability to override the node modules when the target is the browser.
In my opinion this problem is related to the cli because it provide the webpack configuration, but we cannot override it without eject entirely.
I ask you to consider to support again this feature.

I fully agree with @Lughino

Closing this issue doesn't make any sense; why it's angular "Universal" if it's suppose to run on browsers only .. @filipesilva
what's the point of having isPlatformBrowser() if there is nothing other than browser needs to be supported

The app in this issue didn't seem to be a universal app. We have some support for universal apps but it requires custom setup as shown in https://github.com/angular/angular-cli/wiki/stories-universal-rendering. Unit tests are also not Universal apps either.

Maybe @MarkPieszak or @Toxicable can direct you to some more information about what node facilities are available with the Universal setup, but as for as the browser apps are concerned there is no fs available.

I had the same issue, when upgrading one of my angular 4.0 universal app to angular 5.
After spending hour, then finally fixed the issue with following snippet in the clientBundleConfig.
I'm not sure if this is the correct solution, someone may have better solution for the error.
node: { fs: "empty" }

I'm confused. How the hell am I supposed to use ngx-device-detector now?

@nguniversal/express-engine is a transitive dependency of ngx-device-detector that requires fs: https://github.com/angular/universal/blob/master/modules/express-engine/src/main.ts#L8

Now my tests are failing:

Error: Module not found: Error: Can't resolve 'fs' in './node_modules/@nguniversal/express-engine/src',Module not found: Error: Can't resolve 'fs' in './node_modules/@nguniversal/express-engine/src'

@filipesilva @Toxicable what do you guys recommend? I'm clueless. ):

@alfaproject Try adding @types/node to your project and make sure you have typeRoots: [ "node_modules/@types" ] in your tsconfig.

Let me know if that solves your issue

@Toxicable that's what I have already. ):

@alfaproject do you override that anywhere with a types: [ ... ] declaration?

Then how are we supposed to use Angular with Electron to make desktop apps if we cannot use node modules like fs, os etc?

@Toxicable nope, but it doesn't matter anymore, I guess. The dependency I was having issues with removed support for universal. \:

You can fix it, just add to the "package.json"

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

@pakhuta you save my times, thanks

You can fix it, just add to the "package.json"

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

@pakhuta
Implementing the above code opens up the browser window but shows "Not allowed to load local resource:" error. And the DevTools has node_modules/electron directory and not my project one.

it work for me to add the code after devdependencies

"browser": {
"crypto": false,
"fs": false,
"path": false,
"os": false,
"net": false,
"stream": false,
"tls": false
}

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

purushottamjha picture purushottamjha  路  3Comments

donaldallen picture donaldallen  路  3Comments

JanStureNielsen picture JanStureNielsen  路  3Comments

daBishMan picture daBishMan  路  3Comments

gotschmarcel picture gotschmarcel  路  3Comments