Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/wasm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"rollup-plugin"
],
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0||^5.0.0"
},
"peerDependenciesMeta": {
"rollup": {
Expand All @@ -69,7 +69,7 @@
"devDependencies": {
"@rollup/plugin-typescript": "^9.0.1",
"del-cli": "^5.0.0",
"rollup": "^4.0.0-24",
"rollup": "catalog:rollup-next",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Build tool outgrows Node 20

Both CI matrices and .nvmrc still select Node 20, but catalog:rollup-next selects Rollup 5, which requires Node 22.22.0 or newer. The package's build script runs that Rollup directly, putting local builds and the Node 20 CI jobs outside its supported environment. Update the build environment alongside this dependency, or keep a supported build tool for Node 20.

"source-map": "^0.7.4",
"typescript": "^4.8.3"
},
Expand Down
32 changes: 18 additions & 14 deletions packages/wasm/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,32 @@ export function wasm(options: RollupWasmOptions = {}): Plugin {
return null;
},

load(id) {
load(id, loadOptions) {
if (id === HELPERS_ID) {
return getHelpersModule(targetEnv);
}

if (!filter(id)) {
const rawId = loadOptions?.rawId ?? id;

if (!filter(rawId)) {
return null;
}

if (!/\.wasm$/.test(id)) {
if (!/\.wasm$/.test(rawId)) {
return null;
}
this.addWatchFile(id);
this.addWatchFile(rawId);

return Promise.all([fs.promises.stat(id), fs.promises.readFile(id)]).then(
return Promise.all([fs.promises.stat(rawId), fs.promises.readFile(rawId)]).then(
([stats, buffer]) => {
if (targetEnv === 'auto-inline') {
return buffer.toString('binary');
}

if ((maxFileSize && stats.size > maxFileSize) || maxFileSize === 0) {
const hash = createHash('sha1').update(buffer).digest('hex').substr(0, 16);
const ext = path.extname(id);
const name = path.basename(id, ext);
const ext = path.extname(rawId);
const name = path.basename(rawId, ext);

const outputFileName = fileName
.replace(/\[hash\]/g, hash)
Expand All @@ -66,8 +68,8 @@ export function wasm(options: RollupWasmOptions = {}): Plugin {
const publicFilepath = `${publicPath}${outputFileName}`;

// only copy if the file is not marked `sync`, `sync` files are always inlined
if (syncFiles.indexOf(id) === -1) {
copies[id] = {
if (syncFiles.indexOf(rawId) === -1) {
copies[rawId] = {
filename: outputFileName,
publicFilepath,
buffer
Expand All @@ -80,14 +82,16 @@ export function wasm(options: RollupWasmOptions = {}): Plugin {
);
},

transform(code, id) {
if (!filter(id)) {
transform(code, id, transformOptions) {
const rawId = transformOptions?.rawId ?? id;

if (!filter(rawId)) {
return null;
}

if (code && /\.wasm$/.test(id)) {
const isSync = syncFiles.indexOf(id) !== -1;
const publicFilepath = copies[id] ? `'${copies[id].publicFilepath}'` : null;
if (code && /\.wasm$/.test(rawId)) {
const isSync = syncFiles.indexOf(rawId) !== -1;
const publicFilepath = copies[rawId] ? `'${copies[rawId].publicFilepath}'` : null;
let src;

if (publicFilepath === null) {
Expand Down
5 changes: 5 additions & 0 deletions packages/wasm/test/fixtures/attributes-and-plain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* eslint-disable import/no-duplicates */
import plain from './sample.wasm';
import attributed from './sample.wasm' with { type: 'webassembly' };

export default { attributed, plain };
10 changes: 10 additions & 0 deletions packages/wasm/test/fixtures/attributes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import sample from './sample.wasm' with { type: 'webassembly' };

// eslint-disable-next-line no-undef
globalThis.atob = (str) => Buffer.from(str, 'base64').toString('binary');

// eslint-disable-next-line no-undef
result = (async () => {
const { instance } = await sample({ env: {} });
t.is(instance.exports.main(), 3, 'wasm loaded');
})();
32 changes: 28 additions & 4 deletions packages/wasm/test/test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ const testBundle = async (t, bundle) => {
const func = new AsyncFunction('t', `let result;\n\n${code}\n\nreturn result;`);
return func(t);
};
test('loads wasm imported with import attributes', async () => {
expect.assertions(1);
const bundle = await rollup({
input: 'fixtures/attributes.js',
plugins: [wasmPlugin()]
});
await testBundle(avaAssertions, bundle);
});
test('async compiling', async () => {
expect.assertions(2);
const bundle = await rollup({
Expand Down Expand Up @@ -57,6 +65,18 @@ test('fetching WASM from separate file', async () => {
expect(await globby(glob)).toMatchSnapshot();
await del(outputDir);
});
test('emits one asset when the same wasm is imported with and without attributes', async () => {
expect.assertions(2);
const warnings = [];
const bundle = await rollup({
input: 'fixtures/attributes-and-plain.js',
plugins: [wasmPlugin({ maxFileSize: 0 })],
onwarn: (warning) => warnings.push(warning)
});
const { output } = await bundle.generate({ format: 'cjs' });
expect(output.filter(({ fileName }) => fileName.endsWith('.wasm'))).toHaveLength(1);
expect(warnings).toEqual([]);
});
test('complex module decoding', async () => {
expect.assertions(2);
const bundle = await rollup({
Expand Down Expand Up @@ -148,7 +168,8 @@ test('target environment auto', async () => {
wasmPlugin({
targetEnv: 'auto'
})
]
],
treeshake: false
});
const code = await getCode(bundle);
await testBundle(avaAssertions, bundle);
Expand All @@ -164,7 +185,8 @@ test('target environment auto-inline', async () => {
wasmPlugin({
targetEnv: 'auto-inline'
})
]
],
treeshake: false
});
const code = await getCode(bundle);
await testBundle(avaAssertions, bundle);
Expand All @@ -181,7 +203,8 @@ test('target environment browser', async () => {
wasmPlugin({
targetEnv: 'browser'
})
]
],
treeshake: false
});
const code = await getCode(bundle);
await testBundle(avaAssertions, bundle);
Expand All @@ -196,7 +219,8 @@ test('target environment node', async () => {
wasmPlugin({
targetEnv: 'node'
})
]
],
treeshake: false
});
const code = await getCode(bundle);
await testBundle(avaAssertions, bundle);
Expand Down
Loading
Loading