vuejs / vue-cli

🛠️ webpack-based tooling for Vue.js Development
https://cli.vuejs.org/
MIT License
29.76k stars 6.33k forks source link

[Vue PWA] Feature - Inject environment variables in service-worker.js #5047

Open esynaps opened 4 years ago

esynaps commented 4 years ago

What problem does this feature solve?

We need to inject environment variables in service-worker.js

process.env.VUE_APP_MY_VAR should be replaced by the DefinePlugin of webpack (automatically configured by Vue CLI) by a value defined in my .env but it works for all files except the "service-worker.js"

My vue.config.js

module.exports = {
  transpileDependencies: [],
  configureWebpack: {
    resolve: {
      symlinks: false
    }
  },
  pwa: {
    workboxPluginMode: 'InjectManifest',
    workboxOptions: {
      swSrc: 'public/service-worker.js'
    }
  }
}

What does the proposed API look like?

I found two obscure solutions for this problem :

The first one : https://stackoverflow.com/a/57051150/4864628

The second (better): https://github.com/diachedelic/vue-cli-plugin-bundle-service-worker

This last solution uses webpack to bundle the service-worker.js file. In my opinion this should be the default behavior of Vue PWA.

rodrigogs commented 4 years ago

So... no way?

esynaps commented 4 years ago

While waiting for the managers to take care of it, I recommend this link which served as an alternative

https://stackoverflow.com/a/57051150/4864628

Phoen1x84 commented 4 years ago

This would be a great feature. I'm having the same issue and need to change the service worker to cache different API requests depending on deployed environment e.g. QA, UAT and Prod.

Tobiaqs commented 8 months ago

You can encapsulate variables into a query string appended to the service worker script path.

navigator.serviceWorker.register(
    import.meta.env.VITE_SW_PATH + (import.meta.env.VITE_SW_PATH.includes('?') ? '&' : '?') + 'vapid_public_key=' + import.meta.env.VITE_VAPID_PUBLIC_KEY
)

In service worker:

variables = Object.fromEntries(self.serviceWorker.scriptURL.split('?')[1].split('&').map((value, idx) => idx === 1 ? decodeURIComponent(value) : value))

Use .env.development during development & .env.production or actual environment variables to influence what happens at build time.