Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v6] Electron: Module not found: Error: Can't resolve 'fs' #10681

Closed
marcj opened this issue May 6, 2018 · 40 comments
Closed

[v6] Electron: Module not found: Error: Can't resolve 'fs' #10681

marcj opened this issue May 6, 2018 · 40 comments
Labels
area: @angular-devkit/build-angular feature Issue that requests a new feature

Comments

@marcj
Copy link

marcj commented May 6, 2018

Versions

Angular CLI: 6.0.0
Node: 9.11.1
OS: darwin x64
Angular: 6.0.0
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, http, language-service, material, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.6.0
@angular-devkit/build-angular     0.6.0
@angular-devkit/build-optimizer   0.6.0
@angular-devkit/core              0.3.2
@angular-devkit/schematics        0.6.0
@ngtools/webpack                  6.0.0
@schematics/angular               0.6.0
@schematics/update                0.6.0
rxjs                              6.1.0
typescript                        2.7.2
webpack                           4.7.0

Repro steps

When I develop an electron app (and thus have access to Node's fs module), I can't access node modules because typescript or webpack isn't able to resolve it.

import * as fs from 'fs'

Observed behavior

I get an error while building the application ng build:

WARNING in ./node_modules/zone.js/dist/zone-mix.js
Module not found: Error: Can't resolve 'fs' in '/Users/marc/bude/project/node_modules/zone.js/dist'

ERROR in ./src/main/home.ts
Module not found: Error: Can't resolve 'os' in '/Users/marc/bude/project/src/main'

ERROR in ./src/main/home.ts
Module not found: Error: Can't resolve 'path' in '/Users/marc/bude/project/src/main'

....

Desired behavior

I'd like to be able to use Node's modules and define somewhere in the angular.json configuration to allow certain modules (in other words: exclude them from the build process, as the Node runtime provides that stuff).

Mention any other details that might be useful (optional)

In Angular 5 I was able to eject and add in the webpack.config.js following lines at the root level:

  "externals": {
      "mongodb": 'require("mongodb")',
      "fs": 'require("fs")',
  },

However since Anuglar 6 does not provide an eject anymore, I'm not able to use that old webpack.config.json from v5 anymore. To make Angular 6 workable in Electron I need to be able to use a webpack.config.js again or maybe a config option in angular.json that allows me to define webpack's externals.

@sgruhier
Copy link

sgruhier commented May 8, 2018

I cannot use handlebarjs for the same reason :(
It's a blocker to upgrade to ng6

@clydin clydin added the feature Issue that requests a new feature label May 8, 2018
@jushar
Copy link

jushar commented May 9, 2018

I've been running into the same problem. Actually, I only need to use ng eject though to get externals to work and would prefer using angular-cli directly rather than having to eject.
So, at least for me, an externals option for the angular-cli.json/angular.json would help a lot and might also be a quick fix for this specific problem.

@b0bi79
Copy link

b0bi79 commented May 9, 2018

I've been running into the same problem. For ng serve, I get an error:

ERROR in ./node_modules/content-disposition/index.js
Module not found: Error: Can't resolve 'path' in 'D:\Sources\SSIV\Projects\Portal\angular\node_modules\content-disposition'

As a temporary solution, I changed var basename = require('path').basename to var basename = require('path-browserify').basename in the module content-disposition.

@bufke
Copy link

bufke commented May 9, 2018

I suspect I'm getting the same error using libsodium-sumo. After upgrading to angular 6 I get

ERROR in ./node_modules/libsodium-sumo/dist/modules-sumo/libsodium-sumo.js
Module not found: Error: Can't resolve 'path' in '/home/david/Projects/passit-frontend/node_modules/libsodium-sumo/dist/modules-sumo'

Should be easily reproducable on this branch.

Frustratingly, the path module isn't used at all in libsodium.js when used in a browser - it exists only when used in node. It's presence seems to trigger this error.

If I delete references to path, everything works including libsodium crypto.

@alexjlockwood
Copy link

Same issue... After attempting to upgrade to angular-cli v6, I get the following when attempting to run ng serve:

WARNING in ./node_modules/sax/lib/sax.js
Module not found: Error: Can't resolve 'stream' in '/Users/alockwood/ShapeShifter/node_modules/sax/lib'

ERROR in ./node_modules/svgo/lib/svgo/js2svg.js
Module not found: Error: Can't resolve 'os' in '/Users/alockwood/ShapeShifter/node_modules/svgo/lib/svgo'
ERROR in ./node_modules/jszip/lib/readable-stream-browser.js
Module not found: Error: Can't resolve 'stream' in '/Users/alockwood/ShapeShifter/node_modules/jszip/lib'

@ckruhs
Copy link

ckruhs commented May 10, 2018

Same issue here when using ng serve

WARNING in ./node_modules/xml2js/node_modules/sax/lib/sax.js
Module not found: Error: Can't resolve 'stream' in 'C:\Develop\djjb-news-reader\node_modules\xml2js\node_modules\sax\lib'

ERROR in ./node_modules/xml2js/lib/parser.js
Module not found: Error: Can't resolve 'timers' in 'C:\Develop\djjb-news-reader\node_modules\xml2js\lib'

@ocombe
Copy link
Contributor

ocombe commented May 10, 2018

I've found a "temporary" hack to make this work here: #4227 (comment)

You can also use window.require('fs') or any other node module, that should work

@sgruhier
Copy link

Did you try it?
I tried that and I still get Module not found: Error: Can't resolve 'fs' in '..../node_modules/handlebars/lib';

@ocombe
Copy link
Contributor

ocombe commented May 10, 2018

I guess it depends how your lib imports its dependencies, it works for electron and fs, but I just tried rxdb and the "pouchdb-adapter-localstorage" that imports "stream" fails :(

@ckruhs
Copy link

ckruhs commented May 10, 2018

My issue was solved by using npm install events buffer stream timers --save

Tip found here: https://stackoverflow.com/questions/50234196/after-updating-from-angular-5-to-6-i-keep-getting-the-error-cant-resolve-timer

@gimox
Copy link

gimox commented May 10, 2018

Same error here with fs and lokijs

@YoannBureau
Copy link

Same error with path here

@Chocobozzz
Copy link

Same here with path or fs and other node modules for a browser application. Some external dependencies require these modules (and check they exist at runtime) so we cannot upgrade our application to Angular 6.

These changes in this commit seem to be responsible for it: angular/devkit@8e7658a#diff-085e357d25d94ae495a662c157178fb0L103

@sgruhier
Copy link

This should be address as soon as possible. It blocks many people on ng6 upgrade.
In my case with handlebarjs, I imported handlebarjs.js in angular.json instead of using an import in my code. Not very sexy but at least it works.

@smoke
Copy link
Contributor

smoke commented May 15, 2018

By the way this is the reasoning behind this change #9827 (comment) and the relevant PR #9812 that is later ported in angular/devkit@8e7658a#diff-085e357d25d94ae495a662c157178fb0L103

I really hope there would be a reasonable solution - for now the best I can figure out is an option to override / supplement webpack configuration so that nodejs shimming can be defined per project.

Workaround (the best one I found, thanks @niespodd): https://gist.github.com/niespodd/1fa82da6f8c901d1c33d2fcbb762947d

@marcj
Copy link
Author

marcj commented May 15, 2018

Workaround: I've found a workaround that works for me: I downgraded angular-cli to version 1.7.4 and use there ng eject (which works for Angular 6 surprisingly). and then adjust webpack.config.js accordingly.

@sgruhier
Copy link

Great you find a fix for you
I'm not a huge fan of downgrading to CLI 1.7.4. And using eject just because of that issue doesn't look a good solution. Now you are stuck outside CLI. I hope it will be fix soon.

@Chocobozzz
Copy link

@smoke I completely understand the reasoning behind the change. But I don't understand why the Angular-CLI team did not provide a workaround (like an override option for example). We have 10 dependencies that rely on node modules (fs, path etc). How are we supposed to do? Fix all the dependencies ourselves? Staying on Angular CLI 1.7? Waiting an eject option?

I am very thankful to the Angular team to provide us an awesome framework with helpful tools (:heart:), but I spent many hours of my free time just to upgrade 1 element (Angular) of our application... and finally realize that we are at a dead end.

Maybe going back to Angular CLI 1.7 is the best solution for now, but please think about developers that just want to upgrade their application without running into a wall :)

@bufke
Copy link

bufke commented May 15, 2018

My current (hacky) workaround is running this as a postinstall script:

sed -i 's/require("path")/require("something-i-know-exists")/g' node_modules/some-package/file-error-is-in.js

In my case I don't use the node import that errors because my code only runs in a browser. So it can import the wrong package but who cares. This allows me to keep using the cli without ejecting webpack. It is of course a horrible, horrible hack.

@smoke
Copy link
Contributor

smoke commented May 15, 2018

I have placed one good workaround in my post #10681 (comment)

@Pilukina
Copy link

I've upgraded my application into Angularv6 and rxjsv6 succesfully.
After I upgrade from 1.7.4 to 6.0.5, I start getting similar messages to:

Module not found: Error: Can't resolve 'stream' in

I execute:

npm install stream events buffer asn1 timers vm --save

And the application compiles. When rendering the app on browser the first error is:

Uncaught ReferenceError: global is not defined
at Object../node_modules/buffer/index.js (index.js:43)

Which I fix by adding: (window as any).global = window; in polyfills.ts file.
Then I get:

ReferenceError: global is not defined
at Object../node_modules/buffer/index.js (index.js:43)>

TypeError: Cannot read property 'prototype' of undefined at inherits (inherits_browser.js:5) at Object../node_modules/hash-base/index.js (index.js:23) at __webpack_require__ (bootstrap:76) at Object../node_modules/md5.js/index.js (index.js:3) at __webpack_require__ (bootstrap:76) at Object../node_modules/create-hash/browser.js (browser.js:3) at __webpack_require__ (bootstrap:76) at Object../node_modules/crypto-browserify/index.js (index.js:4) at __webpack_require__ (bootstrap:76)

And now I don't know how to proceed...

@ghuser
Copy link

ghuser commented May 31, 2018

const fs = (<any>window).require("fs");

works for me on renderer side without any other modifications (angular5/6).
No build-time checks though.

@rezonant
Copy link
Contributor

rezonant commented Jun 28, 2018

Why are people patching node_modules? This can be solved using tsconfig paths instead. Please see my PR to PeerTube for an example: Chocobozzz/PeerTube#742

EDIT: OK this has problems with the final build, even though it works for dev build :-
EDIT 2: Never mind, the production build succeeds, I was on the wrong branch. This appears to be a good solution to this issue.

@kahboom
Copy link

kahboom commented Jul 5, 2018

Thanks @rezonant , that fixed it for me. I don't like patching node_modules either. My issue was only with fs being used by yamljs. I'm on Angular 6.0.4, CLI 6.0.7, Node 10.4.0, npm 6.1.0, yarn 1.7.0. Unfortunately, @slawiko 's workaround didn't work for me. I did the following:

package.json:

{
   "scripts": {
      "postinstall": "npm rebuild node-sass"
   }
}

tsconfig.json:

{
   "compilerOptions": {
      "paths": {
         "fs": [ "./global-shims" ]
      }
   }
}

Then, in a global-shims.ts file:

(window as any).global = window;

export const NOOP = 0;

@filipesilva
Copy link
Contributor

I'm sorry to say that we do not have support for the Electron platform currently in Angular CLI. We only support building browser apps, and while building browser apps the node native imports (like fs) are not available. You can read more about why we disabled these imports in #9827.

@doivosevic
Copy link

We do not need support for Electron. We only need the compiler to not fail when we include libraries which have been badly written to require fs for some marginal functionality which we wont be using from them. When you started enforcing this in 6 you made a serious breaking change which could be easily avoided if you allowed us to go around this and avoid the compiler error.

@ocombe
Copy link
Contributor

ocombe commented Jul 19, 2018

@filipesilva isn't the CLI supposed to support angular universal, which could use the same node APIs that electron uses?

@sgruhier
Copy link

Just found this https://github.com/angular-guru/electron-builder (not tested but looks great)

@Nishkalkashyap
Copy link

Here's my workaround, works both in ng serve and ng build. #9827 (comment)

@mdg1019
Copy link

mdg1019 commented Nov 30, 2018

Try ngx-electron. It solved issues like this for me.

@zztiswb116
Copy link

This should be address as soon as possible. It blocks many people on ng6 upgrade.
In my case with handlebarjs, I imported handlebarjs.js in angular.json instead of using an import in my code. Not very sexy but at least it works.

how imported handlebarjs.js in angular.json

@Cythia828
Copy link

I have the same issue in my React-Redux project.I have use npm install "fs".But when I import * as fs from 'fs',there's a error....
ERROR in ./src/features/pages/myOwnPage/myPage/list.js
Module not found: Error: Can't resolve 'fs' in '/Users/xuxiaoqi/Desktop/work/myOwnTest/src/features/pages/myOwnPage/myPage'

@B40914109
Copy link

I create a new angular project: ng new ngapp1.
vesion:
Angular CLI:8.0.2
Node: 10.16.0
OS: win32 x64

now, I modify the file : app.component.ts, add some code
import * as fs from 'fs';
console.log(fs);

then I process the cmd: ng serve, I get a isssue:
./src/app/app.component.ts
Module not found: Error: Can't resolve 'tls' in 'C:\Users\Administrator\ngapp1\src\app'

I think it's a simple issue.but i don't know how to fix it. and i find many people have the same question.
Does anyone can help us?
Give a detailed solution. when anyone else has the same question, we can do by this way.
Thanks.

@Nishkalkashyap
Copy link

I struggled with this problem for a long time. But I believe the best way to get around this error once and for all is to use a custom webpack build.

I'm using this angular-builder to add the custom webpack config.

After adding the builder, if you're targeting electron you can do something like this:-

module.exports = {
    ...
    output: {
        globalObject: 'self',
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    target: 'electron-renderer'
}

If you're targeting web, you can do something like this:-

module.exports = {
    ...
    target: 'web',
    node: { fs: 'empty' }
}

This is not a perfect config, but once you add webpack to the build process, the world opens up to you for your specific use cases. Simply move to stack overflow to find an answer.

I've tested this builder with angular version 6, 7, 8 without any problems.

@sataqi
Copy link

sataqi commented Jul 25, 2019

Update: Solved with help from SO Answer

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: @angular-devkit/build-angular feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests