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

Can't resolve 'net'/'global' or other node globals #9827

Closed
istiti opened this Issue Mar 1, 2018 · 31 comments

Comments

Projects
None yet
@istiti

istiti commented Mar 1, 2018

Versions

Angular CLI: 6.0.0-beta.4
Node: 8.9.3
OS: win32 x64
Angular: 6.0.0-beta.6
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

@angular/cdk: 5.2.3
@angular/cli: 6.0.0-beta.4
@angular/material: 5.2.3
@angular-devkit/build-optimizer: 0.4.3
@angular-devkit/core: 0.4.3
@angular-devkit/schematics: 0.4.3
@ngtools/json-schema: 1.2.0
@ngtools/webpack: 6.0.0-beta.4
@schematics/angular: 0.4.3
@schematics/package-update: 0.4.3
typescript: 2.6.2
webpack: 4.0.1

Repro steps

udpate from 1.7.2 to @next branch beta4

Observed problems:

1

it was working in 1.7.2 but not in @next branch I get in one module problem
image
But I fixed it after "npm i net"

2

after reinstalling 6beta4 I get:

Could not find local "typescript" package.The "@ngtools/webpack" package requires a local "typescript@^2.4.2" package to be installed.Error: Cannot find module 'typescript'
Error: Could not find local "typescript" package.The "@ngtools/webpack" package requires a local "typescript@^2.4.2" package to be installed.Error: Cannot find module 'typescript'
    at Object.<anonymous> (C:\...\i10\node_modules\@ngtools\webpack\src\index.js:18:11)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (C:\...node_modules\@angular\cli\models\webpack-config.js:3:19)
    at Module._compile (module.js:635:30)

Fixed after "npm update --next" and "npm i"

3

Then I have an deprecation warning:
image

4

Then I have strange long chunk name
image

5

Another point is when running ng build --build-optimizer --prod
It block at step : 70% building modules without never finish .

Mention any other details that might be useful (optional)

Maybe this is due to webpack4.0 resolution, any temp idea?

@istiti istiti changed the title from on v6beta4: module not found can't resolve 'net' to on 6beta4 many errors/weird behavior Mar 1, 2018

@alexzuza

This comment has been minimized.

alexzuza commented Mar 1, 2018

Can you describe steps you used to update your project?

@istiti

This comment has been minimized.

istiti commented Mar 1, 2018

  1. remove nodes_modules
  2. npm uninstall @angular/cli -g && npm install @angular/cli@next -g && npm install @angular/cli@next && npm i && ng s
@alexzuza

This comment has been minimized.

alexzuza commented Mar 1, 2018

Have you tried to remove package-lock.json file together with node_modules?

@istiti

This comment has been minimized.

istiti commented Mar 1, 2018

@alexzuza already disabled generating this file , thanks

@jskrzypek

This comment has been minimized.

jskrzypek commented Mar 1, 2018

@alexzuza @istiti I fairly certain your original issue with needing net is coming from this commit:
e84baa1 (master) / c7a8b61 (6.0.x)
(they're the same commit just in different branches form the release process afaik)

If you look, they've removed all of the node globals shimming. I'm currently trying to figure out how to overcome that, and put the node builtins back in the bundle.

We're having the same issue with jszip:
slack_-_yoobic

@intellix

This comment has been minimized.

Contributor

intellix commented Mar 1, 2018

Some things I've noticed having a poke at the next CLI with Webpack 4:

  • Serve compilation times are massively off (it says 11377ms but is actually more like 377ms)
  • Building is slightly slower by about 20sec for me (64405ms vs 81253ms).. or maybe it's a false time, I guess I would need to physically time it :)
  • Chunk names seem long and duplicated:
    • 1.7.1: chunk {thing.module} thing.module.db03a5a276313f5358e2.chunk.js () 19.9 kB [rendered]
    • 6.0.0 beta 4: chunk {5} thing-thing-module-ngfactory.fa3021a44cf5d19f158e.js (thing-thing-module-ngfactory) 27.3 kB [rendered]
  • Some modules are larger (19.9kb vs 27.3kb)
@alexzuza

This comment has been minimized.

alexzuza commented Mar 1, 2018

Just tried to update
@jskrzypek
I run into the same problem with jszip. Installing stream package manually solves the issue but i shouldn't do so.

@intellix
I also noticed that console output shows inaccurate time.

One more thing:
If we run cli as ng serve -o then new window will be opened after each rebuild.

@filipesilva

This comment has been minimized.

Member

filipesilva commented Mar 1, 2018

Heya, first of all I want to thank you all for trying the 6.x versions. They are still pretty raw and getting feedback early is super important to address problems.

The build times and chunkname bugs are unexpected, probably to do with Webpack 4 interop. We expect those to get fixed soon.

The problem with net/global is not so straightforward. We are removing it for 6.x, yes (#9812). And we do expect this to cause problems to some projects. But we're not doing it because we want to break projects, we're doing it because leaving it in also breaks other projects, and it is incorrect.

The incorrect part is libraries that are meant to run in the browser relying on node globals being available. Browser code runs in the browser, not in node, and shouldn't expect things that are not available in a browser context to be there.

For instance, if you open up your browser and type require('fs') you will get an error saying require does not exist. require is only available in node. But if you tried to import it some other way, like import('fs') (chrome supports import at the moment), you will also get an error saying it doesn't know what fs is. fs is also available only in node.

Some libraries use those constructs because they expect to be built in node, but to run in the browser. And they also expect the tooling that builds them to either provide a browser version of those node built-ins, or to pretend it's there when it actually is not.

In Angular CLI we never provided a browser version of node built-ins. But we did:

  • provide a shim for global and process.
  • supply an empty module when fs, crypto, tls and net were requested.

This is a problematic situation because even that can break some libraries (#5804), increase the size of others (#8130 (review)), and just generally make for a situation where browser code that shouldn't work at all works only when built in with very specific tooling. This is not a good situation. Browser code should not rely on things that are not available in browser environments.

We investigated the topic and reached this conclusion some time ago but did not remove support for this broken behaviour in CLI 1.x to avoid a breaking change. But now with 6.x it is a good time to make needed breaking changes.

You can find some more context in #8250, #8130, #8160, #5804 and #1548

We understand that this isn't great if your code relies, directly or indirectly, on a library that makes incorrect assumptions about browser environments. The best I can say is that you should bring this problem to their attention via an issue on their tracker. Maybe newer versions of that library don't have this behaviour anymore.

But although it is inconvenient to address these problems, I hope we can agree that the current behaviour is incorrect. Browser code should not rely on things that are not available in browser environments.

@jskrzypek

This comment has been minimized.

jskrzypek commented Mar 1, 2018

@filipesilva is there any chance we could pass in an override for the node webpack config to override the false? Since the options for the node property are all booleans or strings, it's completely encodable as json, and would be straightforward to add it to the .angular-cli.json config.

If you'll consider a PR adding support for that possibility, I'd be happy to make it.

@jskrzypek

This comment has been minimized.

jskrzypek commented Mar 1, 2018

@alexzuza I managed to fix my issue with jszip by changing the import from 'jszip' to 'jszip/dist/jszip.min', which is the more expected choice for web apps I guess...

@alexzuza

This comment has been minimized.

alexzuza commented Mar 1, 2018

@jskrzypek I don't import jszip directly. It's one of dependencies of my dependencies

@clydin

This comment has been minimized.

Member

clydin commented Mar 1, 2018

@alexzuza A path mapping in the app's tsconfig should allow redirection of the jszip import to the jszip/dist/jszip.min.js file.

Untested example:

paths: {
      'jszip': [ '../node_modules/jszip/dist/jszip.min.js' ],
    }

Ideally, since the package appears to ship a browser bundled version it should point the package.json field browser to the file. The CLI would then pick up that file and use it directly.

@alexzuza

This comment has been minimized.

alexzuza commented Mar 1, 2018

@clydin Big thank's for clarification.

It would be great if it was written under

BREAKING CHANGES
@angular/cli: Libraries/Packages must contain a web version if not web specific.

Update

The paths option works

Now only one thing annoys me :)

If we run cli as ng serve -o then new window will be opened after each rebuild.

@clydin

This comment has been minimized.

Member

clydin commented Mar 1, 2018

@alexzuza You're welcome. We are working on that last mentioned annoyance and should be fixed in the next release.

@istiti

This comment has been minimized.

istiti commented Mar 6, 2018

What I understand in this issue the asnwer to my problems:
number 1 : it's time to make breaking change in v6 and ask lib to update and make correct browser support

number 2: no reasons to solve/lost time here because magically if delete all uninstall all ts will install well

number 3: what about DeprecationWarning ?

number 4: long chunkname is webpack4 problem ?

number 5: @filipesilva you say it seems to be webpack4 problem too ? actually it block and never finish at step :
image
on my project

thanks to confirm

@istiti

This comment has been minimized.

istiti commented Mar 13, 2018

update to 6beta5:

   "ok": "npm run fr && npm run de",
    "fr": "node --max-old-space-size=8192 ./node_modules/@angular/cli/bin/ng build --build-optimizer --prod --app=prod --output-path dist/fr --locale fr --bh /fr/ --i18n-format xtb --i18n-file src/locale/fr.xtb",
    "de": "node --max-old-space-size=8192 ./node_modules/@angular/cli/bin/ng build --build-optimizer  --prod --app=prod --output-path dist/de --locale de --bh /de/ --i18n-format xtb --i18n-file src/locale/de.xtb",

when npm run ok i got build-optimizer can't run without --aot, then I remove --buildoptimizer and seems "ng build --prod" build with sourcemap and without aot/minify app, this is chaning ? we need yet specify that we don't want sourcemap ?and add --prod --aot to build aot+minify ? sorry i missed it in readme ? any links of changes ?

second my app is still blocking on build at 92% without moving to 100%

cc @filipesilva

@filipesilva

This comment has been minimized.

Member

filipesilva commented Mar 15, 2018

@istiti we're actually in the middle of moving a lot of things around and hope to have a more stable 6.0 beta soon, so some of those problems are not going to be solved in the next beta but should all be taken care of before 6.0 final.

@jslegers

This comment has been minimized.

jslegers commented Jul 30, 2018

@filipesilva :

The incorrect part is libraries that are meant to run in the browser relying on node globals being available. Browser code runs in the browser, not in node, and shouldn't expect things that are not available in a browser context to be there.

That's why some libraries have code that looks like this :

if (ENVIRONMENT_IS_NODE) {
  var fs = require("fs");
  var NODEJS_PATH = require("path");
  NODEFS.staticInit();
};

Such code used to run fine in Angular 5.

However, in Angular 6, this same code produces the following errors :

ERROR in ./lib/luciad/photon/photon_painter.js
Module not found: Error: Can't resolve 'fs' in 'D:\RIA ANGULAR\ria-angular-cli-2\lib\luciad\photon'
ERROR in ./lib/luciad/photon/photon_painter.js
Module not found: Error: Can't resolve 'path' in 'D:\RIA ANGULAR\ria-angular-cli-2\lib\luciad\photon'

This is simply ridiculous.


@clydin :

This is statement is not what is implied by the first:

"No library should support both browser and node".

Rather, a library should not assume its environment if it intends to support both node and a browser.

Of course. And that's why libraries have stuff like if (ENVIRONMENT_IS_NODE) { }, which now no longer seems possible with Angular 6. Thus, compatibility with Angular 6 prevents libraries from supporting both browser & Node.

None of those are truly wrong. They are all design decisions based on the complexity of the code, volume of platform-dependent APIs, and personal choice. The basic conditional, for instance, is quite acceptable if the API usage is minimal; or if combined with an abstraction layer that is then used throughout the package.

So are you saying I CAN use libraries that have stuff like if (ENVIRONMENT_IS_NODE) { } in them in Angular 6?

And if so, what would I need to do to get this to work?

@pharindoko

This comment has been minimized.

pharindoko commented Jul 30, 2018

well seems like someone else is even more frustrated than me ;D

ravikiran438 added a commit to ravikiran438/contentful-sdk-core that referenced this issue Aug 2, 2018

fix: return empty os for browser builds
Starting Angular CLI 6.x, no empty modules are supplied for node globals, see angular/angular-cli#9827

Khaledgarbaya added a commit to contentful/contentful-sdk-core that referenced this issue Aug 6, 2018

fix: return empty os for browser builds (#62)
* fix: return empty os for browser builds

* fix: return empty os for browser builds

Starting Angular CLI 6.x, no empty modules are supplied for node globals, see angular/angular-cli#9827

axe312ger added a commit to contentful/contentful-management.js that referenced this issue Aug 7, 2018

fix(bundlers): remove browser field in package.json to enable tree sh…
…aking

Starting Angular CLI 6.x, no empty modules are supplied for node globals, see:
angular/angular-cli#9827
contentful/contentful.js#260

axe312ger added a commit to contentful/contentful.js that referenced this issue Aug 7, 2018

fix(bundlers): remove browser field in package.json to enable tree sh…
…aking

Starting Angular CLI 6.x, no empty modules are supplied for node globals, see:
angular/angular-cli#9827
#260

xama5 added a commit to xama5/generate-password-browser that referenced this issue Sep 12, 2018

Fix #2
Angular 6 removed the shim for 'global', thus breaking this package.

See angular/angular-cli#9827 (comment)

@xama5 xama5 referenced this issue Sep 12, 2018

Merged

Fix #2 #3

@yadue

This comment has been minimized.

yadue commented Oct 12, 2018

Any update how to solve those issues?

@giovannipds

This comment has been minimized.

giovannipds commented Oct 31, 2018

How to bring access to node's process back again?
Tried something like: (window as any).process = process; or (window as any).process = window; at polyfills.ts but of course it didn't work. Doing that I have access to a process variable but it comes empty =S...
Update: rethink if you really need this, I was digging here 'cause of Ionic 4 and I ended up with the newest Ionic 4 environments no needing this access anymore.

@Nishkalkashyap

This comment has been minimized.

Nishkalkashyap commented Nov 2, 2018

For anyone still looking for an answer, here's how I managed to require('fs') in my angular 7 app. Or for that matter, any other node module.

Versions

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. Install @types/node

npm install --save-dev @types/node

2. Modify tsconfig.json

Take note of "allowSyntheticDefaultImports" flag. It must be set to 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. Require 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']);
    }
  }
}

Note: The import statements at the top of the file are just to provide for type information. The variable values are set using node require.

4. Result

electron-angular

Edit:

Turns out, that if your project has dependencies that require 'fs', 'path', 'child_process' etc. The angular compiler fails to compile the code. To get around this, as someone has already suggested, add (window as any).global = window; to your polyfills.ts.

In my case, I had chokidar, node-pty and electron as a dependency. This worker for me.

@vlkrrrr

This comment has been minimized.

vlkrrrr commented Nov 8, 2018

in an angular 7 app the workaround (#9827 (comment)) only works for me if i put

(window as any).global = window;

in a .ts file and import it in polyfill.ts , e.g. import 'cstm-polyfill.ts';

@danail-vasilev

This comment has been minimized.

danail-vasilev commented Dec 2, 2018

Hello, is there any lib for deflation that can be used with Angular 6 ?
Since the upgrade I am having the following issues with these zlibs:
devongovett/browserify-zlib#36
imaya/zlib.js#74
I've tried some workarounds, described in the issues above but to no avail.
p.s. I use pako for the deflation without any issue, however, the above is still valid for the mentioned libs.

@callen5914

This comment has been minimized.

callen5914 commented Dec 11, 2018

I followed the guidance you provided here and on my StackOverflow Question but it is still failing to compile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment