Catch up on everthing we announced at this year's Firebase Summit. Learn more

将模块打包器与 Firebase 结合使用

JavaScript 模块打包器可以做很多事情,但它们最有用的功能之一是能够在您的代码库中添加和使用外部库。模块捆绑器读取代码中的导入路径,并将特定于应用程序的代码与导入的库代码组合(捆绑)。

从版本 9 及更高版本开始,Firebase JavaScript SDK 进行了优化,可与模块捆绑器的优化功能配合使用,以减少最终构建中包含的 Firebase 代码量。

import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged, getRedirectResult } from 'firebase/auth';

const firebaseApp = initializeApp({ /* config */ });
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => { /* check status */ });

/**
 * getRedirectResult is unused and should not be included in the code base.
 * In addition, there are many other functions within firebase/auth that are
 * not imported and therefore should not be included as well.
 */

从库中消除未使用代码的过程称为摇树。手动删除此代码将非常耗时且容易出错,但模块捆绑器可以自动删除此代码。

JavaScript 生态系统中有许多高质量的模块打包器。本指南的重点是使用火力地堡与覆盖的WebPack汇总,并esbuild

开始

本指南要求您在开发环境中安装 npm。 npm 用于安装和管理依赖项(库)。要安装NPM,安装Node.js的,其中NPM自动包括。

大多数开发人员在安装 Node.js 后就已正确设置。但是,许多开发人员在设置环境时会遇到一些常见问题。如果您遇到任何错误,请确保您的环境有故宫CLI以及是否有建立适当的权限,所以你不必安装软件包与sudo命令管理员

package.json 并安装 Firebase

一旦你已经安装了故宫,您将需要创建package.json在当地项目的根文件。使用以下 npm 命令生成此文件:

npm init

这将引导您完成一个向导以提供所需的信息。创建文件后,它将类似于以下内容:

{
  "name": "your-package-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {

  }
}

这个文件负责许多不同的事情。如果您想了解更多关于模块捆绑和构建 JavaScript 代码的一般知识,这是一个重要的文件,需要您熟悉一下。本指南的重要部分是"dependencies"对象。该对象将保存您已安装的库及其正在使用的版本的键值对。

添加依赖通过完成npm installnpm i的命令。

npm i firebase

当您运行npm i firebase ,安装过程将更新package.json到列表火力地堡作为一个依赖:

  "dependencies": {
    "firebase": "^9.0.0"
  },

键是库的名称,值是要使用的版本。版本值是灵活的,可以接受一系列值。这称为语义版本控制或 semver。要了解更多关于semver,看到故宫的关于语义版本指南

源与构建文件夹

您编写的代码由模块捆绑器读取和处理,然后作为新文件或文件集输出。将这两种类型的文件分开很重要。模块打包器读取和处理的代码称为“源”代码。它们输出的文件称为构建或“dist”(分发)代码。

在代码库的一个常见的设置是将存储源代码放在一个文件夹,名为src和命名的文件夹中内置的代码dist

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js

在上面的示例文件结构,考虑index.js进口都animations.jsdatalist.js 。当模块捆绑处理源代码就会产生bundle.js在文件dist文件夹。该bundle.js是在该文件的组合src文件夹中的进口,以及和任何库。

如果您使用的源代码控制系统,如Git的,通常忽略dist在主库中存储的代码时,文件夹。

入口点

模块打包器都有一个入口点的概念。您可以将您的应用程序视为一棵文件树。一个文件从另一个文件导入代码,依此类推。这意味着一个文件将成为树的根。此文件称为入口点。

让我们重温之前的文件结构示例。

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js
// src/index.js
import { animate } from './animations';
import { createList } from './datalist';

// This is not real code, but for example purposes only
const theList = createList('users/123/tasks');
theList.addEventListener('loaded', event => {
  animate(theList);
});

src/index.js文件被认为是切入点,因为它开始的所有需要的代码的进口申请。模块捆绑器使用此入口点文件来开始捆绑过程。

将 Firebase 与 webpack 结合使用

Firebase 应用程序和 webpack 不需要特定的配置。本节涵盖了一般的WebPack配置

第一步是从 npm 安装 webpack 作为开发依赖项。

npm i webpack webpack-cli -D

建立在当地的项目命名的根文件webpack.config.js并添加以下代码。

const path = require('path');

module.exports = {
  // The entry point file described above
  entry: './src/index.js',
  // The location of the build folder described above
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  devtool: 'eval-source-map',
};

然后确保将 Firebase 作为依赖项安装。

npm i firebase

然后在您的代码库中初始化 Firebase。以下代码在入口点文件中导入并初始化 Firebase,并使用 Firestore Lite 加载“城市”文档。

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

接下来的一步是添加一个NPM脚本来运行的WebPack版本。打开package.json文件,下面的键值对添加到"scripts"对象。

  "scripts": {
    "build": "webpack --mode=development"
  },

要运行 webpack 并生成构建文件夹,请运行以下命令。

npm run build

最后,检查dist build文件夹。它应该包含一个文件名为bundle.js包含您的应用程序捆绑和依赖代码。

有关为生产优化的WebPack版本的详细信息,请参阅其官方文档的“模式”配置设置

将 Firebase 与 Rollup 结合使用

Firebase 应用程序和 Rollup 不需要特定的配置。本节介绍一般汇总配置。

第一步是安装 Rollup 和一个插件,用于将导入映射到使用 npm 安装的依赖项。

npm i rollup @rollup/plugin-node-resolve -D

建立在当地的项目命名的根文件rollup.config.js并添加以下代码。

import { nodeResolve } from '@rollup/plugin-node-resolve';

export default {
  // the entry point file described above
  input: 'src/index.js',
  // the output for the build folder described above
  output: {
    file: 'dist/bundle.js',
    // Optional and for development only. This provides the ability to
    // map the built code back to the original source format when debugging.
    sourcemap: 'inline',
    // Configure Rollup to convert your module code to a scoped function
    // that "immediate invokes". See the Rollup documentation for more
    // information: https://rollupjs.org/guide/en/#outputformat
    format: 'iife'
  },
  // Add the plugin to map import paths to dependencies
  // installed with npm
  plugins: [nodeResolve()]
};

然后在您的代码库中初始化 Firebase。以下代码在入口点文件中导入并初始化 Firebase,并使用 Firestore Lite 加载“城市”文档。

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

接下来的一步是添加一个NPM脚本来运行程序汇总版本。打开package.json文件,下面的键值对添加到"scripts"对象。

  "scripts": {
    "build": "rollup -c rollup.config.js"
  },

要运行汇总并生成构建文件夹,请运行以下命令。

npm run build

最后,检查dist build文件夹。它应该包含一个文件名为bundle.js包含您的应用程序捆绑和依赖代码。

有关为生产优化汇总版本的详细信息,请参阅其官方文档上的插件产品构建

将 Firebase 与 esbuild 结合使用

Firebase 应用程序和 esbuild 不需要特定的配置。本节介绍一般 esbuild 配置。

第一步是安装 esbuild 作为开发依赖项。

npm i esbuild -D

建立在当地的项目命名的根文件esbuild.config.js并添加以下代码。

require('esbuild').build({
  // the entry point file described above
  entryPoints: ['src/index.js'],
  // the build folder location described above
  outfile: 'dist/bundle.js',
  bundle: true,
  // Replace with the browser versions you need to target
  target: ['chrome60', 'firefox60', 'safari11', 'edge20'],
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  sourcemap: 'inline',
}).catch(() => process.exit(1))

然后在您的代码库中初始化 Firebase。以下代码在入口点文件中导入并初始化 Firebase,并使用 Firestore Lite 加载“城市”文档。

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

const firebaseApp = initializeApp({ /* config */ });
const db = getFirestore(firebaseApp);

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

接下来的步骤是一个NPM脚本添加到运行esbuild。打开package.json文件,下面的键值对添加到"scripts"对象。

  "scripts": {
    "build": "node ./esbuild.config.js"
  },

最后,检查dist build文件夹。它应该包含一个文件名为bundle.js包含您的应用程序捆绑和依赖代码。

有关为生产优化esbuild的更多信息,请参阅其官方文档上缩小和其他优化