Angular-cli: Outdated buffer sub dependency causes `global is not defined` error

Created on 28 Oct 2019  ·  9Comments  ·  Source: angular/angular-cli

🐞 Bug report

Following #8160 I found that it is still possible to cause the global ist not defined error without installing a library that actively uses global. It is caused by buffer which is a sub dependency of @angular-devkit/build-angular.

Command (mark with an x)

No command. It is a runtime issue. Any command that builds the project obviously.

Is this a regression?

Yes, the regression is obviously the removal of the global shim.

Description

@angular-devkit/build-angular depends on a version of webpack, which depends on a version of node-libs-browser (deprecated!) which depends on a version of buffer that is actually using global.

$ npm ls buffer
[email protected] /Users/ohcibi/Documents/Projekte/PERK/iotgen/iotgen-webui
└─┬@angular-devkit/[email protected]
  └─┬ [email protected]
    └─┬ [email protected]
      └── [email protected]

The latest versions of the buffer package have fixed that but since node-libs-browser is deprecated, this won't fix on webpack4. webpack 5 does not have the node-libs-browser dependency anymore.

The library I have installed and try to import was jwt-simple.

🔬 Minimal Reproduction

npm install -D jwt-simple
# Add `import jwt from 'jwt-simple' to some angular module
ng serve
# Visit route that uses the module with the import and see error in console

🔥 Exception or Error


index.js:43 Uncaught ReferenceError: global is not defined
    at Object../node_modules/buffer/index.js (index.js:43)
    at __webpack_require__ (bootstrap:79)
    at Object../node_modules/safe-buffer/index.js (index.js:2)
    at __webpack_require__ (bootstrap:79)
    at Object../node_modules/randombytes/browser.js (browser.js:15)
    at __webpack_require__ (bootstrap:79)
    at Object../node_modules/crypto-browserify/index.js (index.js:3)
    at __webpack_require__ (bootstrap:79)
    at Object../node_modules/jwt-simple/lib/jwt.js (jwt.js:13)
    at __webpack_require__ (bootstrap:79)

🌍 Your Environment



     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / ‚ñ≥ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 8.3.12
Node: 12.12.0
OS: darwin x64
Angular: 8.1.3
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.14
@angular-devkit/build-angular     0.803.14
@angular-devkit/build-optimizer   0.803.14
@angular-devkit/build-webpack     0.803.14
@angular-devkit/core              8.3.14
@angular-devkit/schematics        8.3.12
@angular/cli                      8.3.12
@ngtools/webpack                  8.3.14
@schematics/angular               8.3.12
@schematics/update                0.803.12
rxjs                              6.4.0
typescript                        3.4.5
webpack                           4.39.2



blocked on upstream devkibuild-angular browser low broken triage #1 bufix

Most helpful comment

@zl810881283 For libraries that assume the presence of Node.js, the recommended solution is to shim the global value for browsers via the following as found in this comment:

// Add global to window, assigning the value of window itself.
(window as any).global = window;

All 9 comments

Interesting. Wasn't expecting any of the node libraries to be included since we set the node option in webpack to false for browser builds.

But maybe webpack special-cases crypto as it's also a browser API? I expected it to just leave it as window.crypto or something.

I get the feeling we'll have to wait for Webpack 5 to address this.

crypto is a Node.js specific API. Newer browsers contain the Web Cryptography API (https://www.w3.org/TR/WebCryptoAPI/#introduction). While they both provide cryptography functionality, they are vastly different.

It is also important to note that enabling any of the Webpack node shims/polyfills is considered unsupported behavior. Alternatively, if using the path mapping method, the developer will need to ensure that all requirements of the path mapped shim are also covered within the application. It is highly recommended to use packages that truly support the browser platform or are cross-platform to avoid issues such as this. And related to this, Webpack 5 will default to disabling all node shimming.

That might all be true but the purpose of this issue is that the information that’s spread out about that error is not accurate. What you find is that it’s the libraries authors and thus the choice of the developer to use that libraries fault that it happens. But in this case the library is not doing anything deprecated but the broken shim that webpack 4 depends on and won’t change that is. Ironically while being a browser shim itself. So for this instance of this error it’s a simple regression that is caused by removing the shims from angular-cli while webpack wasn’t ready for that. Clearly this removal should have waited for webpack removing that broken dependency and the information about that situation needs to be updated instead of simply blaming other library authors to do deprecated stuff (after all the deprecated dependency causing trouble here comes from angular-cli itself).

The library in question is using “crypto” which does not exist in a browser and as a result is not a browser compatible library. Using shims or polyfills to attempt to work around the issue is and will always be complex and problematic. Especially in this case as it appears that the shims themselves require shims making them not cross platform as well. Libraries that are not cross platform or web specific should be avoided when possible. Not only do issues such as this result but it can also cause performance and size concerns for the application.

In regards to “crypto” itself in this context, It is highly recommended to use built in and fully validated cryptographic implementations. This is especially important when related to security and authorization/authentication use cases. On a browser that would be the Web Cryptography API.

Is there a way to fix this temporarily?

@zl810881283 For libraries that assume the presence of Node.js, the recommended solution is to shim the global value for browsers via the following as found in this comment:

// Add global to window, assigning the value of window itself.
(window as any).global = window;

Is there a more practical resolution to this issue besides the somewhat elitist/ivory tower sounding response of "use better libs and tell your lib author to be better people" that seems to be being advocated here?

There are many libs, examples, demos, and so on that have been broken by these changes, and those of us affected by them aren't as interested in engaging in a philosophical debate as we are in simply getting our projects functional again.

@alzeebum you have to wait for angular-cli using webpack 5 since the "bad lib" is from angular-cli itself and not anyone that you have installed.

@clydin wrongly assumed that this issue is about security regarding crypto vs webcryptoapi and thus moved this issue out of focus. I don't expect any fix for this except said upgrade to webpack 5.

I am facing same issue,

Angular CLI: 9.1.7
Node: 12.3.0
OS: darwin x64

Angular: 9.1.1
... animations, common, compiler, core, platform-browser
... platform-browser-dynamic, router, upgrade
Ivy Workspace: Yes

Package Version

@angular-devkit/architect 0.901.7
@angular-devkit/build-angular 0.901.7
@angular-devkit/build-ng-packagr 0.901.7
@angular-devkit/build-optimizer 0.901.7
@angular-devkit/build-webpack 0.901.7
@angular-devkit/core 9.1.7
@angular-devkit/schematics 9.1.7
@angular/cdk 9.0.0
@angular/cli 9.1.7
@angular/compiler-cli 9.1.9
@angular/elements 9.0.1
@angular/forms 9.1.9
@angular/http 7.2.15
@ngtools/webpack 9.1.7
@nguniversal/express-engine 7.1.1
@schematics/angular 9.1.7
@schematics/update 0.901.7
ng-packagr 9.0.0-rc.7
rxjs 6.5.5
typescript 3.8.3
webpack 4.41.5

Even after adding ,
// Add global to window, assigning the value of window itself.
(window as any).global = window;

also not getting solve

index.js:43 Uncaught ReferenceError: global is not defined
at Object.../../node_modules/buffer/index.js (index.js:43)
at __webpack_require__ (bootstrap:19)
at Object.../../node_modules/safe-buffer/index.js (index.js:2)
at __webpack_require__ (bootstrap:19)
at Object.../../node_modules/jws/lib/sign-stream.js (sign-stream.js:2)
at __webpack_require__ (bootstrap:19)
at Object.../../node_modules/jws/index.js (index.js:2)
at __webpack_require__ (bootstrap:19)
at Object.../../node_modules/jsonwebtoken/decode.js (decode.js:1)
at __webpack_require__ (bootstrap:19)
../../node_modules/buffer/index.js @ index.js:43
__webpack_require__ @ bootstrap:19
../../node_modules/safe-buffer/index.js @ index.js:2
__webpack_require__ @ bootstrap:19
../../node_modules/jws/lib/sign-stream.js @ sign-stream.js:2
__webpack_require__ @ bootstrap:19
../../node_modules/jws/index.js @ index.js:2
__webpack_require__ @ bootstrap:19
../../node_modules/jsonwebtoken/decode.js @ decode.js:1
__webpack_require__ @ bootstrap:19
../../node_modules/jsonwebtoken/index.js @ index.js:2
__webpack_require__ @ bootstrap:19
../../libs/rules/src/lib/enigma/enigma.service.ts @ selectors.ts:11
__webpack_require__ @ bootstrap:19
../../libs/rules/src/lib/performance/rules-performance.component.ts @ main.js:19389
__webpack_require__ @ bootstrap:19
../../libs/rules/src/lib/tfc-rules.module.ts @ tfc-rules.constants.ts:7
__webpack_require__ @ bootstrap:19
../../libs/rules/src/index.ts @ index.ts:1
__webpack_require__ @ bootstrap:19
./src/app/platform.module.ts @ platform.component.ts:17
__webpack_require__ @ bootstrap:19
./src/main.ts @ main.ts:2
__webpack_require__ @ bootstrap:19
0 @ main.ts:8
__webpack_require__ @ bootstrap:19
(anonymous) @ bootstrap:83
(anonymous) @ bootstrap:83

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rajjejosefsson picture rajjejosefsson  ·  3Comments

hartjo picture hartjo  ·  3Comments

brtnshrdr picture brtnshrdr  ·  3Comments

daBishMan picture daBishMan  ·  3Comments

hareeshav picture hareeshav  ·  3Comments