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

Fix npm package #2394

Merged
merged 19 commits into from
Apr 18, 2022
Merged

Fix npm package #2394

merged 19 commits into from
Apr 18, 2022

Conversation

hoodmane
Copy link
Member

When we load pyodide from node_modules, the calculated indexURL
starts with file:// which causes trouble. Truncate it off.

Work towards fixing #2393.

When we load pyodide from node_modules, the calculated indexURL
starts with `file://` which causes trouble. Truncate it off.
@hoodmane hoodmane changed the title Fix calculateIndexURL when file is loaded from node_modules Fix node package Apr 12, 2022
src/js/rollup.config.js Show resolved Hide resolved
const fileName = ErrorStackParser.parse(err)[0].fileName!;
let fileName = ErrorStackParser.parse(err)[0].fileName!;
if (IN_NODE && fileName.startsWith("file://")) {
fileName = fileName.slice("file://".length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could use an explanatory comment about why we are doing this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well we get file://path but node expects paths not to start with file://

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, and I assume this would also work when importing pyodide js from local files? Could you please add a comment that this is necessary when determining indexURL with remote URLs in node?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this would also work when importing pyodide js from local files?

Well yeah. The path shouldn't ever start with file:// in Node. If it starts with file:// we remove it, if not we leave it alone. I think a sort of related issue is that in compat.ts in node we check if the path starts with https:// in which case we make a web request otherwise we make a fs operation. But the fs operations get mad about paths starting with file://. Maybe a better solution would be to remove this in compat.ts.

src/js/compat.ts Show resolved Hide resolved
Copy link
Member

@rth rth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, a couple more comments otherwise LGTM. Also opened #2397 to improve a bit the quality control of this package before the release.

But yeah, since none of us has much experience with typescript, we are doing what we can :)

src/js/package.json Outdated Show resolved Hide resolved
src/js/package.json Outdated Show resolved Hide resolved
// If we are IN_NODE, download the package from the cdn, then stash it into
// the node_modules directory for future use.
let binary = await _loadBinaryFile(cdnURL, file_name);
await nodeFsPromisesMod.writeFile(`${baseURL}${file_name}`, binary);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very sure of this. IMO this kind of behavior should better be more explicit. For example, puppeteer downloads binaries during installation (though that is not what we want because Pyodide is not only for server-side usage), or playwright provides a command playwright install to download binaries after installation.

Copy link
Member Author

@hoodmane hoodmane Apr 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe take a config variable? My main concern is that packages.json is still going to include all of these packages but the request will fail when it tries to open the file which doesn't exist.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My main concern is that packages.json is still going to include all of these packages but the request will fail when it tries to open the file which doesn't exist.

Yes, I also think it would be great if people don't need to download packages manually. So providing a way of automatically downloading packages would be nice for the user experience.

My opinion is that we should let Pyodide users know what is going on. They need to know that whl files are not included in the npm packages and those will be downloaded after installation.

If we are going to download packages in runtime as in this PR, I think there needs a proper log telling that it is downloading and stashing packages.

Maybe take a config variable

Yeah, a config variable for deciding whether to download missing packages in runtime (or die with error) would be nice IMO. It would also be nice if CDN URLs can be configured at the top level as there were some requests.
Still, I think it would be great to provide an explicit way to install packages before runtime (maybe $ npx pyodide install or something?) and recommend that way. The advantages of downloading them before runtime will be:

  • If there is a problem in the CDN, it can be checked beforehand.
  • Running time is stabilized (we don't need to download a large package at the first run)
  • We can verify checksums of packages beforehand.

Copy link
Member Author

@hoodmane hoodmane Apr 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe $ npx pyodide install or something?

I am not likely to work on this myself too soon, but I am happy if someone else would do it.

In the meantime, I'm not sure what we should do in this PR. If you have an opinion, I would be happy for you to put in code that you like (you can push it directly to this branch). I think I agree with you about the long term solution, but I'm not what the best intermediate solutions are.

I think there needs a proper log telling that it is downloading and stashing packages.

Perhaps adding logging to this for now would be okay? Or we could remove it from this PR and throw an error if a missing package is loaded?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps adding logging to this for now would be okay?

Yeah I am okay with that for this PR. Perhaps let's not document this behavior for now. Thanks for working on this!

I am not likely to work on this myself too soon, but I am happy if someone else would do it.

I'll open a issue so we can revisit this later.

if (!pyodide.version.includes("dev")) {
// Currently only used in Node to download packages the first time they are
// loaded. But in other cases it's harmless.
API.setCdnUrl(`https://pyodide-cdn2.iodide.io/v${pyodide.version}/full/`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't iodide.io url deprecated BTW?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably. I still primarily use it...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps let's use https://cdn.jsdelivr.net as in our documentation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, we should definitely not use it, it doesn't cache well. I'm thinking we should fully discontinue it soon.

Copy link
Member

@ryanking13 ryanking13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on node issues @hoodmane!

@hoodmane hoodmane changed the title Fix node package Fix npm package Apr 18, 2022
@hoodmane hoodmane merged commit e5a46e5 into pyodide:main Apr 18, 2022
@hoodmane hoodmane deleted the node-index-url branch April 18, 2022 04:10
@hoodmane
Copy link
Member Author

Thanks for the reviews @rth and @ryanking13!

ryanking13 pushed a commit that referenced this pull request May 2, 2022
Various fixes to improve the npm package.

Switch to publishing the dist folder, fix indexURL for node, 
fix node commonJS import and ES6 import only publish core 
Pyodide interpreter to npm, download and cache other wheels 
on first use.
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

Successfully merging this pull request may close these issues.

None yet

3 participants