Check out what’s new from Firebase at Google I/O 2022. Learn more

Como usar empacotadores de módulos com o Firebase

Os bundlers de módulo JavaScript podem fazer muitas coisas, mas um de seus recursos mais úteis é a capacidade de adicionar e usar bibliotecas externas em sua base de código. Os bundlers de módulo leem os caminhos de importação em seu código e combinam (agrupam) seu código específico do aplicativo com o código da biblioteca importada.

A partir da versão 9 e superior, o SDK do Firebase JavaScript é otimizado para funcionar com os recursos de otimização dos bundlers de módulo para reduzir a quantidade de código do Firebase incluído na compilação final.

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.
 */

Esse processo de eliminação de código não utilizado de uma biblioteca é conhecido como trepidação de árvore. Seria extremamente demorado e propenso a erros remover manualmente esse código, mas os empacotadores de módulos podem automatizar essa remoção.

Existem muitos empacotadores de módulos de alta qualidade no ecossistema JavaScript. Este guia se concentra em abordar o uso do Firebase com webpack , Rollup e esbuild .

iniciar

Este guia requer que você tenha o npm instalado em seu ambiente de desenvolvimento. npm é usado para instalar e gerenciar dependências (bibliotecas). Para instalar o npm, instale o Node.js , que inclui o npm automaticamente.

A maioria dos desenvolvedores está configurada corretamente depois de instalar o Node.js. No entanto, existem problemas comuns que muitos desenvolvedores enfrentam ao configurar seu ambiente. Se você encontrar algum erro, certifique-se de que seu ambiente tenha a CLI do npm e que você tenha as permissões adequadas configuradas para não precisar instalar pacotes como administrador com o comando sudo .

package.json e instalação do Firebase

Depois de instalar o npm, você precisará criar um arquivo package.json na raiz do seu projeto local. Gere este arquivo com o seguinte comando npm:

npm init

Isso o levará através de um assistente para fornecer as informações necessárias. Depois que o arquivo for criado, ele será semelhante ao seguinte:

{
  "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": {

  }
}

Este arquivo é responsável por muitas coisas diferentes. Este é um arquivo importante para se familiarizar se você quiser aprender mais sobre agrupamento de módulos e construção de código JavaScript em geral. A peça importante para este guia é o objeto "dependencies" . Este objeto conterá um par chave-valor da biblioteca que você instalou e a versão que está usando.

A adição de dependências é feita através do npm install ou npm i .

npm i firebase

Ao executar npm i firebase , o processo de instalação atualizará o package.json para listar o Firebase como uma dependência:

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

A chave é o nome da biblioteca e o valor é a versão a ser usada. O valor da versão é flexível e pode aceitar um intervalo de valores. Isso é conhecido como versionamento semântico ou semver. Para saber mais sobre semver, consulte o guia do npm sobre versionamento semântico .

Pastas de origem vs compilação

O código que você escreve é ​​lido e processado por um empacotador de módulos e, em seguida, é gerado como um novo arquivo ou conjunto de arquivos. É importante separar esses dois tipos de arquivos. O código que os empacotadores do módulo lêem e processam é conhecido como código "fonte". Os arquivos que eles produzem são conhecidos como código construído ou "dist" (distribuição).

Uma configuração comum em bases de código é armazenar o código fonte em uma pasta chamada src e o código construído em uma pasta chamada dist .

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


- dist
 |_ bundle.js

Na estrutura de arquivo de exemplo acima, considere que index.js importa animations.js e datalist.js . Quando um empacotador de módulo processa o código-fonte, ele produz o arquivo bundle.js na pasta dist . O bundle.js é uma combinação dos arquivos na pasta src e também de quaisquer bibliotecas importadas.

Se você estiver usando sistemas de controle de origem como o Git, é comum ignorar a pasta dist ao armazenar esse código no repositório principal.

Pontos de entrada

Todos os empacotadores de módulos têm um conceito de ponto de entrada. Você pode pensar em seu aplicativo como uma árvore de arquivos. Um arquivo importa código de outro e assim por diante. Isso significa que um arquivo será a raiz da árvore. Este arquivo é conhecido como ponto de entrada.

Vamos revisitar o exemplo anterior de estrutura de arquivos.

- 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);
});

O arquivo src/index.js é considerado o ponto de entrada, pois inicia a importação de todo o código necessário para a aplicação. Este arquivo de ponto de entrada é usado por empacotadores de módulos para iniciar o processo de empacotamento.

Como usar o Firebase com webpack

Não há configuração específica necessária para aplicativos do Firebase e webpack. Esta seção abrange uma configuração geral do webpack .

O primeiro passo é instalar o webpack do npm como uma dependência de desenvolvimento.

npm i webpack webpack-cli -D

Crie um arquivo na raiz do seu projeto local chamado webpack.config.js e adicione o código a seguir.

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',
};

Em seguida, verifique se o Firebase está instalado como uma dependência.

npm i firebase

Em seguida, inicialize o Firebase em sua base de código. O código a seguir importa e inicializa o Firebase em um arquivo de ponto de entrada e usa o Firestore Lite para carregar um documento "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(),
  };
}

A próxima etapa é adicionar um script npm para executar a compilação do webpack. Abra o arquivo package.json e adicione o seguinte par de valores-chave ao objeto "scripts" .

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

Para executar o webpack e gerar a pasta de compilação, execute o seguinte comando.

npm run build

Por fim, verifique a pasta dist build. Ele deve conter um arquivo chamado bundle.js que contém seu aplicativo empacotado e o código de dependência.

Para obter mais informações sobre como otimizar sua compilação de webpack para produção, consulte a documentação oficial na configuração de "modo" .

Como usar o Firebase com rollup

Não há configuração específica necessária para aplicativos do Firebase e Rollup. Esta seção abrange uma configuração geral de Rollup.

O primeiro passo é instalar o Rollup e um plugin usado para mapear importações para dependências instaladas com npm.

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

Crie um arquivo na raiz do seu projeto local chamado rollup.config.js e adicione o código a seguir.

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

Em seguida, inicialize o Firebase em sua base de código. O código a seguir importa e inicializa o Firebase em um arquivo de ponto de entrada e usa o Firestore Lite para carregar um documento "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(),
  };
}

A próxima etapa é adicionar um script npm para executar a compilação de rollup. Abra o arquivo package.json e adicione o seguinte par de valores-chave ao objeto "scripts" .

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

Para executar o rollup e gerar a pasta de compilação, execute o comando a seguir.

npm run build

Por fim, verifique a pasta dist build. Ele deve conter um arquivo chamado bundle.js que contém seu aplicativo empacotado e o código de dependência.

Para obter mais informações sobre como otimizar sua compilação Rollup para produção, consulte a documentação oficial sobre plug-ins para compilações de produção .

Como usar o Firebase com esbuild

Não há configuração específica necessária para aplicativos do Firebase e esbuild. Esta seção abrange uma configuração geral de esbuild.

O primeiro passo é instalar o esbuild como uma dependência de desenvolvimento.

npm i esbuild -D

Crie um arquivo na raiz do seu projeto local chamado esbuild.config.js e adicione o código a seguir.

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))

Em seguida, inicialize o Firebase em sua base de código. O código a seguir importa e inicializa o Firebase em um arquivo de ponto de entrada e usa o Firestore Lite para carregar um documento "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(),
  };
}

A próxima etapa é adicionar um script npm para executar esbuild. Abra o arquivo package.json e adicione o seguinte par de valores-chave ao objeto "scripts" .

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

Por fim, verifique a pasta dist build. Ele deve conter um arquivo chamado bundle.js que contém seu aplicativo empacotado e o código de dependência.

Para obter mais informações sobre como otimizar o esbuild para produção, consulte a documentação oficial sobre minificação e outras otimizações .