-
-
Notifications
You must be signed in to change notification settings - Fork 375
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
Adds brotli support for modern javascript #674
Conversation
Note: We can extend this support to css files as well |
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.
Couple of things, some important some not.
packages/cli/lib/lib/sw.js
Outdated
// Before saving the response in cache, we need to treat the headers. | ||
async cacheWillUpdate({request, response}) { | ||
if (/.js.br$/.test(request.url)) { | ||
const headers = response.headers; |
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.
Would this work instead of manually cloning?
response = response.clone();
response.headers.set('content-type', 'application/javascript')
return response;
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.
This should – it's what my service workers are doing, tho I just pray that they work
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.
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.
my bad - this would work though:
const headers = new Headers(clonedResponse.headers);
newHeaders.set('content-type', 'application/javascript');
return new Response(await clonedResponse.text(), { headers })
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.
fixed
}), | ||
); | ||
} | ||
if (config['sw']) { |
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.
Any reason this isn't config.sw
?
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.
nups, fixed
sw: swSrc, | ||
}, | ||
target: 'webworker', | ||
output: { |
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.
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.
done.. i guess?
filename: '[name]-esm.js', | ||
beforeStartExecution: (plugins) => { | ||
plugins.forEach(plugin => { | ||
if (plugin.constructor.name === 'DefinePlugin' && plugin.definitions) { |
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.
What's the reason for only mutating values in-place here - does this fix DefinePlugin
definitions leaking into the parent compiler?
Otherwise this could just be
plugins.forEach(plugin => {
if (plugin.constructor.name === 'DefinePlugin') {
if (!plugin.definitions) throw Error('ESM Error: DefinePlugin found without definitions.');
plugin.definitions['process.env.ES_BUILD'] = 'true';
}
});
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.
good point, i can chk that
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.
works, fixed
|
||
let swSrc = resolve(__dirname, './../sw.js'); | ||
if (fs.existsSync(resolve(`${src}/sw.js`))) { | ||
console.log(yellow('⚛️ Info - CLI found sw.js in source root folder, using that to compile the final service worker instead')); |
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.
Nit: can we make this a different color like blue? yellow seems like a warning, this is informational.
Also maybe shorten the message since it's a heads-up that will be shown every build? Or only show the message when things change (first build or sw.js added/removed):
// only warn on first build, OR on rebuild if sw.js is added/removed:
let swSrc = resolve(__dirname, './../sw.js');
const exists = fs.existsSync(resolve(`${src}/sw.js`));
if (exists !== global.hasSeenSw) {
global.hasSeenSw = exists;
if (exists) {
console.log(blue('⚛️ Detected custom sw.js: compiling instead of default Service Worker.'));
}
else {
console.log(blue('⚛️ No custom sw.js detected: compiling default Service Worker.'));
}
}
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.
done
); | ||
}; | ||
)]; | ||
if (env.sw) { |
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.
Is the Array return here done with the intention of moving to a MultiCompiler? This seems like it'll break in future Workbox versions that use child compilation.
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.
How is the child compiler affected by the its parent compilation mode?
@developit I re-did this with a child compiler, please review |
# Conflicts: # packages/cli/lib/lib/entry.js # packages/cli/lib/lib/webpack/webpack-client-config.js # packages/cli/package.json
sw: swSrc, | ||
}; | ||
childCompiler.options.target = 'webworker'; | ||
childCompiler.options.output = JSON.parse( |
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.
@developit @ForsakenHarmony do we have any dep already which can help me do this deepcopy?
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.
nvm fixed it
packages/cli/lib/commands/build.js
Outdated
@@ -22,6 +23,15 @@ module.exports = async function(src, argv) { | |||
); | |||
} | |||
|
|||
if (argv.brotli) { | |||
console.log( |
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.
guess this should use the util log fn
) | ||
); | ||
} else { | ||
console.log( |
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.
same thing here?
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.
Other than that looks good
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.
its alive!
|
Fixed comments! |
What kind of change does this PR introduce?
Feature
Did you add tests for your changes?
WIP
Summary
This PR does the following
Adds
brotli
support for precaching first party modern javascript, hence reducing the total cost/ total download amount from network to the end user.Puts this behind a flag as one needs to add headers to their jS serving infra, before enabling this(see the added console.log)
Switches the underlying
sw
builder from sw-precache to workbox, for better extendable code.(next PR png -> webP)Adds the capability to copy sw.js into user land and add custom logic to it.
Fixes [next] Service Worker precaches HTML files, but they aren't used #751
We only add brotli support modern js because we can be sure without a test that browser supporting esm supports brotli.
Does this PR introduce a breaking change?
Yes, the existing preact-cli-sw-precache plugins wont work anymore.
But the users will be able to just copy our
sw.js
file into their src root and add custom logic to it.