Skip to main content

CommonJS | ESModule | TSConfig

  • CommonJS | ESModule | TSConfig

O que são CommonJS e ESModule?

1. CommonJS (CJS)

  • Origem: Introduzido no Node.js.
  • Sintaxe: Usa require para importar e module.exports ou exports para exportar.
  • Padrão de Módulos: Tradicional no Node.js.
  • Suporte: Amplamente suportado, mesmo em ambientes antigos.

Exemplo:

// CommonJS
const fs = require('fs'); // Importação
module.exports = function greet() { // Exportação
console.log('Hello, CommonJS!');
};

2. ESModule (ESM)

  • Origem: Padrão nativo do JavaScript, introduzido no ES6 (2015).
  • Sintaxe: Usa import para importar e export para exportar.
  • Suporte: Nativamente suportado em navegadores modernos e no Node.js (com "type": "module" no package.json).
  • Vantagem: Melhor suporte para otimizações de ferramentas de empacotamento e browsers.

Exemplo:

// ESModule
import fs from 'fs'; // Importação
export default function greet() { // Exportação
console.log('Hello, ESModule!');
}

Diferenças Principais

AspectoCommonJSESModule
Importaçãorequire('mod')import mod from 'mod'
Exportaçãomodule.exports ou exportsexport e export default
CarregamentoSincrônicoAssíncrono
SuporteNode.js e ferramentas antigasNavegadores modernos e Node.js
OtimizaçõesMenos eficienteMelhor otimização com bundlers

Carregar pacotes Commonjs dentro do ESModule import.meta.url

import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const pino = require('pino');

// Uso do `pino`
const logger = pino();
logger.info('Hello, Pino!');

Habilitar esModuleInterop no TypeScript

{
"compilerOptions": {
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}

import pino from 'pino';

const logger = pino();
logger.info('Hello, Pino!');

Usar Importação Dinâmica

const pino = await import('pino').then(module => module.default);

// Uso do `pino`
const logger = pino();
logger.info('Hello, Pino!');

Propriedades do TSConfig relacionadas ao CommonJS e ESModule

Propriedade target

A propriedade target no tsconfig.json determina a versão do JavaScript para a qual o código TypeScript será compilado. Isso é importante porque diferentes ambientes de execução (como navegadores ou versões do Node.js) suportam diferentes conjuntos de funcionalidades do ECMAScript. Ao definir o target, você pode assegurar que o código compilado seja compatível com o ambiente onde será executado.

Valores possíveis para target incluem:

  • ES3 (padrão): Compatível com os ambientes JavaScript mais antigos.
  • ES5: Suporte para ambientes mais antigos; é o alvo recomendado para aplicações que precisam de compatibilidade ampla.
  • ES6/ES2015: Introduz suporte para classes, métodos de string, promessas, símbolos, e mais.
  • ES2016: Adiciona suporte para o operador de exponenciação e o método Array.prototype.includes.
  • ES2017: Introduz funções assíncronas, Object.entries, Object.values, e mais.
  • ES2018: Adiciona operadores de rest/spread para objetos, promessas assíncronas, RegExp named capture groups.
  • ES2019: Introduz Array.prototype.flat, Array.prototype.flatMap, e mais.
  • ES2020: Adiciona BigInt, Promise.allSettled, dynamic import(), e mais.
  • ESNext: Alvo mais recente, inclui as funcionalidades mais recentes propostas para o padrão ECMAScript.

Propriedade module

A propriedade module especifica o tipo de módulo gerado pelo compilador TypeScript. Módulos são importantes para organizar e encapsular código, bem como para gerenciar dependências. A escolha do módulo afeta como as instruções import e export são compiladas e pode ser crucial para a compatibilidade com diferentes carregadores de módulos ou ambientes.

Valores possíveis para module incluem:

  • None: Não gera código de módulo.
  • CommonJS: Utilizado para ambientes Node.js ou projetos que utilizam bundlers como o Webpack para ambientes que suportam CommonJS.
    const fs = require('fs'); // Importação no CommonJS
    module.exports = { func: () => {} }; // Exportação no CommonJS

  • AMD: Utilizado para projetos que requerem carregamento assíncrono de módulos.
  • UMD: Gera módulos que podem ser utilizados tanto com AMD quanto CommonJS.
  • System: Para uso com o carregador de módulos SystemJS.
  • ES6/ES2015 e versões mais recentes (ES2020, ESNext, etc.): Gera módulos ECMAScript que são úteis para projetos que visam ambientes modernos de execução que suportam módulos ES nativamente.
    import fs from 'fs'; // Importação no ESM
    export const func = () => {}; // Exportação no ESM

Escolher os valores apropriados para target e module depende do seu ambiente de execução e necessidades de compatibilidade. Por exemplo, para um projeto Node.js moderno, você pode usar target: "ES2018" e module: "CommonJS". Para um projeto de front-end visando navegadores modernos, target: "ES6" e module: "ESNext" podem ser escolhas adequadas.

Propriedade moduleResolution

Controla como o TypeScript resolve os caminhos dos módulos importados.

  • Exemplos de Valores:
    • node: Segue a lógica de resolução do Node.js. Procura por node_modules, extensões .js, .json, .node.

    • nodenext: Suporte para ESM e CJS no Node.js. Segue as regras de "type": "module" ou "type": "commonjs" no package.json.

    • classic: O comportamento mais antigo do TypeScript. Não procura em node_modules.