diff --git a/src/index.js b/src/index.js index de25f10..8618e0c 100644 --- a/src/index.js +++ b/src/index.js @@ -70,15 +70,13 @@ class SWPrecacheWebpackPlugin { // sw-precache needs physical files to reference so we MUST wait until after assets are emitted before generating the service-worker. compiler.plugin('after-emit', (compilation, callback) => { this.configure(compiler, compilation); // configure the serviceworker options - - const done = () => callback(); - const error = (err) => callback(err); + this.checkWarnings(compilation); // generate service worker then write to file system this.createServiceWorker() - .then(serviceWorker => this.writeServiceWorker(serviceWorker, compiler, callback)) - .then(this.checkWarnings(compilation)) - .then(done, error); + .then(serviceWorker => this.writeServiceWorker(serviceWorker, compiler)) + .then(() => callback()) + .catch(err => callback(err)); }); } @@ -196,12 +194,18 @@ class SWPrecacheWebpackPlugin { }); } - writeServiceWorker(serviceWorker, compiler, callback) { + writeServiceWorker(serviceWorker, compiler) { + const promisify = func => (...args) => new Promise((resolve, reject) => func(...args, (err, result) => { + return err ? reject(err) : resolve(result); + })); + const mkdirp = promisify(compiler.outputFileSystem.mkdirp); + const writeFile = promisify(compiler.outputFileSystem.writeFile); + const {filepath} = this.workerOptions; // use the outputFileSystem api to manually write service workers rather than adding to the compilation assets - return compiler.outputFileSystem.mkdirp(path.resolve(filepath, '..'), - () => compiler.outputFileSystem.writeFile(filepath, serviceWorker, callback)); + return mkdirp(path.resolve(filepath, '..')) + .then(() => writeFile(filepath, serviceWorker)); } /** diff --git a/test/plugin.spec.js b/test/plugin.spec.js index 48831ad..28841f0 100644 --- a/test/plugin.spec.js +++ b/test/plugin.spec.js @@ -196,15 +196,12 @@ test.serial('#createServiceWorker()', async t => { plugin.configure(compiler, compilation); return callback(); }); - await runCompiler(compiler); - t.truthy(await plugin.createServiceWorker(), 'generate something'); }); -test.serial('#writeServiceWorker(serviceWorker, compiler, callback)', async t => { +test.serial('#writeServiceWorker(serviceWorker, compiler)', async t => { t.plan(2); - const filepath = path.resolve(__dirname, 'tmp/service-worker.js'); const compiler = webpack(webpackConfig()); const plugin = new SWPrecacheWebpackPlugin({filepath}); @@ -215,10 +212,12 @@ test.serial('#writeServiceWorker(serviceWorker, compiler, callback)', async t => plugin.apply(compiler); compiler.plugin('after-emit', (compilation, callback) => { - plugin.writeServiceWorker(serviceWorker, compiler, callback); + plugin.writeServiceWorker(serviceWorker, compiler) + .then(() => callback()) + .catch(err => callback(err)); }); - await runCompiler(compiler); + await runCompiler(compiler); t.truthy(await fsExists(filepath), 'service-worker should exist'); }); @@ -257,7 +256,7 @@ test.serial('importScripts[] should support entry point & dynamically imp 'some-script-path.js', {filename: 'some-script-path.[hash].js'}, {chunkName: 'sw'}, - {chunkName: 'service-worker-imported-script-2'} + {chunkName: 'service-worker-imported-script-2'}, ], }); @@ -313,9 +312,11 @@ test.serial('should keep [hash] in importScripts after configuring SW', async t const plugin = new SWPrecacheWebpackPlugin({filepath, importScripts: ['some_sw-[hash].js']}); plugin.apply(compiler); - compiler.plugin('after-emit', (compilation) => { + compiler.plugin('after-emit', (compilation, callback) => { plugin.configure(compiler, compilation); + callback(); }); + await runCompiler(compiler); t.truthy(plugin.options.importScripts[0] === 'some_sw-[hash].js', 'hash should be preserve after writing the sw'); @@ -329,8 +330,9 @@ test.serial('should not modify importScripts value when no [hash] is provided', const plugin = new SWPrecacheWebpackPlugin({filepath, importScripts: ['some_script.js']}); plugin.apply(compiler); - compiler.plugin('after-emit', (compilation) => { + compiler.plugin('after-emit', (compilation, callback) => { plugin.configure(compiler, compilation); + callback(); }); await runCompiler(compiler);