如何在 public 文件夹中使用静态 JS 的环境变量

How to use environment variables with static JS in public folder

我有 VueJS 应用程序 (Vue CLI 3) 和其他 static JS 脚本public 文件夹中。而且我不明白如何在 .js.

中使用 .env

假设我有一些特定的环境变量,例如 MY_URL 和我的 JS 文件:

const myUrl = process.env.VUE_APP_MY_URL;

它不起作用,因为据我所知,来自 public 文件夹的静态文件不会被 webpack 处理。

也许有人知道好的解决方案?或者其他 solutions\workarounds?

在我的例子中,我将 .js 放到 src 并通过 chainWebpack:

添加新的 entry
config.entryPoints.delete('app')

config.entry('app')
    .add('./src/main.ts')
    .end()
    .entry('myScript')
    .add('./src/myScript.js')
    .end()

现在 webpack 将脚本构建为单独的文件,但使用 app.js 注入 index.html。这不是我真正想要的。

所以,主要目的 - 构建单独的静态 JS 文件,具有特定名称,没有散列(例如,myScript.js),其中包含来自 .env 的变量(.env.production.env.development)

docspublic 文件夹中静态文件的主要信息:

Static assets placed in the public directory will simply be copied and not go through webpack

因此,我无法将 .envpublic 中的静态文件一起使用。

我还没有找到完美的解决方案,但至少有 3 个可以接受的选项:


  1. JS文件作为入口,作为Jesse Reza Khorasanee said in comments and gave a link几乎相同的问题

主要思想: 配置 vue.config.js 额外的条目并强制 webpack 处理我的文件。

// vue.config.js

module.exports = {
  configureWebpack: {
    entry: {
      public: "./public/main.js"
    },
    output: {
      filename: "[name]/[name].main.js"
    }
  }
};

此解决方案适用于某些功能:

  • 至少 两个入口点我的 SPA 的主要入口 (main.js) 和 额外条目 仅用于我的静态 JS。 这不好,因为处理后的 JS 将包含 link 到 vendors.js 块作为条目之一。但是我只需要webpack处理过的JS文件。

  • 文件名中的 output.filenamehashclear config 相同(这是行不通的,因为我将此脚本用作第 3 方JS 并通过静态名称加载),或者我的 JS 文件不同 output.filename 但具有 脏配置 :

configureWebpack: config => {
        config.output.filename = (pathData) => {
            return pathData.chunk.name === 'myScript'
                ? '[name].js' : '[name].[hash].js';
        };
    ...
}
  • 如果我将我的 JS 留在 public 文件夹中,我会在构建后得到两个文件:一个在默认 js 文件夹中,其中包含其他静态资产,另一个在 main.js[= 附近的根文件夹中119=]

  1. Multi-Page Application (configuration for Vue multi-page mode)
module.exports = {
  pages: {
    index: {
      // entry for the page
      entry: 'src/index/main.js',
      chunks: ['chunk-vendors', 'chunk-common', 'index']
    },
    // when using the entry-only string format,
    // template is inferred to be `public/myScript.html`
    // and falls back to `public/index.html` if not found.
    // Output filename is inferred to be `myScript.html`.
    myScript: 'src/myScript.js'
  }
}

这个解决方案几乎可以像第一个解决方案一样工作,而且我得到了一个清晰的配置文件。但我仍然对 vendors.js 有问题,似乎 pages 选项直接与 html-webpack-plugin 一起工作,我可以配置 chunks,它将加载我的 page,我试过了设置此选项的不同方法但没有成功。供应商仍然是 myScript 条目的一部分。


  1. 将 JS 文件构建为 library

我在我的案例中选择了这个解决方案。因为它清晰而简短。

我在 package.json 中添加了额外的脚本:vue-cli-service build --no-clean --target lib --name paysendPaymentLibrary src/payment.js 并更改了主 build 脚本。

package.json 的最终版本:

...
"scripts": {
    "build": "vue-cli-service build && npm run build-library",
    "build-library": "vue-cli-service build --no-clean --target lib --name myScriptLibrary src/myScript.js"
  },
...

在 运行 npm run build 之后,我得到了 SPA 的静态文件和我的脚本的三个文件:

  • myScriptLibrary.umd.min.js
  • myScriptLibrary.umd.js
  • myScriptLibrary.common.js

对于第 3 方站点,我使用 myScriptLibrary.umd.js 文件。

如果您选择此解决方案请在构建应用程序时小心,因为:

  • Windowsvue-cli-service build & npm run build-library中脚本会运行顺序,但在Unix它运行s 并行。它可能会导致您的 SPA 文件被删除。所以一定要使用 && 而不是 &(参见 关于环境和 parallel\sequential 脚本 运行ning)
  • 已处理文件的大小 比原始 静态 JS 文件大。例如,在我的例子中,原始文件大小:4 KiB,构建后:15.44 KiB,gzipped:5.78 KiB.