wasm-pack icon indicating copy to clipboard operation
wasm-pack copied to clipboard

Add type = "module" in package.json to support nodejs in bundler mode

Open josephg opened this issue 3 years ago β€’ 5 comments

πŸ’‘ Feature description

When you build using the default "bundler" mode, it can almost run directly from nodejs, using nodejs's built in ESM support.

Unfortunately, the created package.json file is missing "type": "module". Adding this to the created package.json not only fixes some bundler issues, but also makes nodejs understand the created package too:

foo.js:

import {greet} from 'my_module'
greet()
$ node --experimental-wasm-modules foo.js
(node:414396) ExperimentalWarning: Importing Web Assembly modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Hello world!

josephg avatar Jul 26 '21 08:07 josephg

Using node 14.17.3 (the current LTS release) I was able to get node to load the "bundler" version of the package.

To make it work, I had to add a main entry to the package.json as well as the "type": "module" (otherwise I just got Error [ERR_MODULE_NOT_FOUND]: Cannot find package...).

I also had to work around a typescript issue: the current releases of typescript generates require where import is needed. I could fix the generated js manually, or switch to pre-releases builds of the compiler with: https://github.com/microsoft/TypeScript/pull/44501 which actually works! (use "typescript": "npm:@typescript-deploys/[email protected]" which is mentioned in the PR discussion)

So with those two items added to the generated package.json, and that typescript compiler per-release, I'm able to use a single package in both nodejs and in the browser.

@josephg Thanks so much for posting this: I'd never have tried this approach without your suggestion!

CraigMacomber avatar Jul 27 '21 05:07 CraigMacomber

It seems like you should only need that fancy version of typescript to support having mixed mode JS files. Typescript should be able to compile using esm mode in the currently released typescript versions. I haven't tried it though.

josephg avatar Jul 28 '21 11:07 josephg

It seems like you should only need that fancy version of typescript to support having mixed mode JS files. Typescript should be able to compile using esm mode in the currently released typescript versions. I haven't tried it though.

I can't change the module type for the package doing the import (multiple unrelated import of third party packages break if I change it), so I needed an alternative. But in general, yes, compiling to an esm module should be a solution.

CraigMacomber avatar Jul 29 '21 17:07 CraigMacomber

I've just written up the process of getting the hello-wasm-pack example to work under Next.js. It was not altogether painless :-) and included manually editing the package under node_modules to be the kind of ESM that Next.js will work with. Please check out https://github.com/gthb/try-to-use-wasm-in-next.js/blob/main/README.md and consider changing the package.json in the wasm-pack bundler output accordingly (I've posted a PR for that).

gthb avatar Sep 22 '21 18:09 gthb

I am using this simple script after build to automatically add "type":"module"' to package.json after build:

const fs = require("fs"); // replace with import fs from 'fs'; if you need
const packageFileContent = fs.readFileSync("./pkg/package.json", "utf-8");
const packageJSON = JSON.parse(packageFileContent);
packageJSON.type = "module";
packageJSON.main = packageJSON.module;
fs.writeFileSync("./pkg/package.json", JSON.stringify(packageJSON, null, 2), "utf-8");

neuronetio avatar Jul 20 '22 17:07 neuronetio

It’d be great to see https://github.com/rustwasm/wasm-pack/pull/1061 merged! I’ve crafted a demo where I use --targer=bundler and then manually patch package.json. It confirms that the proposed solution works in Node.js, Jest and Next.js πŸŽ‰

kachkaev avatar Oct 14 '22 12:10 kachkaev

i really don't understand why this is still an issue.

this effectively breaks imports and forces all of us to do hacks and workarounds. this is a very popular package, and it definitely deserves more attention from the core team! To the core team, you don't need to implement this yourself, just MERGE THE PRs and publish it. we are happy then!

woss avatar Oct 17 '22 09:10 woss

@drager sorry to ping, but would really love to see this PR merged. We're using an npm module built with wasm-pack, and we're unable to use it natively in Node + ES Modules because it wrongly declares itself as a CommonJS module. I am more than happy to help with any polish or other tasks to get this over the finish line.

vacekj avatar Apr 29 '23 09:04 vacekj

Another temporary fix could be using the Linux jq command, e.g.:

"wasm-patch": "jq '.type = \"module\"' ./your-pkg/package.json > ./your-pkg/package.json.tmp && mv ./your-pkg/package.json.tmp ./your-pkg/package.json",

Then run it after you run wasm-pack.

(The temporary file is necessary unless you're willing to install extra packages)

LeoDog896 avatar Jul 23 '23 15:07 LeoDog896

It would be nice to be really nice to have more control over the package.json in general (including whether it's generated). For a recent project I ended up deleting it on build and just made my own wrapping package.json at the root of the project.

AlansCodeLog avatar Jul 25 '23 00:07 AlansCodeLog

This issue is a must for everyone who is learning wasm-pack for the first time.

Hello, new wasmer.

You can try this:

npm pkg set type='module'
npm pkg set main='<your_crate>.js'

magicwenli avatar Sep 09 '23 11:09 magicwenli

Bumping this; closing this issue by merging any of the above PRs or implementing any of the above solutions would be appreciated by many. I'm needing WASM more and more as I get into systems + web development, and having this issue closed would resolve a major hurdle in my adoption of this. Don't mean to be a pain, and apologies if this ping comes off poorly.

ben-laird avatar Nov 13 '23 16:11 ben-laird

Bumping this; closing this issue by merging any of the above PRs or implementing any of the above solutions would be appreciated by many. I'm needing WASM more and more as I get into systems + web development, and having this issue closed would resolve a major hurdle in my adoption of this. Don't mean to be a pain, and apologies if this ping comes off poorly.

Yes, need to rebase master into the current PR in order to get that merged.

drager avatar Nov 14 '23 06:11 drager

Yes, need to rebase master into the current PR in order to get that merged.

Done. (Well, merged, not rebased, from master β€” but I think the PR should just be squash-merged to master anyway, right?)

gthb avatar Nov 14 '23 10:11 gthb

Yes, need to rebase master into the current PR in order to get that merged.

Done. (Well, merged, not rebased, from master β€” but I think the PR should just be squash-merged to master anyway, right?)

Thank you!

drager avatar Nov 14 '23 19:11 drager