webpackenvironment-variablesservice-workervue-cli-3workbox-webpack-plugin

How can I customize my Service Worker based on environment variables?


Edit: This looks like a duplicate of this Unresolved Question. Do I mark this as answered, or delete?

I am using InjectManifest from workbox-webpack-plugin inside a Vue CLI 3 app. The custom service worker that I am injecting into has handling for Firebase Cloud Messaging (FCM). I need to listen for messages from different senders based on my environment (local, staging, and production).

Ideally, service-worker.js would look like this:

importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js');

firebase.initializeApp({
    'messagingSenderId': process.env.VUE_APP_FCM_SENDER_ID
});

However, this code doesn't seem to be touched by webpack, as the output service worker still reads process.env.VUE_APP_FCM_SENDER_ID instead of the hardcoded key.

How can I run my service worker through webpack in order to resolve environment variables?


Solution

  • It's probably way too late for you now but for others this is how I went on about getting around this. This process still utilizes .env file for your environment related variables.
    The idea is to create a new script that loads the .env file which creates a new file populated with the variables from .env file.
    After the build process we simply import the newly generated file in sw.js for it to be used.

    Here are the steps.
    First create a file called swEnvbuild.js which will be your script that runs after webpack

    //swEnvBuild.js - script that is separate from webpack
    require('dotenv').config(); // make sure you have '.env' file in pwd
    const fs = require('fs');
    
    fs.writeFileSync('./dist/public/swenv.js',
    `
    const process = {
      env: {
        VUE_APP_FCM_SENDER_ID: conf.VUE_APP_FCM_SENDER_ID
      }
    }
    `);
    

    Secondly, we import the file that was generated from swEnvBuild.js called swenv.js in our sw.js.

    // sw.js
    importScripts('swenv.js'); // this file should have all the vars declared
    console.log(process.env.VUE_APP_FCM_SENDER_ID);
    

    And lastly, for this to work with one command just add the following in your npm scripts (assuming that you're running either Linux/Mac).

    scripts: {
      "start": "webpack && node swEnvBuild.js"
    }
    

    Hopefully, that should do the trick. I wish there was much cleaner way to do this so I'd be happy to know how other's solution too.