2

How do you structure a NodeJS package, containing wrapped C++ code that's compiled into web assembly, so that when you run npm install <package name>, the compilation step happens?

I have a package mypackage configured so that when I run npm run build in its project directory, C++ code is compiled into web assembly, and this is then bundled with other Javascript for the package.

I'm now trying to use this package from another project, and if I run npm install --save mypackage, it installs the package's Javascript, but doesn't run it's build process, so none of the web assembly is created, resulting in a broken package.

Cerin
  • 60,957
  • 96
  • 316
  • 522
  • Are you looking for node-gyp? https://stackoverflow.com/q/39739626/3001761 – jonrsharpe Sep 07 '20 at 16:29
  • 1
    One of the main benefits of Wasm is the you can build it once and run it anywhere, so most likely you just need to add the wasm file itself to the package rather than trying to find a way to have it compiled on every install. The other big reason to do this is to avoid developers having to have the emscripten compiler installed just to use your package. – sbc100 Sep 07 '20 at 19:51
  • @sbc100 Good point. – Cerin Sep 07 '20 at 21:18

1 Answers1

0

How you do it

In the scriptis section in package.json file, you can add a postinstall script, while will be run each time after a package is installed. You can find more about npm scripts here https://docs.npmjs.com/misc/scripts

inside pacakge.json

...
"scripts": {
 ...
 "postinstall": "npm run build"
}

Should you do it

The only valid reason to make build process happen at the target (consumer) system is if the build is dependent on the operating system or architecture of the target system, or is dependent on some configuration/properties of the target system. If the build is not related then it should be made at publishing time, this way it will be done once for all consumers, saving bandwidth, and time. usually also you save space because the bundled package is less than the source.

If you decide to package the built artifact (your bundled package) then its a good idea to use the prepublish script

"scripts": {
 ...
 // this will make sure that you are always publishing the most updated built artifact, instead of having to manually run build each time you want to publish
 "prepublish": "npm run build" 
}

Another good idea, is to also exclude the source files from the published package using .npmignore, to actually save space.

ehab
  • 7,162
  • 1
  • 25
  • 30