Criando um Pacote NPM com Suporte a CommonJS e ESM usando Rollup
Marcelo Lourenço
Posted on October 14, 2024
Neste post, vamos explorar como criar um pacote NPM com suporte a CommonJS (CJS) e ECMAScript Modules (ESM) usando Rollup.
Rollup é um bundler JavaScript ideal para criar bibliotecas e pacotes, pois ele gera bundles de código altamente otimizados, que podem ser facilmente usados em diferentes ambientes.
Estrutura do projeto:
my-npm-package/
├── src/
│ ├── index.js
| └── utils
| ├──math.js
| └──string.js
├── rollup.config.js
└── package.json
1. Configurando o Projeto
Comece criando um novo diretório para o seu pacote NPM. Dentro do diretório, execute o comando:
npm init -y
Isso irá gerar um arquivo package.json
básico.
Atualize o arquivo package.json
com as seguintes informações:
{
"name": "my-npm-package",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c --watch"
},
"repository": {
"type": "git",
"url": "git+https://github.com/your-username/my-npm-package.git"
},
"author": "",
"license": "MIT"
}
Explicando as propriedades:
- name: Nome do pacote NPM.
- version: Versão do pacote.
- description: Descrição do pacote.
- main: Define o arquivo principal para projetos CommonJS.
- module: Define o arquivo principal para projetos ESM.
- scripts: Define scripts para build e desenvolvimento.
- repository: Define o repositório do pacote.
- author: Nome do autor do pacote.
- license: Licença do pacote.
Em seguida, instale as dependências necessárias:
npm install rollup @rollup/plugin-commonjs @rollup/plugin-node-resolve
Explicando as dependências:
- rollup: Ferramenta de empacotamento de módulos.
- rollup-plugin-commonjs: Plugin Rollup para lidar com módulos CommonJS.
- rollup-plugin-node-resolve: Plugin Rollup para resolver dependências de módulos do Node.js.
2. Criando a Pasta src
Crie uma pasta chamada src
dentro do diretório do projeto.
Dentro de src
, crie um arquivo index.js
.
// src/index.js
import { add } from './utils/math.js';
import { toUpperCase } from './utils/string.js';
export function calculate() {
const result = add(10, 20);
return `Result: ${result}, UpperCase: ${toUpperCase('hello')}`;
}
Dentro de src
, crie o subdiretório utils
.
Dentro do subdiretório utils
, crie os aquivos:
math.js
// src/utils/math.js
export function add(a, b) {
return a + b;
}
string.js
// src/utils/string.js
export function toUpperCase(str) {
return str.toUpperCase();
}
3. Criando o Arquivo rollup.config.js
.
Crie um arquivo rollup.config.js
com a configuração do Rollup.
O Rollup tem 2 opções de configurações de saída:
- A primeira: Todo o código em único arquivo de saída.
- A segunda: Utilizando o
preserveModules
para manter a estrutura de módulos.
3.1 Arquivo rollup.config.js
sem preservar a estrutura de módulo
O Rollup, por padrão, combina todos os módulos em um único arquivo de saída. Isso significa que todos os seus módulos, incluindo seus próprios e seus dependentes, são mesclados em um único arquivo JavaScript.
// rollup.config.js
import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
export default [
{
input: 'src/index.js', // Arquivo principal de entrada
output: {
file: 'dist/index.cjs', // Diretório de saída para CommonJS
format: 'cjs',
sourcemap: true,
},
plugins: [
resolve(),
commonjs(),
],
},
{
input: 'src/index.js', // Arquivo principal de entrada
output: {
file: 'dist/index.mjs', // Diretório de saída para ES Modules
format: 'es',
sourcemap: true,
},
plugins: [
resolve(), // Resolve módulos de node_modules
commonjs() // Converte pacotes CommonJS para ESModules
],
},
];
Explicando as configurações:
- input: Define o arquivo de entrada para o Rollup.
- output: Define o arquivo de saída e o formato de saída.
- format: Define o formato do módulo (ESM ou CommonJS).
- plugins: Define os plugins que serão utilizados no Rollup.
3.2 Arquivo rollup.config.js
preservando a estrutura de módulo
O Rollup mantém a estrutura de módulos do seu código original. Cada módulo do seu projeto será empacotado em seu próprio arquivo.
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: './src/index.js', // Arquivo principal de entrada
output: [
{
dir: 'dist/cjs', // Diretório de saída para CommonJS
format: 'cjs',
entryFileNames: '[name].cjs', // Mantém o nome do arquivo original
exports: 'auto',
preserveModules: true, // Preserva a estrutura dos módulos
preserveModulesRoot: 'src', // Diretório base que será mantido
},
{
dir: 'dist/mjs', // Diretório de saída para ES Modules
format: 'es',
entryFileNames: '[name].mjs',
preserveModules: true,
preserveModulesRoot: 'src',
}
],
plugins: [
resolve(), // Resolve módulos de node_modules
commonjs() // Converte pacotes CommonJS para ESModules
]
};
Explicando as configurações:
-
entryFileNames: Define um padrão para os nomes dos arquivos de saída, usando placeholders:
-
[name]
: Substituído pelo nome do módulo. -
[hash]
: Substituído por um hash único para o arquivo. -
[format]
: Substituído pelo formato do módulo (esm ou cjs).
-
-
preserveModules: Preserva a estrutura de módulos original do código. Se
true
, cada módulo será empacotado em seu próprio arquivo. - preserveModulesRoot: Define o diretório raiz dos módulos a serem preservados.
3.2.1 Neste caso, altere essas linhas no package.json
:
"main": "dist/cjs/index.cjs",
"module": "dist/mjs/index.mjs",
4. Compilando e Publicando o Pacote
Execute o comando npm run build
para compilar o seu pacote. Isso irá gerar os arquivos compilados em dist/
.
Em seguida, publique o pacote no npm usando o comando npm publish
.
5. Usando o Pacote
Agora você pode usar o pacote NPM que criou em outros projetos.
- Exemplo em um projeto CommonJS:
const { calculate } = require('my-npm-package');
console.log(calculate()); // "Result: 30, UpperCase: HELLO"
-
Exemplo em um projeto ESM (quando o
package.json
tem o"type": "module"
):
import { calculate } from 'my-npm-package';
console.log(calculate()); // "Result: 30, UpperCase: HELLO"
Conclusão
Criar um pacote NPM com suporte a CommonJS e ESM é simples usando o Rollup. Ao seguir as etapas descritas neste post, você pode construir um pacote flexível e reutilizável que atenda às necessidades de diferentes projetos.
Posted on October 14, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.