pcb
pcb copied to clipboard
Add 'publicPath' option to runtime 'install' method
Is it possible to update runtime_template.js
to contain a publicPath
option. So that I can register SW in runtime using custom publicPath - not the one provided by webPack, i.e.
require("offline-plugin/runtime").install({
publicPath: '/myOwnPublicPathTo/sw.js'
})
When my app is deployed to asp.net mvc app it can run from any subfolder - so asp.net provide proper base path in runtime.
I'm realized that sw.js itself contains a lot of build time path variables...
Don't give up on it so fast :-) Yes, sw.js has a lot of things generated on build time, but in general everything there could be used relatively to publicPath.
There is a relative paths option in offline-plugin, if you set it to true
then it don't use webpack's publicPath, but rather everything relative to page which requested the sw.js. Give it a try :-)
Thanks. I've hacked a bit runtime_template.js
and make it works as expected.
So yeah. I want custom path option in runtime.install
@alfeg can you show to me what exactly you changed there?
@NekR, sure. Something like:
var registration = navigator.serviceWorker
.register(
<%- JSON.stringify(ServiceWorker.location) %>
<% if (ServiceWorker.scope) { %>
, { scope: <%- JSON.stringify(ServiceWorker.scope) %> }
<% } %>
);
to
var registration = navigator.serviceWorker
.register(
options.publicPath || <%- JSON.stringify(ServiceWorker.location) %>
<% if (ServiceWorker.scope) { %>
, { scope: <%- JSON.stringify(ServiceWorker.scope) %> }
<% } %>
);
This works for me.
@alfeg okay, that makes sense. I'll need some other things from your. In generated sw.js
there is a __wpo
variable at the top. Would be good if you could provide here its content and if possible your webpack config. If you don't want it to be public, you can send it to my email (it's on github profile). This will help me understand the whole picture. Thank you!
It's a combination of problems.
We using webpack builded application inside of older Asp.Net MVC application - this cause us to use publicPath with server side includes - ~\WebPackApp\path\to\app
. Those URI's are resolved in runtime with ASP.NET engine. Essentialy our app is just a single View
. Actually this problem with webpack.publicPath reuse is my main problem with a lot of external libs. Maybe we need to find time to solve it on our side, but's it's very tricky.
Due to our deployment processes I cannot identify correct public path during build, and don't want to do anything with package during deploy.
I cannot provide code - it's already deleted. I've done with research, and find out that we are able to seamlessly integrate Service Workers caching with a very little amount of code. offline-plugin
works as expected, relative paths
hint helped a lot. Only issue is lack of ability to provide path to sw.js
in runtime.
@alfeg I see, thank you for the additional information. I think I can fix that. Thanks for reporting this issue 👍
I'm also experiencing a similar issue.
I need the sw.js
file served from /
so that it can cache my top level index.html
, but all my assets from Webpack are served under /static/
. I need a way to have the registration call that gets added by offline-plugin to my bundle to load /sw.js
, and for sw.js itself to cache my webpack assets using a /static
path.
Currently if I specify publicPath on the options for OfflinePlugin() (or as a key on it's ServiceWorker
option) the registration code will, in addition to the expected behaviour of prepending that path to my assets in the sw.js __wpo.assets.main
object, try to also use that path when registering the sw.js
file which I believe to be a bug.
I should be able to specify something like (perhaps with the publicPath properties swapped around):
new OfflinePlugin({
externals: ['/'],
publicPath: '/',
ServiceWorker: {
publicPath: '/static'
}
})
To have the registration code load the ServiceWorker from /sw.js
, which should append /static
to the assets paths in __wpo
.
Also it's very unclear in the docs how this library actually uses the publicPath
options. One would assume the top level and ServiceWorker
option would have different effects but it appears both get used as both the path to register the sw.js
from and the path to prepend to your bundle assets in sw.js
itself. I think one of the options (probably the top level one) should be removed, and a registerPath
option which is used as the path to register the ServiceWorker from added instead.
@wyqydsyq This works for me:
new OfflinePlugin({
externals: ['/'],
publicPath: '/static',
ServiceWorker: {
publicPath: '/sw.js'
},
AppCache: {
publicPath: '/appcache'
}
})
Although you'll need to generated correct structure of assets too because specified publicPath
s do not affect how assets are generated to the file system.
If you think something isn't clear, please make it clearer. All that is welcome.
@alfeg will __webpack_public_path__
work for you in your case? If you have to prefix SW/AppCache paths then I guess you have to prefix all other assets paths and the correct way to do so in webpack is by assigning to __webpack_public_path__
:
__webpack_public_path__ = '/dynamic-path/'
@wyqydsyq ping @alfeg ping
@NekR , nope It's already set to proper path.
I am also facing the similar issue, we want to make our client-side code host domain agnostic and serve from CDN, without building multiple times.
in short __webpack_public_path__ = '/dynamic-path/'
this would work if offline-plugin supports it. Anything similar which would allow to set publicPath at runtime or set it automatically as well.
Yeah, I see a point it. Would be good to add it.
@NekR I tried your example and you're right that it works, I must have had the publicPath
properties the wrong way around, which leads me to what I believe to be an actionable here; the publicPath
property under the ServiceWorker
option needs to be renamed to make a clear distinction between the behaviour of it and the top level option.
Something like this would make more sense:
new OfflinePlugin({
externals: ['/'],
publicPath: '/static',
ServiceWorker: {
installPath: '/sw.js'
}
})
Since publicPath
refers to the publicPath
used in building your assets, installPath
is the path that the ServiceWorker loader will try to install sw.js
from.
@wyqydsyq Yes, I think renaming it to registerPath
makes sense. PR is welcome if you want to do so.
Also if someone wants to help with adding "dynamic public path support" it's welcome too 👍
I want to use offline-plugin with CDN, so I am interested to take a look if I can get a working PR.
hold on... it seems that I am thinking about a different thing from previous discussion. For my use case, my sw.js still lives on my website, but my scripts generated by webpack are hosted on cdn. So I want my sw.js to cache the scripts from cdn instead during install.
actually I wasn't even sure if that's possible, because serviceWorker.register(...) doesn't allow passing any value to the service worker. https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register
after some investigation, I am thinking about storing the dynamic publicPath to IndexedDB before calling serviceWorker.register, and let service worker read from IndexedDB and override publicPath if it exists.
@NekR indexedDB's API is too complex, I want to import a small module (only 500b) 'idb-keyval' to take care of it. So it will be a dependency in generated code.
ask beforehand if you have any concerns. I think I can make a proof of concept PR soon. If the solution sounds good. I can keep polishing it up to support all cases.