FredKSchott / snowpack

ESM-powered frontend build tool. Instant, lightweight, unbundled development. ✌️
https://www.snowpack.dev
MIT License
19.48k stars 922 forks source link

[BUG] "files" entries from package.json, and specifically .wasm files, are not in build output #3440

Closed ahupp closed 3 years ago

ahupp commented 3 years ago

Bug Report Quick Checklist

Describe the bug

My snowpack project depends on a local package that includes a .wasm file. This setup works fine under snowpack dev (the .wasm file can be loaded) but the .wasm file is not emitted with snowpack build. If I manually copy it over everything works fine.

To Reproduce

This project depends on rustup and wasm-pack:

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$ curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

To repro:

$ git clone https://github.com/ahupp/stamp-maker
$ cd stamp-maker/www
$ npm run deploy

See that the .wasm file is not included in the snowpack build:

$ ls ../wasm/pkg
package.json  README.md  stamp-maker_bg.wasm  stamp-maker_bg.wasm.d.ts  stamp-maker.d.ts  stamp-maker.js
$ ls build/_snowpack/link/wasm/pkg/
stamp-maker.js

Expected behavior

Snowpack will emit each of entries in the files field in ../wasm/pkg/package.json (stamp-maker-wasm) into the output directory.

Anything else?

Happy to take a stab at this if you point me in the wright direction.

drwpow commented 3 years ago

Hm. This may be a bug, but if Snowpack is missing files it’s usually because it can’t find a reference to them anywhere. How are you loading the .wasm files in JavaScript or HTML? If you are importing that somewhere, but Snowpack isn’t picking it up, then we can write a test for that and squish that bug.

By default, Snowpack doesn’t arbitrarily copy files from src/ over if it can’t detect they’re being used in the final build. Otherwise you’d end up with a ton of clutter from the original source files left over, and possibly stuff you didn’t want in production.

But sometimes you want to copy files over! In that scenario, I’d recommend using the static option like so in your Snowpack config:

module.exports = {
  mount: {
    src: './dist',
    wasm: { url: './dist/wasm', static: true }
  },
};
ahupp commented 3 years ago

I found that wasm-pack has different output modes, and the "web" mode is manually loading the .wasm file rather than using import. Switching to "bundler" mode fixes it for me. Docs: https://rustwasm.github.io/wasm-pack/book/commands/build.html Thanks for the useful pointer!

ahupp commented 3 years ago

I spoke too soon; the bundler mode does:

import wasm from "./the.wasm";

Which doesn't actually work in a browser (yet). I ended up doing this, with an alias entry and an additional mount for the root URL (with the help of snowpack-plugin-wasm-pack:

  alias: {
    "stamp-maker-wasm": "../wasm/pkg",
  },
  mount: {
    "../wasm/pkg": {
      url: "/dist/stamp-maker-wasm",
      static: true,
      resolve: true,
    },
    "./": {
      url: "/",
    },
  },

It would be really nice if snowpack supported this case, and I think it's really close. I'll comment with some thoughts on https://github.com/snowpackjs/snowpack/discussions/1053