Skip to content
This repository has been archived by the owner on Sep 9, 2021. It is now read-only.

Commit

Permalink
fix: support WASM
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi authored Jul 13, 2020
1 parent 2b9e2fd commit 152634c
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 21 deletions.
30 changes: 25 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ import schema from './options.json';
import supportWebpack5 from './supportWebpack5';
import supportWebpack4 from './supportWebpack4';

let FetchCompileWasmPlugin;

try {
// Webpack 5
// eslint-disable-next-line global-require, import/no-unresolved
FetchCompileWasmPlugin = require('webpack/lib/web/FetchCompileWasmPlugin');
} catch (ignoreError) {
// Nothing
}

// Webpack 4
FetchCompileWasmPlugin =
FetchCompileWasmPlugin ||
// eslint-disable-next-line global-require, import/no-unresolved
require('webpack/lib/web/FetchCompileWasmTemplatePlugin');

export default function loader() {}

export function pitch(request) {
Expand All @@ -33,12 +49,13 @@ export function pitch(request) {
);

const worker = {};
const compilerOptions = this._compiler.options || {};
const chunkFilename = compilerOptions.output.chunkFilename.replace(
/\.([a-z]+)(\?.+)?$/i,
'.worker.$1$2'
);

worker.options = {
filename,
chunkFilename: `[id].${filename}`,
namedChunkFilename: null,
};
worker.options = { filename, chunkFilename, globalObject: 'self' };

worker.compiler = this._compilation.createChildCompiler(
'worker',
Expand All @@ -51,6 +68,9 @@ export function pitch(request) {
new NodeTargetPlugin().apply(worker.compiler);
}

new FetchCompileWasmPlugin({
mangleImports: compilerOptions.optimization.mangleWasmImports,
}).apply(worker.compiler);
new SingleEntryPlugin(this.context, `!!${request}`, 'main').apply(
worker.compiler
);
Expand Down
12 changes: 12 additions & 0 deletions test/__snapshots__/fallback-option.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,15 @@ exports[`"fallback" option should work by default: errors 1`] = `Array []`;
exports[`"fallback" option should work by default: result 1`] = `"{\\"postMessage\\":true,\\"onmessage\\":true}"`;

exports[`"fallback" option should work by default: warnings 1`] = `Array []`;

exports[`"fallback" option should work with "false" value and the "publicPath" options: errors 1`] = `Array []`;

exports[`"fallback" option should work with "false" value and the "publicPath" options: result 1`] = `"{\\"postMessage\\":true,\\"onmessage\\":true}"`;

exports[`"fallback" option should work with "false" value and the "publicPath" options: warnings 1`] = `Array []`;

exports[`"fallback" option should work with "true" value and the "publicPath" options: errors 1`] = `Array []`;

exports[`"fallback" option should work with "true" value and the "publicPath" options: result 1`] = `"{\\"postMessage\\":true,\\"onmessage\\":true}"`;

exports[`"fallback" option should work with "true" value and the "publicPath" options: warnings 1`] = `Array []`;
44 changes: 32 additions & 12 deletions test/fallback-option.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,75 @@ import {
compile,
getCompiler,
getErrors,
// getModuleSource,
getResultFromBrowser,
getWarnings,
} from './helpers';

describe('"fallback" option', () => {
it('should work by default', async () => {
const compiler = getCompiler('./basic/entry.js', { inline: true });
const stats = await compile(compiler);
const result = await getResultFromBrowser(stats);

expect(stats.compilation.assets['test.worker.js']).toBeDefined();
expect(result).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should should work with "true" value', async () => {
const compiler = getCompiler('./basic/entry.js', {
inline: true,
fallback: true,
});
const stats = await compile(compiler);
const result = await getResultFromBrowser(stats);

// expect(getModuleSource('./basic/worker.js', stats)).toMatchSnapshot(
// 'module'
// );
expect(stats.compilation.assets['test.worker.js']).toBeDefined();
expect(result).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should should work with "true" value', async () => {
it('should should work with "false" value', async () => {
const compiler = getCompiler('./basic/entry.js', {
inline: true,
fallback: false,
});
const stats = await compile(compiler);
const result = await getResultFromBrowser(stats);

expect(stats.compilation.assets['test.worker.js']).toBeUndefined();
expect(result).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work with "true" value and the "publicPath" options', async () => {
const compiler = getCompiler('./basic/entry.js', {
inline: true,
fallback: true,
publicPath: '/js/',
});
const stats = await compile(compiler);
const result = await getResultFromBrowser(stats);

// expect(getModuleSource('./basic/worker.js', stats)).toMatchSnapshot(
// 'module'
// );
expect(stats.compilation.assets['test.worker.js']).toBeDefined();
expect(result).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should should work with "false" value', async () => {
it('should work with "false" value and the "publicPath" options', async () => {
const compiler = getCompiler('./basic/entry.js', {
inline: true,
fallback: false,
publicPath: '/js/',
});
const stats = await compile(compiler);
const result = await getResultFromBrowser(stats);

// expect(getModuleSource('./basic/worker.js', stats)).toMatchSnapshot(
// 'module'
// );
expect(stats.compilation.assets['test.worker.js']).toBeUndefined();
expect(result).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
Expand Down
Binary file added test/fixtures/wasm/add.wasm
Binary file not shown.
24 changes: 24 additions & 0 deletions test/fixtures/wasm/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const Worker = require('./worker');

const worker = new Worker();

let result;

worker.onmessage = function (event) {
if (!result) {
result = document.createElement("div");
result.setAttribute('id', 'result');

document.body.append(result);
}

console.log(event)

result.innerText = JSON.stringify(event.data)
};

const button = document.getElementById('button');

button.addEventListener('click', () => {
worker.postMessage({ postMessage: true })
});
13 changes: 13 additions & 0 deletions test/fixtures/wasm/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>

<button id="button">Run Action</button>

</body>
</html>
9 changes: 9 additions & 0 deletions test/fixtures/wasm/worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
onmessage = async function(event) {
const workerResult = event.data;

const wasm = await import('./add.wasm');

workerResult.onmessage = wasm.add(10, 20);

postMessage(workerResult);
};
10 changes: 10 additions & 0 deletions test/helpers/getCompiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,15 @@ export default (fixture, loaderOptions = {}, config = {}) => {
...config,
};

if (webpack.version[0] === '5') {
if (!fullConfig.experiments) {
fullConfig.experiments = {};
}

fullConfig.experiments.importAsync = true;
fullConfig.experiments.importAwait = true;
fullConfig.experiments.asyncWebAssembly = true;
}

return webpack(fullConfig);
};
7 changes: 3 additions & 4 deletions test/inline-option.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('"inline" option', () => {
expect(getModuleSource('./basic/worker.js', stats)).toMatchSnapshot(
'module'
);
expect(stats.compilation.assets['test.worker.js']).toBeDefined();
expect(result).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
Expand All @@ -26,10 +27,7 @@ describe('"inline" option', () => {
const stats = await compile(compiler);
const result = await getResultFromBrowser(stats);

// TODO need fix absolute path
// expect(getModuleSource('./basic/worker.js', stats)).toMatchSnapshot(
// 'module'
// );
expect(stats.compilation.assets['test.worker.js']).toBeDefined();
expect(result).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
Expand All @@ -43,6 +41,7 @@ describe('"inline" option', () => {
expect(getModuleSource('./basic/worker.js', stats)).toMatchSnapshot(
'module'
);
expect(stats.compilation.assets['test.worker.js']).toBeDefined();
expect(result).toMatchSnapshot('result');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
Expand Down
14 changes: 14 additions & 0 deletions test/loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,18 @@ describe('worker-loader', () => {
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

// TODO fix for webpack@5, works fine with webpack@4
// it('should work with WASM', async () => {
// const compiler = getCompiler('./wasm/entry.js');
// const stats = await compile(compiler);
// const result = await getResultFromBrowser(stats);
//
// expect(getModuleSource('./wasm/worker.js', stats)).toMatchSnapshot(
// 'module'
// );
// expect(result).toMatchSnapshot('result');
// expect(getWarnings(stats)).toMatchSnapshot('warnings');
// expect(getErrors(stats)).toMatchSnapshot('errors');
// });
});

0 comments on commit 152634c

Please sign in to comment.