如何根据环境变量自定义Service Worker?

问题描述 投票:3回答:1

编辑:这看起来像这个Unresolved Question的副本。我将此标记为已回答或删除吗?

我在Vue CLI 3应用程序中使用来自workbox-webpack-plugin的InjectManifest。我注入的自定义服务工作者负责处理Firebase云消息传递(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
});

但是,webpack似乎没有触及此代码,因为输出服务工作者仍然读取process.env.VUE_APP_FCM_SENDER_ID而不是硬编码密钥。

如何通过webpack运行我的服务工作者以解决环境变量?

webpack service-worker vue-cli-3 workbox-webpack-plugin
1个回答
3
投票

现在对你来说可能为时已晚,但对于其他人来说,这就是我如何解决这个问题。此过程仍然使用.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"
}

希望,这应该成功。我希望有更清洁的方法来做到这一点,所以我很高兴知道其他人的解决方案。


0
投票

我遇到了同样的问题,关键是让webpack构建过程输出它使用的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.jsvue-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 })

它并不完美,但它肯定能完成任务。它是D-R-Y,因为您只需在一个位置定义所有环境变量,整个应用程序使用相同的值。另外,它不处理源代码管理中的任何文件。我不喜欢插件在Webpack生命周期中运行得太早,所以我们必须创建dist目录,但希望比我聪明的其他人能够解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.