Firebase와 함께 모듈 번들러 사용

자바스크립트 모듈 번들러에는 다양한 기능이 있지만, 가장 유용한 기능 중 하나는 외부 라이브러리를 추가하여 코드베이스에서 사용하는 것입니다. 모듈 번들러는 코드에서 가져오기 경로를 읽고 애플리케이션별 코드와 가져온 라이브러리 코드를 결합(번들)합니다.

Firebase 자바스크립트 모듈식 API 버전 9 이상에서는 모듈 번들러의 최적화 기능과 연동하여 최종 빌드에 포함되는 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.
 */

라이브러리에서 미사용 코드를 제거하는 이 프로세스를 트리 쉐이킹이라고 합니다. 수동으로 이 코드를 직접 삭제하려면 시간이 오래 걸리고 실수가 나오기 쉽지만, 모듈 번들러는 이러한 삭제를 자동화할 수 있습니다.

자바스크립트 생태계에는 다양한 고품질의 모듈 번들러가 있습니다. 이 가이드에서는 webpack, Rollup, esbuild와 함께 Firebase를 사용하는 방법을 중점적으로 설명합니다.

시작하기

이 가이드를 사용하려면 개발 환경에 npm이 설치되어 있어야 합니다. npm은 종속 항목(라이브러리)을 설치하고 관리하는 데 사용됩니다. Node.js를 설치하면 npm이 자동으로 포함됩니다.

대부분의 개발자는 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": {

  }
}

이 파일은 다양한 역할을 합니다. 모듈 번들링 및 일반적인 자바스크립트 코드 작성에 대해 자세히 알고 싶다면 이 파일에 익숙해지는 것이 중요합니다. 이 가이드와 관련하여 중요한 부분은 "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.jsanimations.jsdatalist.js를 가져온다고 가정해 보겠습니다. 모듈 번들러는 소스 코드를 처리하고 dist 폴더에 bundle.js 파일을 생성합니다. bundle.jssrc 폴더의 파일과 가져오기한 모든 라이브러리를 결합한 결과물입니다.

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 파일은 애플리케이션에 필요한 모든 코드의 가져오기를 시작하므로 진입점으로 간주됩니다. 이 진입점 파일은 모듈 번들러에서 번들링 프로세스를 시작하는 데 사용됩니다.

webpack과 함께 Firebase 사용

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를 사용하여 'city' 문서를 로드합니다.

// 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(),
  };
}

다음 단계는 webpack 빌드를 실행하는 npm 스크립트를 추가하는 것입니다. package.json 파일을 열고 "scripts" 객체에 다음 키-값 쌍을 추가합니다.

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

webpack을 실행하고 빌드 폴더를 생성하려면 다음 명령어를 실행합니다.

npm run build

마지막으로 dist 빌드 폴더를 확인합니다. 여기에는 번들 애플리케이션 및 종속 항목 코드가 포함된 bundle.js라는 파일이 포함되어야 합니다.

webpack 빌드를 프로덕션용으로 최적화하는 방법에 대한 자세한 내용은 'mode' 구성 설정에 대한 공식 문서를 참조하세요.

Rollup과 함께 Firebase 사용

Firebase 앱과 Rollup에는 특별한 구성이 필요하지 않습니다. 이 섹션에서는 일반적인 Rollup 구성을 설명합니다.

첫 번째 단계는 npm으로 설치한 종속 항목에 대한 가져오기를 매핑하는 데 사용되는 플러그인과 Rollup을 설치하는 것입니다.

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를 사용하여 'city' 문서를 로드합니다.

// 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"
  },

Rollup을 실행하고 빌드 폴더를 생성하려면 다음 명령어를 실행합니다.

npm run build

마지막으로 dist 빌드 폴더를 확인합니다. 여기에는 번들 애플리케이션 및 종속 항목 코드가 포함된 bundle.js라는 파일이 포함되어야 합니다.

Rollup 빌드를 프로덕션용으로 최적화하는 방법에 대한 자세한 내용은 프로덕션 빌드용 플러그인에 대한 공식 문서를 참조하세요.

esbuild와 함께 Firebase 사용

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를 사용하여 'city' 문서를 로드합니다.

// 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(),
  };
}

다음 단계는 esbuild를 실행하는 npm 스크립트를 추가하는 것입니다. package.json 파일을 열고 "scripts" 객체에 다음 키-값 쌍을 추가합니다.

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

마지막으로 dist 빌드 폴더를 확인합니다. 여기에는 번들 애플리케이션 및 종속 항목 코드가 포함된 bundle.js라는 파일이 포함되어야 합니다.

esbuild를 프로덕션용으로 최적화하는 방법에 대한 자세한 내용은 압축 및 기타 최적화에 대한 공식 문서를 참조하세요.