Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Vite Library Mode no Node.js

Atualizado em: 11 de setembro de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

O Vite Library Mode no Node.js permite empacotar bibliotecas JavaScript e TypeScript usando uma configuração orientada à distribuição. Ele é especialmente útil para componentes, SDKs de navegador, utilitários compartilhados e pacotes que precisam de uma página de demonstração durante o desenvolvimento.

O modo de biblioteca define entry points, formatos de saída, nomes de arquivos e integração com o pipeline do Vite. Porém, o autor ainda precisa externalizar dependências, gerar declarações TypeScript, definir exports, controlar CSS e testar o tarball em consumidores reais.

Neste guia, você aprenderá a configurar Vite Library Mode, criar entradas únicas ou múltiplas, gerar ESM e CommonJS, externalizar peer dependencies, exportar CSS, produzir tipos e publicar um pacote seguro.

Quando usar Library Mode?

Use quando o pacote é consumido por outras aplicações e precisa de:

  • bundle ESM;
  • formato CommonJS ou UMD;
  • tree shaking;
  • assets e CSS processados;
  • servidor de desenvolvimento para exemplos;
  • plugins do ecossistema Vite;
  • build rápido e configuração pequena.

Para bibliotecas Node.js puras e fluxos avançados, Rollup, Rolldown ou esbuild podem oferecer controle mais direto.

Instalação

npm install --save-dev vite typescript

Crie uma estrutura:

my-lib/
├── src/
│   ├── index.ts
│   └── secondary.ts
├── vite.config.ts
├── tsconfig.json
└── package.json

Configuração de entrada única

import { resolve } from 'node:path';
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    lib: {
      entry: resolve(import.meta.dirname, 'src/index.ts'),
      name: 'MyLibrary',
      fileName: 'my-library'
    }
  }
});

A documentação atual de Library Mode do Vite explica que o preset gera formatos adequados à distribuição e permite personalizar o pipeline subjacente.

Scripts

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "build:watch": "vite build --watch",
    "typecheck": "tsc --noEmit"
  }
}

Veja npm Scripts no Node.js.

Página de demonstração

Durante o desenvolvimento, index.html pode importar a biblioteca:

<script type="module" src="/demo/main.ts"></script>
import { createWidget } from '../src/index.ts';

createWidget(document.querySelector('#app'));

Isso oferece HMR e feedback rápido sem publicar o pacote.

Múltiplos entry points

export default defineConfig({
  build: {
    lib: {
      entry: {
        index: resolve(import.meta.dirname, 'src/index.ts'),
        secondary: resolve(import.meta.dirname, 'src/secondary.ts')
      }
    }
  }
});

O package.json precisa expor cada entrada:

{
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    },
    "./secondary": {
      "import": "./dist/secondary.js",
      "require": "./dist/secondary.cjs"
    }
  }
}

Consulte Exports e Imports no package.json.

Formatos

lib: {
  entry: resolve(import.meta.dirname, 'src/index.ts'),
  formats: ['es', 'cjs'],
  fileName(format) {
    return format === 'es' ? 'index.js' : 'index.cjs';
  }
}

Uma entrada única também pode gerar UMD quando consumidores usam script global. Para bibliotecas modernas, ESM costuma ser o formato principal.

Externalizando dependências

build: {
  lib: { /* ... */ },
  rolldownOptions: {
    external: ['react', 'react-dom']
  }
}

Dependências que o consumidor fornece devem ficar externas. Isso evita duas cópias de React ou outro framework.

Peer dependencies

{
  "peerDependencies": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  }
}

Teste todas as versões declaradas. Não use um range amplo apenas para evitar manutenção.

External automático

Uma função pode ler dependencies e peerDependencies:

const externals = [
  ...Object.keys(pkg.dependencies ?? {}),
  ...Object.keys(pkg.peerDependencies ?? {})
];

external(id) {
  return externals.some(name =>
    id === name || id.startsWith(`${name}/`)
  );
}

Decida conscientemente se dependencies devem ser empacotadas. Em uma biblioteca de navegador, incorporar utilitários pequenos pode simplificar consumo; em plugins e SDKs, externalização costuma ser preferível.

Globais para UMD

output: {
  globals: {
    react: 'React',
    'react-dom': 'ReactDOM'
  }
}

Essa configuração só é necessária para formatos globais como UMD ou IIFE.

Package.json recomendado

{
  "name": "@empresa/widget",
  "version": "1.0.0",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/index.cjs",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    }
  }
}

TypeScript não é verificado pelo Vite

Vite transforma TypeScript, mas não executa typecheck completo. Mantenha:

npm run typecheck

No CI, execute typecheck antes da publicação. Consulte CI para Node.js com GitHub Actions.

Declarações TypeScript

Gere tipos com tsc:

{
  "compilerOptions": {
    "emitDeclarationOnly": true,
    "declaration": true,
    "declarationMap": true,
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src"]
}
tsc -p tsconfig.types.json

Plugins como vite-plugin-dts podem automatizar, mas executam código adicional e precisam ser avaliados. A etapa nativa é mais previsível quando a estrutura é simples.

CSS da biblioteca

Quando a biblioteca importa CSS:

import './style.css';

O Vite gera um arquivo CSS separado. Exporte-o:

{
  "exports": {
    ".": "./dist/index.js",
    "./style.css": "./dist/my-library.css"
  }
}

Defina cssFileName para um nome estável quando necessário.

CSS inline ou separado?

CSS separado permite cache e import explícito. Injetar CSS pelo JavaScript pode facilitar widgets, mas cria efeitos colaterais e dificulta SSR. Documente a escolha.

Assets

Imagens, fontes e WASM importados podem ser copiados ou incorporados conforme o tamanho. Teste URLs no pacote instalado, não apenas no servidor local.

Variáveis de ambiente

No Library Mode, referências a import.meta.env podem ser substituídas durante o build. Não coloque segredos. Bibliotecas não devem fixar configuração do ambiente do consumidor.

Para valores dinâmicos, aceite opções:

createClient({
  endpoint,
  apiKey
});

Define

define: {
  __LIB_VERSION__: JSON.stringify(pkg.version)
}

Use apenas metadados públicos. Tudo incorporado fica visível.

Tree shaking

Publique ESM, exports nomeados e módulos sem efeitos colaterais. No package.json:

{
  "sideEffects": ["**/*.css"]
}

Isso informa que JavaScript pode ser removido, mas imports de CSS devem ser preservados.

Minificação

Bibliotecas geralmente não precisam ser minificadas. O consumidor pode minificar com contexto completo. Entregar código legível melhora debug e auditoria.

Sourcemaps

build: {
  sourcemap: true,
  lib: { /* ... */ }
}

Sourcemaps ajudam consumidores, mas podem aumentar tamanho e revelar fontes. Defina uma política.

Watch mode

vite build --watch

Use para desenvolver junto com uma aplicação consumidora local. Mudanças no arquivo de configuração podem exigir reinício do processo.

Testando com npm pack

npm run typecheck
npm test
npm run build
npm pack --dry-run
npm pack

Instale o tarball em um projeto limpo:

npm install ../empresa-widget-1.0.0.tgz

Veja Publicar Pacote no npm.

Testes de formatos

node --input-type=module -e "import('@empresa/widget').then(console.log)"
node -e "console.log(require('@empresa/widget'))"

Para bibliotecas de navegador, crie também testes em navegadores reais com Playwright.

SSR

Se a biblioteca pode rodar em SSR, não acesse window ou document durante import. Faça a leitura dentro de funções ou proteja por ambiente.

Bibliotecas Node.js puras

Vite Library Mode é orientado principalmente a bibliotecas de navegador e frameworks. Para pacotes Node.js sem assets ou página demo, Rollup para Bibliotecas Node.js ou esbuild no Node.js pode ser mais direto.

Monorepos

Em npm Workspaces, cada pacote pode ter sua configuração ou compartilhar helpers. Não deixe dependências internas serem incorporadas quando devem permanecer como pacotes separados.

CI

- run: npm ci
- run: npm run lint
- run: npm run typecheck
- run: npm test
- run: npm run build
- run: npm pack --dry-run

Teste o tarball em uma aplicação exemplo e armazene o pacote como artifact antes da release.

Segurança

  • Fixe Vite e plugins.
  • Não incorpore segredos.
  • Externalize frameworks.
  • Restrinja o campo files.
  • Revise sourcemaps.
  • Teste SSR.
  • Publique com OIDC.

Erros comuns

  • Sem external: framework é duplicado.
  • Sem types: consumidores perdem IntelliSense.
  • Exports incorretos: import ou require falha.
  • CSS não exportado: estilos desaparecem.
  • Import.meta.env com segredo: dado entra no bundle.
  • Teste só no demo: pacote instalado quebra.
  • Side effects false com CSS: bundler remove estilo.
  • Usar Vite para backend sem necessidade: configuração fica indireta.

Configuração recomendada

import { resolve } from 'node:path';
import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    sourcemap: true,
    lib: {
      entry: {
        index: resolve(import.meta.dirname, 'src/index.ts'),
        secondary: resolve(import.meta.dirname, 'src/secondary.ts')
      },
      formats: ['es', 'cjs']
    },
    rolldownOptions: {
      external: ['react', 'react-dom']
    }
  }
});

Conclusão

O Vite Library Mode no Node.js combina experiência de desenvolvimento rápida com um preset de build orientado à distribuição. Entradas, formatos, CSS e assets podem ser configurados sem montar toda a infraestrutura manualmente.

Externalize peer dependencies, gere declarations, defina exports e teste o tarball. Quando o pacote é validado fora do demo local, Vite se torna uma base eficiente para bibliotecas modernas.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita