-
Notifications
You must be signed in to change notification settings - Fork 800
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support importWorkboxFrom: 'local' in the InjectManifest webpack plugin #1290
Changes from 4 commits
aae6b5a
782a25a
fc12572
4a85cf2
3183d66
1302a84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,10 +80,13 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { | |
const compiler = webpack(config); | ||
compiler.run((webpackError) => { | ||
if (webpackError) { | ||
expect(webpackError.message.includes('importWorkboxFrom')); | ||
done(); | ||
if (webpackError.message.includes('importWorkboxFrom')) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI, in the course of writing this PR, I discovered that this test pattern wasn't actually working as it was initially implemented: it should have been I took the opportunity to clean up this test along with the corresponding test in the |
||
done(); | ||
} else { | ||
done(new Error(`An unexpected error was thrown: ${webpackError.message}`)); | ||
} | ||
} else { | ||
done('Unexpected success.'); | ||
done(new Error('Unexpected success.')); | ||
} | ||
}); | ||
}); | ||
|
@@ -304,7 +307,6 @@ describe(`[workbox-webpack-plugin] GenerateSW (End to End)`, function() { | |
const basenames = libraryFiles.map((file) => path.basename(file)); | ||
expect(basenames).to.eql(ALL_WORKBOX_FILES); | ||
|
||
|
||
// The correct importScripts path should use the versioned name of the | ||
// parent workbox libraries directory. We don't know that version ahead | ||
// of time, so we ensure that there's a match based on what actually | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ const GenerateAssetPlugin = require('generate-asset-webpack-plugin'); | |
const HtmlWebpackPlugin = require('html-webpack-plugin'); | ||
const expect = require('chai').expect; | ||
const fse = require('fs-extra'); | ||
const glob = require('glob'); | ||
const path = require('path'); | ||
const tempy = require('tempy'); | ||
const vm = require('vm'); | ||
|
@@ -17,6 +18,47 @@ describe(`[workbox-webpack-plugin] InjectManifest (End to End)`, function() { | |
const WORKBOX_SW_FILE_NAME = getModuleUrl('workbox-sw'); | ||
const SRC_DIR = path.join(__dirname, '..', 'static', 'example-project-1'); | ||
const SW_SRC = path.join(__dirname, '..', 'static', 'sw-src.js'); | ||
const WORKBOX_DIRECTORY_PREFIX = 'workbox-'; | ||
const ALL_WORKBOX_FILES = [ | ||
'workbox-background-sync.dev.js', | ||
'workbox-background-sync.dev.js.map', | ||
'workbox-background-sync.prod.js', | ||
'workbox-background-sync.prod.js.map', | ||
'workbox-broadcast-cache-update.dev.js', | ||
'workbox-broadcast-cache-update.dev.js.map', | ||
'workbox-broadcast-cache-update.prod.js', | ||
'workbox-broadcast-cache-update.prod.js.map', | ||
'workbox-cache-expiration.dev.js', | ||
'workbox-cache-expiration.dev.js.map', | ||
'workbox-cache-expiration.prod.js', | ||
'workbox-cache-expiration.prod.js.map', | ||
'workbox-cacheable-response.dev.js', | ||
'workbox-cacheable-response.dev.js.map', | ||
'workbox-cacheable-response.prod.js', | ||
'workbox-cacheable-response.prod.js.map', | ||
'workbox-core.dev.js', | ||
'workbox-core.dev.js.map', | ||
'workbox-core.prod.js', | ||
'workbox-core.prod.js.map', | ||
'workbox-google-analytics.dev.js', | ||
'workbox-google-analytics.dev.js.map', | ||
'workbox-google-analytics.prod.js', | ||
'workbox-google-analytics.prod.js.map', | ||
'workbox-precaching.dev.js', | ||
'workbox-precaching.dev.js.map', | ||
'workbox-precaching.prod.js', | ||
'workbox-precaching.prod.js.map', | ||
'workbox-routing.dev.js', | ||
'workbox-routing.dev.js.map', | ||
'workbox-routing.prod.js', | ||
'workbox-routing.prod.js.map', | ||
'workbox-strategies.dev.js', | ||
'workbox-strategies.dev.js.map', | ||
'workbox-strategies.prod.js', | ||
'workbox-strategies.prod.js.map', | ||
'workbox-sw.js', | ||
'workbox-sw.js.map', | ||
]; | ||
|
||
describe(`[workbox-webpack-plugin] runtime errors`, function() { | ||
it(`should throw when swSrc is not set`, function() { | ||
|
@@ -44,39 +86,13 @@ describe(`[workbox-webpack-plugin] InjectManifest (End to End)`, function() { | |
const compiler = webpack(config); | ||
compiler.run((webpackError) => { | ||
if (webpackError) { | ||
expect(webpackError.message.includes('importWorkboxFrom')); | ||
done(); | ||
} else { | ||
done('Unexpected success.'); | ||
} | ||
}); | ||
}); | ||
|
||
it(`should throw when importWorkboxFrom is set to 'local'`, function(done) { | ||
const outputDir = tempy.directory(); | ||
const config = { | ||
entry: { | ||
entry1: path.join(SRC_DIR, WEBPACK_ENTRY_FILENAME), | ||
}, | ||
output: { | ||
filename: '[name]-[chunkhash].js', | ||
path: outputDir, | ||
}, | ||
plugins: [ | ||
new InjectManifest({ | ||
importWorkboxFrom: 'local', | ||
swSrc: SW_SRC, | ||
}), | ||
], | ||
}; | ||
|
||
const compiler = webpack(config); | ||
compiler.run((webpackError) => { | ||
if (webpackError) { | ||
expect(webpackError.message.includes('importWorkboxFrom')); | ||
done(); | ||
if (webpackError.message.includes('importWorkboxFrom')) { | ||
done(); | ||
} else { | ||
done(new Error(`An unexpected error was thrown: ${webpackError.message}`)); | ||
} | ||
} else { | ||
done('Unexpected success.'); | ||
done(new Error('Unexpected success.')); | ||
} | ||
}); | ||
}); | ||
|
@@ -240,12 +256,87 @@ describe(`[workbox-webpack-plugin] InjectManifest (End to End)`, function() { | |
|
||
const swFile = path.join(outputDir, path.basename(SW_SRC)); | ||
try { | ||
// First, validate that the generated service-worker.js meets some basic assumptions. | ||
await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { | ||
importScripts: [[ | ||
FILE_MANIFEST_NAME, | ||
workboxEntryName, | ||
]], | ||
suppressWarnings: [[]], | ||
precacheAndRoute: [[[], {}]], | ||
}}); | ||
|
||
// Next, test the generated manifest to ensure that it contains | ||
// exactly the entries that we expect. | ||
const manifestFileContents = await fse.readFile(path.join(outputDir, FILE_MANIFEST_NAME), 'utf-8'); | ||
const context = {self: {}}; | ||
vm.runInNewContext(manifestFileContents, context); | ||
|
||
const expectedEntries = [{ | ||
url: 'entry2-0c3c00f8cd0d3271089c.js', | ||
}, { | ||
url: 'entry1-3865b3908d1988da1758.js', | ||
}]; | ||
expect(context.self.__precacheManifest).to.eql(expectedEntries); | ||
|
||
done(); | ||
} catch (error) { | ||
done(error); | ||
} | ||
}); | ||
}); | ||
|
||
it(`should support setting importWorkboxFrom to 'local'`, function(done) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be cool to include a test where Webpack There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
const FILE_MANIFEST_NAME = 'precache-manifest.b6f6b1b151c4f027ee1e1aa3061eeaf7.js'; | ||
const outputDir = tempy.directory(); | ||
const config = { | ||
entry: { | ||
entry1: path.join(SRC_DIR, WEBPACK_ENTRY_FILENAME), | ||
entry2: path.join(SRC_DIR, WEBPACK_ENTRY_FILENAME), | ||
}, | ||
output: { | ||
filename: '[name]-[chunkhash].js', | ||
path: outputDir, | ||
}, | ||
plugins: [ | ||
new InjectManifest({ | ||
importWorkboxFrom: 'local', | ||
swSrc: SW_SRC, | ||
}), | ||
], | ||
}; | ||
|
||
const compiler = webpack(config); | ||
compiler.run(async (webpackError) => { | ||
if (webpackError) { | ||
return done(webpackError); | ||
} | ||
|
||
const swFile = path.join(outputDir, path.basename(SW_SRC)); | ||
try { | ||
// Validate the copied library files. | ||
const libraryFiles = glob.sync(`${WORKBOX_DIRECTORY_PREFIX}*/*.js*`, | ||
{cwd: outputDir}); | ||
|
||
const modulePathPrefix = path.dirname(libraryFiles[0]); | ||
|
||
const basenames = libraryFiles.map((file) => path.basename(file)); | ||
expect(basenames).to.eql(ALL_WORKBOX_FILES); | ||
|
||
// The correct importScripts path should use the versioned name of the | ||
// parent workbox libraries directory. We don't know that version ahead | ||
// of time, so we ensure that there's a match based on what actually | ||
// got copied over. | ||
const workboxSWImport = libraryFiles.filter( | ||
(file) => file.endsWith('workbox-sw.js'))[0]; | ||
|
||
// First, validate that the generated service-worker.js meets some basic assumptions. | ||
await validateServiceWorkerRuntime({swFile, expectedMethodCalls: { | ||
importScripts: [[ | ||
FILE_MANIFEST_NAME, | ||
workboxEntryName, | ||
workboxSWImport, | ||
]], | ||
setConfig: [[{modulePathPrefix}]], | ||
suppressWarnings: [[]], | ||
precacheAndRoute: [[[], {}]], | ||
}}); | ||
|
@@ -257,9 +348,9 @@ describe(`[workbox-webpack-plugin] InjectManifest (End to End)`, function() { | |
vm.runInNewContext(manifestFileContents, context); | ||
|
||
const expectedEntries = [{ | ||
url: 'entry2-0c3c00f8cd0d3271089c.js', | ||
url: 'entry2-17c2a1b5c94290899539.js', | ||
}, { | ||
url: 'entry1-3865b3908d1988da1758.js', | ||
url: 'entry1-d7f4e7088b64a9896b23.js', | ||
}]; | ||
expect(context.self.__precacheManifest).to.eql(expectedEntries); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think
JSON.stringify
is necessary?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's safer than wrapping the value in either
"..."
or'...'
, just on the off chancemodulePathPrefix
contains any quote characters. (Not that it should, but still.)JSON.stringify()
is guaranteed to return a properly escaped string.