如何使用 vue-cli 外部化一个库

How to externalize a lib with vue-cli

在我的 vue-cli 项目 (@vue/cli 4.4.4) 中,我想在构建时排除 firebase 并在运行时包含它(通过 index.html)。

在我的 package.json 我有那些导入

{
 ...
 "dependencies": {
   ...
    "firebase": "^7.24.0",
    "firebaseui": "^4.7.1"
  },
}

我想从构建中排除。 Google/SO 的研究让我在 vue.config.js:

中包含了这些行
module.exports = {
 ...
  configureWebpack: {
    externals: {
      firebaseui: "firebaseui",
      firebase: "firebase",
    },
  }
};

还有 webpack.config.js:

module.exports = {
  externals: {
    firebase: "firebase",
    firebaseui: "firebaseui",
  },
};

但是,这不起作用。 Firebase 仍包含在 dist/js 文件夹中生成的 js 文件中。

我如何使用 webpack 的 vue-cli 排除功能来仅将我自己的代码与一些小的 deps 捆绑在一起?

我也偶然发现了这个问题。 Firebase Web SDK 捆绑后非常大。

我做了什么:

通过他们的 CDN 导入 Firebase Web SDK 并将其放置在 public/index.html:

<!-- public/index.html -->
<head>
  ...

  <title>...</title>

  <!-- Firebase App, then all other used services in your app -->
  <script src="https://www.gstatic.com/firebasejs/8.3.1/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/8.3.1/firebase-auth.js"></script>
  <script src="https://www.gstatic.com/firebasejs/8.3.1/firebase-firestore.js"></script>

  <!-- Firebase UI -->
  <script src="https://www.gstatic.com/firebasejs/ui/4.8.0/firebase-ui-auth.js"></script>
</head>

创建一个 src/firebase.js 作为单一入口点来初始化我的 firebase。

// src/firebase.js
import "firebase/app";

const firebaseConfig = {
    ...
};

firebase.initializeApp(firebaseConfig);

export default firebase;

然后在我的 src/main.js 文件中导入它,然后安装应用程序。

// src/main.js
import "@/firebase.js"; // @ is shorthand to /src

import { createApp } from "vue";
...

使用 Webpack Externals 将 CDN 公开的全局 firebase 映射到 "firebase/app" 的任何导入。我们不需要在 vue 文件中导入其他服务(即 auth、firestore),因为它将由 CDN 提供。

// vue.config.js
module.exports = {
  ...
  chainWebpack: (config) => {
    config.externals({
      "firebase/app": "firebase",
      firebaseui: "firebaseui",
    });
  },
  ...
};

请注意,我没有包含上面导入的默认导出的名称。通过将它也命名为 firebase(让智能感知工作)来这样做会在浏览器中抛出一个警告:Firebase is already defined in the global scope。您可以:

  • 为导入使用不同的名称,例如:import fb from "firebase/app"。这将使智能感知在使用 fb.<restOfObject>

    时起作用
  • 或者,如果您只是要部署应用程序并且不需要智能感知,则不要包含名称。

无论哪种方式,所有 firebase.<restOfObject> 函数都将在您的代码上运行,因为 Webpack Externals 会将 CDN 公开的 firebase 全局名称映射到您使用 firebase/app.

即使不导入,所有其他组件现在也可以访问全局 firebase 对象。

// Sample of a .vue file
<script>
const auth = firebase.auth(); // this still works

const ui = new firebaseui.auth.AuthUI(auth); // this too

export default {
  data() {
      ...
  }
};
</script>

Vue 构建大小

参考资料

我这里可能有错误。对此答案的任何改进表示赞赏。这是我的第一个回答,希望能帮到你。