Как я могу настроить мой Service Worker на основе переменных среды? - PullRequest
0 голосов
/ 25 января 2019

Редактировать: Это похоже на дубликат этого Нерешенного вопроса . Пометить это как отвеченное или удалить?

Я использую InjectManifest из workbox-webpack-plugin внутри приложения Vue CLI 3. У работника таможенной службы, в который я вливаю, есть обработка для Firebase Cloud Messaging (FCM). Мне нужно прослушивать сообщения от разных отправителей в зависимости от среды (локальной, промежуточной и производственной).

В идеале, service-worker.js должен выглядеть так:

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
});

Однако этот код, похоже, не затрагивается веб-пакетом, поскольку работник службы вывода все еще читает process.env.VUE_APP_FCM_SENDER_ID вместо жестко закодированной клавиши.

Как я могу запустить моего сервисного работника через веб-пакет для разрешения переменных среды?

Ответы [ 2 ]

0 голосов
/ 16 июля 2019

У меня была такая же проблема, и ключом к получению процесса сборки веб-пакета было выводить используемые им env-переменные, чтобы их можно было импортировать в сервисный работник.Это избавляет вас от необходимости дублировать ваши определения env var во что-то еще, что предварительно обрабатывает ваш сервисный работник (в любом случае, это просто грязно, потому что этот файл находится под контролем исходного кода).

  1. создатьновый плагин Webpack

    // <project-root>/vue-config/DumpVueEnvVarsWebpackPlugin.js
    const path = require('path')
    const fs = require('fs')
    
    const pluginName = 'DumpVueEnvVarsWebpackPlugin'
    
    /**
     * We to configure the service-worker to cache calls to both the API and the
     * static content server but these are configurable URLs. We already use the env var
     * system that vue-cli offers so implementing something outside the build
     * process that parses the service-worker file would be messy. This lets us
     * dump the env vars as configured for the rest of the app and import them into
     * the service-worker script to use them.
     *
     * We need to do this as the service-worker script is NOT processed by webpack
     * so we can't put any placeholders in it directly.
     */
    
    module.exports = class DumpVueEnvVarsWebpackPlugin {
      constructor(opts) {
        this.filename = opts.filename || 'env-vars-dump.js'
      }
    
      apply(compiler) {
        const fileContent = Object.keys(process.env)
          .filter(k => k.startsWith('VUE_APP_'))
          .reduce((accum, currKey) => {
            const val = process.env[currKey]
            accum += `const ${currKey} = '${val}'\n`
            return accum
          }, '')
        const outputDir = compiler.options.output.path
        if (!fs.existsSync(outputDir)) {
          // TODO ideally we'd let Webpack create it for us, but not sure how to
          // make this run later in the lifecycle
          fs.mkdirSync(outputDir)
        }
        const fullOutputPath = path.join(outputDir, this.filename)
        console.debug(
          `[DumpVueEnvVarsWebpackPlugin] dumping env vars to file=${fullOutputPath}`,
        )
        fs.writeFileSync(fullOutputPath, fileContent)
      }
    }
    
  2. используйте плагин в вашей конфигурации vue-cli (vue.config.js или vue-config/config.default.js, если ваша конфигурация разделена на несколько файлов)

    // import out plugin (change the path to where you saved the plugin script)
    const DumpVueEnvVarsWebpackPlugin = require('./DumpVueEnvVarsWebpackPlugin.js')
    
    module.exports = {
      // other stuff...
      configureWebpack: {
        plugins: [
          // We add our plugin here
          new DumpVueEnvVarsWebpackPlugin({ filename: 'my-env-vars.js' })
        ],
      },
    }
    
  3. в нашем скрипте работника сервиса, теперь мы можем импортировать файл, который мы написали с помощью нашего плагина Webpack (он будет там после сборки, а работники сервиса не будут работать в режиме devпоэтому мы должны быть в безопасности)

    importScripts('./my-env-vars.js') // written by DumpVueEnvVarsWebpackPlugin
    const fcmSenderId = VUE_APP_FCM_SENDER_ID // comes from script imported above
    console.debug(`Using sender ID = ${fcmSenderId}`)
    
    // use the variable
    firebase.initializeApp({
        'messagingSenderId': fcmSenderId
    })
    

Это не идеально, но оно, безусловно, выполняет свою работу.Это СУХОЙ, поскольку вам нужно только определить все ваши env-переменные в одном месте, и все приложение использует одни и те же значения.Кроме того, он не обрабатывает файлы, находящиеся в системе контроля версий.Мне не нравится, что плагин запускается слишком рано в жизненном цикле Webpack, поэтому нам нужно создать dist dir, но, надеюсь, у кого-нибудь умнее меня будет исправление.

0 голосов
/ 15 марта 2019

Вероятно, для вас уже слишком поздно, но для других я продолжал обходить это. Этот процесс все еще использует файл .env для переменных, связанных с вашей средой.
Идея состоит в том, чтобы создать новый скрипт, который загружает файл .env, который создает новый файл, заполненный переменными из файла .env.
После процесса сборки мы просто импортируем новый сгенерированный файл в sw.js для его использования.

Вот шаги.
Сначала создайте файл с именем swEnvbuild.js, который будет вашим сценарием, который запускается после 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
  }
}
`);

Во-вторых, мы импортируем файл, сгенерированный из swEnvBuild.js с именем swenv.js, в наш sw.js.

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

И, наконец, для того, чтобы это работало с одной командой, просто добавьте следующее в свои скрипты npm (при условии, что вы используете Linux / Mac).

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

Надеюсь, это должно сработать. Хотелось бы, чтобы был более чистый способ сделать это, поэтому я был бы рад узнать, как другие решения тоже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...