jspm / project

Roadmap and management repo for the jspm project
161 stars 8 forks source link

Error messages when trying to import several packages #91

Closed iandunn closed 3 years ago

iandunn commented 3 years ago

Hi, I just discovered JSPM and love the idea, kudos!

I've gotten several packages to work, but others are giving me errors. I'm not sure if I'm doing something wrong, but I've read the docs and tried different variations on the URL & the import. I didn't see anything specifically relevant in the other issues I read either, but that might be because I don't have enough knowledge to notice it.

// These both get "Uncaught TypeError: Path must be a string. Received undefined"
import { default as generatePassphrase } from 'https://jspm.dev/npm:eff-diceware-passphrase@3.0';
//import { default as securePassword } from 'https://jspm.dev/npm:secure-password@4.0';

// This gets "Uncaught TypeError: can't access property "_handle", stream is undefined"
//import { default as argon2 } from 'https://jspm.dev/npm:argon2@0.27';

// This works
//import { default as entropy } from 'https://jspm.dev/npm:ideal-password@2.3';
//console.log( { entropy: entropy( 'hello world' ) } );

Sandbox: https://codepen.io/iandunn/pen/GRNgQMV?editors=0010

How can I troubleshoot if it's something I'm doing wrong, something the package is doing wrong, or a bug in JSPM?

Thanks!

guybedford commented 3 years ago

Hey, glad to hear it's interesting to you and thanks for posting, always happy to dive into these.

So the issue with the first one seems to be that the secure-random-uniform package depends on libsodium which obviously only runs in Node.js because it uses native bindings. From what I can tell it doesn't seem to have a browser build - https://unpkg.com/browse/secure-random-uniform@4.0.0/package.json.

secure-random-uniform itself seems to be loaded by secure-shuffle. This package also doesn't have any browser build, and directly depends on the secure-random-uniform package - https://unpkg.com/browse/secure-shuffle@2.0.0/index.js.

eff-diceware-passphrase in turn directly depends on secure-random-uniform, so it seems this package has no browser compatibility path without a PR to secure-random-uniform to add a "browser" field or otherwise that uses a secure random shuffle in the browser eg based on web crypto random, or itself depends on a universal random library that will work in browser.

The issue with secure-password is exactly the same as it directly depends on sodium native.

The argon2 issue seems to be a similar kind of thing as it indirectly depends on native bindings as well as npmlog which attempts to operate on process.stdout without checking if it is supported. We could actually get the npmlog check to pass by ensuring process.stdout and process.stdin are defined in jspm core, which seems worthwhile.

Even if we get that line to pass though (that _handle bug which is a trival fix), my concern is that the next failure will then just be the native binaries not working, as argon2 directly attempts to use them - line 9 of https://unpkg.com/browse/argon2@0.27.1/argon2.js with direct usage in every code path.

So these all seem to be native binary packages without any browser support. Hope that helps get a clearer picture.

iandunn commented 3 years ago

Ah, that makes sense, thanks!

In the future I'll check the browser field in package.json, and more generally look for alternate builds.

I also just noticed that I overlooked this part of the docs:

All CommonJS modules are effectively converted into export default module.exports as an ECMAScript module. That is, they should always be imported as import cjs from 'cjs',

...which seems like it would have been a problem even if there'd been a browser build.

guybedford commented 3 years ago

No problem at all!

...which seems like it would have been a problem even if there'd been a browser build.

Actually, no, this is the correct semantics for Node.js build all bundlers are aligning on. See https://nodejs.org/dist/latest-v15.x/docs/api/esm.html#esm_interoperability_with_commonjs for more info.

iandunn commented 3 years ago

Ah, ok,

import { default as generatePassphrase } from 'https://jspm.dev/npm:eff-diceware-passphrase@3.0';

is the same as:

import generatePassphrase from 'https://jspm.dev/npm:eff-diceware-passphrase@3.0';

That make sense. Thanks!