如何将使用Firebase的项目拆分多文件适配Webpack打包
问题:Webpack拆分Firebase模块后无法跨文件访问的解决方法
我决定将项目转为使用Webpack,因原项目已十分混乱。我尝试为应用的会员、计划、认证等模块拆分独立JS文件,这些模块均需用到Firebase的Functions、数据库、认证等功能,但似乎所有代码必须放在index.js才能正常运行,且总会出现Firebase无法从index.js访问的各类奇怪错误。请问该如何构建项目结构,才能在多个文件中使用Firebase并最终通过Webpack打包为单个文件?
现有代码
index.js
import $ from 'jquery'; import mixpanel from 'mixpanel-browser'; import { initializeApp } from "firebase/app"; import { getAnalytics } from "firebase/analytics"; import { getFirestore, collection, query, where, getDocs } from "firebase/firestore"; import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword, onAuthStateChanged } from "firebase/auth"; const firebaseConfig = { ... }; // Initialize Firebase const app = initializeApp(firebaseConfig); const db = getFirestore(app); const analytics = getAnalytics(); const auth = getAuth(); // Javascript import './js/auth.js'; import './js/members.js'; // Styles import './scss/fonts.scss'; import './scss/auth.scss'; import './scss/main.scss'; import './scss/navbar.scss'; import './scss/buttons.scss'; import './scss/inputs.scss'; ...
members.js
import { getFunctions, httpsCallable } from "firebase/functions"; const functions = getFunctions(); const listMembers = httpsCallable(functions, 'listMembers'); listMembers() .then((result) => { const data = result.data; const sanitizedMessage = data.text; console.log(sanitizedMessage); }) .catch((error) => { const code = error.code; const message = error.message; const details = error.details; });
解决方案
问题出在你没有在子模块中复用已初始化的Firebase实例,而是尝试重新创建,导致Firebase无法关联到正确的应用上下文。正确的做法是将Firebase的初始化逻辑抽离为独立模块,导出已初始化的实例,供其他模块导入使用。
1. 创建独立的Firebase初始化模块
在项目根目录(或js文件夹下)新建firebase.js,集中处理Firebase的配置与初始化:
import { initializeApp } from "firebase/app"; import { getAnalytics } from "firebase/analytics"; import { getFirestore } from "firebase/firestore"; import { getAuth } from "firebase/auth"; import { getFunctions } from "firebase/functions"; const firebaseConfig = { // 你的Firebase配置 }; // 初始化Firebase App const app = initializeApp(firebaseConfig); // 导出各个服务实例 export const db = getFirestore(app); export const auth = getAuth(app); export const functions = getFunctions(app); export const analytics = getAnalytics(app);
2. 修改index.js,导入Firebase实例
移除index.js中的Firebase初始化代码,改为导入上述模块的实例:
import $ from 'jquery'; import mixpanel from 'mixpanel-browser'; // 导入Firebase实例 import { db, auth, analytics } from './firebase.js'; // Javascript import './js/auth.js'; import './js/members.js'; // Styles import './scss/fonts.scss'; import './scss/auth.scss'; import './scss/main.scss'; import './scss/navbar.scss'; import './scss/buttons.scss'; import './scss/inputs.scss'; ...
3. 修改子模块(如members.js),导入共享的Firebase实例
不再在子模块中重新获取Functions,而是导入firebase.js中已初始化的实例:
import { httpsCallable } from "firebase/functions"; import { functions } from '../firebase.js'; // 根据文件路径调整 const listMembers = httpsCallable(functions, 'listMembers'); listMembers() .then((result) => { const data = result.data; const sanitizedMessage = data.text; console.log(sanitizedMessage); }) .catch((error) => { const code = error.code; const message = error.message; const details = error.details; });
关键说明
- 所有Firebase服务(Auth、Firestore、Functions等)都必须基于同一个已初始化的
app实例创建,否则会出现上下文不匹配的错误。 - 通过集中管理Firebase实例,你可以在任意子模块中导入使用,同时保证Webpack打包时只会初始化一次Firebase,避免重复初始化的问题。
内容的提问来源于stack exchange,提问作者aszet
相关产品推荐
相关产品推荐

