Skip to content

Commit

Permalink
Use tapPromise to fix Webpack plugin async issues
Browse files Browse the repository at this point in the history
  • Loading branch information
sonkkeli committed May 23, 2023
1 parent 775d47c commit 24b567c
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 3 deletions.
44 changes: 44 additions & 0 deletions packages/rollup-plugin-webbundle/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import test from 'ava';
import * as path from 'path';
import * as rollup from 'rollup';
import crypto from 'crypto';
import url from 'url';
import * as wbn from 'wbn';
import * as wbnSign from 'wbn-sign';
Expand Down Expand Up @@ -395,3 +396,46 @@ test("integrityBlockSign with undefined baseURL doesn't fail", async (t) => {
t.is(keys.length, 1);
t.is(output[keys[0]].fileName, outputFileName);
});

// To make sure actually async things work.
test('integrityBlockSign with sleeping CustomSigningStrategy', async (t) => {
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

class CustomSigningStrategy {
async sign(data) {
await sleep(500);
return crypto.sign(
/*algorithm=*/ undefined,
data,
TEST_ED25519_PRIVATE_KEY
);
}

async getPublicKey() {
await sleep(500);
return crypto.createPublicKey(TEST_ED25519_PRIVATE_KEY);
}
}

const outputFileName = 'out.swbn';

const bundle = await rollup.rollup({
input: 'fixtures/index.js',
plugins: [
webbundle({
output: outputFileName,
integrityBlockSign: {
strategy: new CustomSigningStrategy(),
},
}),
],
});
const { output } = await bundle.generate({ format: 'esm' });
const keys = Object.keys(output);
t.is(keys.length, 1);
t.is(output[keys[0]].fileName, outputFileName);
});
19 changes: 16 additions & 3 deletions packages/webbundle-webpack-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,30 @@ export class WebBundlePlugin implements WebpackPluginInstance {

apply = (compiler: Compiler) => {
if (isWebpackMajorV4()) {
compiler.hooks.emit.tap(this.constructor.name, this.process);
compiler.hooks.emit.tapPromise(
this.constructor.name,
async (compilation: Compilation) => {
return new Promise(async (resolve, _reject) => {

Check failure on line 101 in packages/webbundle-webpack-plugin/src/index.ts

View workflow job for this annotation

GitHub Actions / lint

Promise executor functions should not be async

Check warning on line 101 in packages/webbundle-webpack-plugin/src/index.ts

View workflow job for this annotation

GitHub Actions / lint

'_reject' is defined but never used
await this.process(compilation);
resolve();
});
}
);
} else {
compiler.hooks.thisCompilation.tap(
this.constructor.name,
(compilation: Compilation) => {
compilation.hooks.processAssets.tap(
compilation.hooks.processAssets.tapPromise(
{
name: this.constructor.name,
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER,
},
() => this.process(compilation)
async () => {
return new Promise(async (resolve, _reject) => {

Check failure on line 117 in packages/webbundle-webpack-plugin/src/index.ts

View workflow job for this annotation

GitHub Actions / lint

Promise executor functions should not be async

Check warning on line 117 in packages/webbundle-webpack-plugin/src/index.ts

View workflow job for this annotation

GitHub Actions / lint

'_reject' is defined but never used
await this.process(compilation);
resolve();
});
}
);
}
);
Expand Down
35 changes: 35 additions & 0 deletions packages/webbundle-webpack-plugin/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import test from 'ava';
import crypto from 'crypto';
import webpack from 'webpack';
import MemoryFS from 'memory-fs';
import url from 'url';
Expand Down Expand Up @@ -297,3 +298,37 @@ test("integrityBlockSign with undefined baseURL doesn't fail", async (t) => {
});
t.deepEqual(memfs.readdirSync('/out').sort(), ['example.swbn', 'main.js']);
});

// The webpack plugin had a bug that it didn't work for actually async code so
// this test will prevent that from occurring again.
test('integrityBlockSign with sleeping CustomSigningStrategy', async (t) => {
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

class CustomSigningStrategy {
async sign(data) {
await sleep(500);
return crypto.sign(
/*algorithm=*/ undefined,
data,
TEST_ED25519_PRIVATE_KEY
);
}

async getPublicKey() {
await sleep(500);
return crypto.createPublicKey(TEST_ED25519_PRIVATE_KEY);
}
}

const { memfs } = await run({
output: 'async.swbn',
integrityBlockSign: {
strategy: new CustomSigningStrategy(),
},
});
t.deepEqual(memfs.readdirSync('/out').sort(), ['async.swbn', 'main.js']);
});

0 comments on commit 24b567c

Please sign in to comment.