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

Failing in web client projects due to NodeJS usage without polyfills. #156

Closed
preston opened this issue Aug 16, 2022 · 13 comments
Closed

Failing in web client projects due to NodeJS usage without polyfills. #156

preston opened this issue Aug 16, 2022 · 13 comments

Comments

@preston
Copy link

preston commented Aug 16, 2022

I'm updating an Angular 14 app which uses webpack 5. Older versions of webpack had included polyfills for NodeJS functions by default. Now that this is no longer the case, fhirclient seems to break immediately due to Node functions being missing. Below is the error. Anyone using a client-side webapp framework that does not include Node polyfills should be getting this error.

./node_modules/fhirclient/lib/security/server.js:12:17-34 - Error: Module not found: Error: Can't resolve 'crypto' in '/Users/preston/Developer/git/angular-on-fhir/node_modules/fhirclient/lib/security'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }
@vlad-ignatov
Copy link
Collaborator

Can you provide more info on how you are importing this library? I noticed that your error comes from security/server.js, while on the client-side security/browser.js should be the imported one.

@preston
Copy link
Author

preston commented Aug 17, 2022

@vlad-ignatov Just import FHIR from 'fhirclient', which is how the documentation examples work, here: http://docs.smarthealthit.org/client-js/#client

@vlad-ignatov
Copy link
Collaborator

I see. It does appear to be a bug. I can start working on it tomorrow. Meanwhile, perhaps the only fix for you (other than using a bundle via script tag) would be to add new DefinePlugin({ "IS_BROWSER": true }) to the plugins array of your webpack config. Example: https://github.com/smart-on-fhir/client-js/blob/master/webpack.config.js#L26

@preston
Copy link
Author

preston commented Aug 17, 2022

Much appreciated! I'm happy to help test. -Preston

@vlad-ignatov
Copy link
Collaborator

I think I might be close to releasing a fix in the next version. Before I do that, it would be great if you can test and verify that your issue is solved. To do so:

npm rm fhirclient
npm i https://github.com/smart-on-fhir/client-js.git

@preston
Copy link
Author

preston commented Aug 17, 2022

Using the current repo I can get the project to compile by change the import to import FHIR from 'fhirclient/dist';, but still get a runtime error related to use of the global object by 'browser.js'. (Screenshots attached.) Here's where it blows up..

Screen Shot 2022-08-17 at 11 42 42 AM

Screen Shot 2022-08-17 at 11 48 18 AM

@preston
Copy link
Author

preston commented Aug 17, 2022

I think this is it:

const crypto: Crypto = global.crypto || require("isomorphic-webcrypto").default

vlad-ignatov added a commit that referenced this issue Aug 17, 2022
@vlad-ignatov
Copy link
Collaborator

Oh, yes. This is a hack needed for testing only. We use the native Crypto, or msCrypto in IE11 via "isomorphic-webcrypto". This line just allows tests to "inject" the NodeJS Crypto in there, because JsDOM does not have one...

I have pushed a fix for that: afab420#diff-b5c64cf5995872585d4cb25310e8720be856fce951df0ca1a260b12dddc8808cR4-R6

@preston
Copy link
Author

preston commented Aug 17, 2022

I haven't extensively tested it, but am at least getting through the initial SMART launch redirect by FHIR.oauth2.authorize(..) now. :)

@vigneshkv23
Copy link

Same issue,
While creating the new image we are seeing this issue with Angular 12.
Note- Changed to 2.4.0 build succeeded

./node_modules/fhirclient/lib/security/server.js:14:15-32 - Error: Module not found: Error: Can't resolve 'crypto' in '/apps/healthunitysmartauth/node_modules/fhirclient/lib/security'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
	- install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "crypto": false }
The command '/bin/sh -c /opt/app-root/src/.npm-global/bin/ng build' returned a non-zero code: 1	

@vlad-ignatov
Copy link
Collaborator

The fix should now be released in [email protected]

@preston
Copy link
Author

preston commented Aug 18, 2022

Working now. Thanks!

@mzbik
Copy link

mzbik commented Feb 28, 2023

When serving an angular app (via embedded EHR launch) from http://localhost:4200/... in Chrome 110.0.5481.177, I get:
globalThis.crypto = some instance of Crypto not SubtleCrypto which has globalThis.crypto.digest === undefined.

This causes digestSha256 in browser.js(37) to fail. I suggest broadening the test in browser.js(10) to include a test for globalThis.crypto.subtle === undefined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants