Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

将模块打包器与 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的更多信息,请参阅其官方文档上缩小和其他优化