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 生态系统中有许多高质量的模块打包器。本指南重点介绍如何将 Firebase 与webpack 、 Rollup和esbuild 结合使用。
开始使用
本指南要求您在开发环境中安装 npm。 npm 用于安装和管理依赖项(库)。要安装 npm,请安装自动包含 npm 的 Node.js。
大多数开发人员在安装 Node.js 后就已正确设置。但是,许多开发人员在设置环境时会遇到一些常见问题。如果您遇到任何错误,请确保您的环境具有 npm CLI并且您已设置适当的权限,因此您不必以管理员身份使用 sudo 命令安装软件包。
package.json 和安装 Firebase
安装 npm 后,您需要在本地项目的根目录下创建一个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 install
或npm i
命令完成的。
npm i firebase
当您运行npm i firebase
时,安装过程将更新package.json
以将 Firebase 列为依赖项:
"dependencies": {
"firebase": "^9.0.0"
},
键是库的名称,值是要使用的版本。版本值是灵活的,可以接受一系列值。这称为语义版本控制或 semver。要了解有关 semver 的更多信息,请参阅 npm 的语义版本控制指南。
源与构建文件夹
您编写的代码由模块捆绑器读取和处理,然后作为新文件或文件集输出。将这两种类型的文件分开很重要。模块捆绑器读取和处理的代码称为“源”代码。它们输出的文件称为构建或“dist”(分发)代码。
代码库中的一个常见设置是将源代码存储在名为src
的文件夹中,并将构建的代码存储在名为dist
的文件夹中。
- src
|_ index.js
|_ animations.js
|_ datalist.js
- dist
|_ bundle.js
在上面的示例文件结构中,考虑index.js
导入了animations.js
和datalist.js
。当模块捆绑器处理源代码时,它将在dist
文件夹中生成bundle.js
文件。 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
构建文件夹。它应该包含一个名为bundle.js
的文件,其中包含您的捆绑应用程序和依赖项代码。
有关为生产优化 webpack 构建的更多信息,请参阅他们关于“模式”配置设置的官方文档。
将 Firebase 与汇总一起使用
Firebase 应用和汇总不需要特定配置。本节介绍一般的汇总配置。
第一步是安装 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
构建文件夹。它应该包含一个名为bundle.js
的文件,其中包含您的捆绑应用程序和依赖项代码。
有关为生产优化 Rollup 构建的更多信息,请参阅他们关于生产构建插件的官方文档。
将 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
构建文件夹。它应该包含一个名为bundle.js
的文件,其中包含您的捆绑应用程序和依赖项代码。
有关为生产优化 esbuild 的更多信息,请参阅他们关于缩小和其他优化的官方文档。