Node.js: Módulos path e url
Última atualização: 2026-08-26
1. A história: um desastre na implantação causado por um delimitador
A ferramenta CLI desenvolvida por Bob funcionou perfeitamente no macOS — a concatenação de caminhos utilizava /, e tanto a leitura da configuração quanto a gravação de logs ocorreram sem problemas. No entanto, após a implantação em um servidor Linux, o programa imediatamente apresentou um erro: ENOENT: no such file or directory. Após investigação, descobriu-se que Bob havia codificado / como separador de caminho no código, enquanto certa lógica de tratamento de caminhos no Windows utilizava \, o que levou a uma confusão na análise dos caminhos. Esse incidente proporcionou a Bob uma compreensão profunda da finalidade do módulo path — nunca concatenar caminhos manualmente.
(1) Você aprenderá
- Métodos principais do módulo
path: concatenar / resolver / analisar / formatar / nome_extensão / nome_base / nome_diretório - path.sep / path.delimiter: constantes multiplataforma
- url.URL / url.parse / url.fileURLToPath
- Construtor de URL e searchParams
- __dirname / __filename vs import.meta.url
- Melhores práticas para o tratamento de caminhos entre plataformas
2. Principais métodos do módulo path
O módulo path é um módulo integrado do Node.js que oferece ferramentas para concatenar, analisar e formatar caminhos de arquivos, lidando automaticamente com as diferenças nos separadores de caminho entre os sistemas operacionais.
(1) concatenação de caminhos — Path concatenation
path.join() Concatena vários segmentos de caminho em um único caminho padronizado, utilizando automaticamente o separador do sistema atual.
▶ Exemplo: Concatenação básica de caminhos com path.join
const path = require('path');
const fullPath = path.join('/app', 'src', 'utils', 'helper.js');
console.log(fullPath);
// macOS/Linux: /app/src/utils/helper.js
// Windows: \app\src\utils\helper.js
▶ Exemplo: normalização automática com path.join
const path = require('path');
console.log(path.join('/app', '../config', 'settings.json'));
// /config/settings.json
console.log(path.join('src', '.', 'index.js'));
// src/index.js
(2) path.resolve — Converte para um caminho absoluto
path.resolve() Concatene os caminhos da direita para a esquerda até obter um caminho absoluto. Se não for possível obter um caminho absoluto, use o diretório de trabalho atual como base.
▶ Exemplo: Uso básico do path.resolve
const path = require('path');
console.log(path.resolve('src', 'index.js'));
// /current/working/dir/src/index.js
console.log(path.resolve('/app', 'src', 'index.js'));
// /app/src/index.js
console.log(path.resolve('/app', '/tmp', 'file.txt'));
// /tmp/file.txt(Use the absolute path on the far right as the reference.)
(3) path.parse e path.format — Análise e reconstrução de caminhos
path.parse() divide o caminho em cinco partes: raiz, dir, base, ext e nome; path.format() recompõe o objeto em uma string de caminho.
▶ Exemplo: analisar o caminho usando path.parse
const path = require('path');
const parsed = path.parse('/app/src/utils/helper.js');
console.log(parsed);
{
root: '/',
dir: '/app/src/utils',
base: 'helper.js',
ext: '.js',
name: 'helper'
}
graph LR
A["/app/src/utils/helper.js"] --> B["root: /"]
A --> C["dir: /app/src/utils"]
A --> D["base: helper.js"]
D --> E["name: helper"]
D --> F["ext: .js"]
style A fill:#4CAF50,color:#fff
style B fill:#FF9800,color:#fff
style C fill:#2196F3,color:#fff
style D fill:#9C27B0,color:#fff
style E fill:#E91E63,color:#fff
style F fill:#FF5722,color:#fff
▶ Exemplo: path.format — Reescrita de caminhos
const path = require('path');
const filePath = path.format({
dir: '/app/src/utils',
base: 'helper.js'
});
console.log(filePath);
// /app/src/utils/helper.js
(4) caminho.extname / caminho.basename / caminho.dirname
Esses três métodos extraem a extensão do arquivo, o nome do arquivo e a parte do caminho correspondente ao diretório, respectivamente.
▶ Exemplo: Extração das partes de um caminho
const path = require('path');
const filePath = '/app/src/utils/helper.js';
console.log(path.extname(filePath)); // .js
console.log(path.basename(filePath)); // helper.js
console.log(path.basename(filePath, '.js')); // helper
console.log(path.dirname(filePath)); // /app/src/utils
3. Constantes de caminho multiplataforma
Os separadores de caminho e os separadores de variáveis de ambiente variam de acordo com os sistemas operacionais; o módulo path fornece constantes para acomodar essas diferenças.
(1) path.sep — Separador de caminho
| Plataforma | separador de caminho |
|---|---|
| macOS / Linux | / |
| Windows | \ |
(2) path.delimiter — Separador da variável de ambiente
| Plataforma | delimitador de caminho |
|---|---|
| macOS / Linux | : |
| Windows | ; |
▶ Exemplo: Como usar path.sep e path.delimiter
const path = require('path');
console.log('Delimiter:', JSON.stringify(path.sep));
// macOS/Linux: "/"
// Windows: "\\"
const envPaths = process.env.PATH.split(path.delimiter);
console.log('PATH Number of entries:', envPaths.length);
4. O módulo url e o construtor de URLs
(1) url.parse (obsoleto) vs new URL()
url.parse() é uma versão mais antiga da API e foi marcada como obsoleta. Recomendamos o uso do construtor new URL(), que está em conformidade com o padrão WHATWG.
| Recurso | url.parse() | new URL() |
|---|---|---|
| Padrão | Node.js antigo | Padrão WHATWG |
| Status | Obsoleto | Recomendado |
| Tratamento de erros | Retornar null sem aviso |
Lançar um TypeError |
| searchParams | Nenhum | URLSearchParams integrado |
| Desempenho | Mais lento | Mais rápido |
▶ Exemplo: Uso antigo de url.parse (não recomendado)
const url = require('url');
const parsed = url.parse('https://example.com/api/users?name=Bob&page=1');
console.log(parsed.hostname);
console.log(parsed.query);
example.com
name=Bob&page=1
▶ Exemplo: Uso recomendado de new URL()
const myUrl = new URL('https://example.com/api/users?name=Bob&page=1');
console.log(myUrl.hostname);
console.log(myUrl.pathname);
console.log(myUrl.searchParams.get('name'));
console.log(myUrl.searchParams.get('page'));
example.com
/api/users
Bob
1
(2) url.searchParams —— Manipulação de parâmetros de consulta
A propriedade searchParams do objeto URL é uma instância de URLSearchParams, que oferece métodos práticos para adicionar, excluir, atualizar e consultar parâmetros.
▶ Exemplo: Operações CRUD para searchParams
const myUrl = new URL('https://example.com/search');
myUrl.searchParams.set('q', 'nodejs');
myUrl.searchParams.set('lang', 'zh');
myUrl.searchParams.append('tag', 'バックエンド');
myUrl.searchParams.append('tag', 'tutorial');
myUrl.searchParams.remove('lang');
console.log(myUrl.toString());
// https://example.com/search?q=nodejs&tag=バックエンド&tag=tutorial
console.log(myUrl.searchParams.getAll('tag'));
// [ 'バックエンド', 'tutorial' ]
(3) url.fileURLToPath — Converte uma URL de arquivo em um caminho local
No módulo ESM, import.meta.url retorna uma URL no formato file://, que deve ser convertida em um caminho do sistema de arquivos usando url.fileURLToPath().
▶ Exemplo: Conversão de fileURLToPath
const { fileURLToPath } = require('url');
const fileUrl = 'file:///app/src/index.js';
const filePath = fileURLToPath(fileUrl);
console.log(filePath);
// macOS/Linux: /app/src/index.js
// Windows: \app\src\index.js
5. __dirname / __filename x import.meta.url
Essa é a principal diferença entre os sistemas de módulos CJS e ESM no que diz respeito à obtenção do caminho atual do arquivo.
| Característica | __dirname / __filename | import.meta.url |
|---|---|---|
| Sistema de módulos | CJS (require) | ESM (import) |
| Tipo de retorno | String de caminho absoluto | String de URL file:// |
| Disponibilidade | Variável global, use diretamente | Requer fileURLToPath |
| Caminho do diretório | __dirname (recuperar diretamente) | Requer dirname(fileURLToPath()) |
| Caminho do arquivo | __nome_do_arquivo (acesso direto) | Requer conversão usando fileURLToPath() |
▶ Exemplo: Como usar __dirname no CJS
const path = require('path');
console.log('__dirname:', __dirname);
console.log('__filename:', __filename);
const configPath = path.join(__dirname, 'config', 'settings.json');
console.log(configPath);
▶ Exemplo: Como usar import.meta.url no ESM
import { fileURLToPath } from 'url';
import path from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
console.log('__dirname:', __dirname);
console.log('__filename:', __filename);
6. Tabela de referência rápida dos métodos comuns de caminho
| Método | Parâmetros | Valor de retorno | Finalidade |
|---|---|---|---|
path.join() |
...paths |
string |
Concatenar segmentos de caminho e normalizá-los automaticamente |
path.resolve() |
...paths |
string |
Converter para caminho absoluto |
path.parse() |
pathString |
object |
Dividir o caminho em suas partes constituintes |
path.format() |
pathObject |
string |
Reconstruir o objeto “path” como uma string |
path.extname() |
pathString |
string |
Obter extensão do arquivo |
path.basename() |
pathString[, ext] |
string |
Obter nome do arquivo (a extensão pode ser omitida) |
path.dirname() |
pathString |
string |
Ir para o Índice |
path.isAbsolute() |
pathString |
boolean |
Verificar se é um caminho absoluto |
path.normalize() pathString string Caminho normalizado (tratamento de .., .) |
|||
path.relative() |
from, to |
string |
Obter o caminho relativo de “from” para “to” |
7. Melhores práticas para o tratamento de caminhos entre plataformas
(1) Princípios Fundamentais
| Regra | Descrição | Exemplo incorreto | Exemplo correto |
|---|---|---|---|
| Uso de path.join | Tratamento automático de delimitadores | 'src' + '/' + 'index.js' |
path.join('src', 'index.js') |
| Usar path.sep | Constante separadora de aspas | str.split('/') |
str.split(path.sep) |
| Usar path.resolve | Obter o caminho absoluto | process.cwd() + '/' + file |
path.resolve(file) |
| Usar fileURLToPath | Converter URL do arquivo | import.meta.url.slice(7) |
fileURLToPath(import.meta.url) |
| Evite usar __dirname no ESM | Não disponível | Use __dirname diretamente | Use import.meta.url em vez disso |
▶ Exemplo:(2) Padrões comuns de erros
const path = require('path');
// ❌ Hard-coded delimiters
const bad1 = '/app/data/' + 'config.json';
// ✅ Usage path.join
const good1 = path.join('/app', 'data', 'config.json');
// ❌ Manually Merge Working Directories
const bad2 = process.cwd() + '/output/result.log';
// ✅ Usage path.resolve
const good2 = path.resolve('output', 'result.log');
// ❌ String Replacement Delimiter
const bad3 = somePath.replace(/\\/g, '/');
// ✅ Usage path.normalize
const good3 = path.normalize(somePath);
8. Exemplo abrangente: Ferramenta de caminho de arquivo multiplataforma
O exemplo a seguir simula a lógica central da ferramenta CLI revisada por Bob: leitura do caminho de configuração, criação do diretório de dados, análise da URL e extração de parâmetros.
const path = require('path');
const { fileURLToPath } = require('url');
class PathTool {
constructor(baseDir) {
this.baseDir = baseDir || process.cwd();
}
resolveConfigPath(configRelativePath) {
return path.resolve(this.baseDir, configRelativePath);
}
buildDataPath(...segments) {
return path.join(this.baseDir, 'data', ...segments);
}
parseUrl(urlString) {
const myUrl = new URL(urlString);
return {
protocol: myUrl.protocol,
hostname: myUrl.hostname,
pathname: myUrl.pathname,
params: Object.fromEntries(myUrl.searchParams.entries())
};
}
extractFileInfo(filePath) {
const parsed = path.parse(filePath);
return {
directory: parsed.dir,
fileName: parsed.name,
extension: parsed.ext,
fullPath: filePath
};
}
toFilePath(urlOrPath) {
if (urlOrPath.startsWith('file://')) {
return fileURLToPath(urlOrPath);
}
return path.resolve(urlOrPath);
}
}
const tool = new PathTool('/app/project');
// 1. Parsing the Configuration Path
const configPath = tool.resolveConfigPath('config/app.json');
console.log('Configuration Path:', configPath);
// /app/project/config/app.json
// 2. Data Merge Catalog
const dataPath = tool.buildDataPath('users', 'profiles.json');
console.log('Data Path:', dataPath);
// /app/project/data/users/profiles.json
// 3. Analysis URL and extract the parameters
const parsed = tool.parseUrl('https://api.example.com/v1/users?role=admin&active=true');
console.log('URL Analysis:', parsed);
// { protocol: 'https:', hostname: 'api.example.com',
// pathname: '/v1/users', params: { role: 'admin', active: 'true' } }
// 4. Extract File Information
const info = tool.extractFileInfo('/app/project/data/users/profiles.json');
console.log('File Information:', info);
// { directory: '/app/project/data/users',
// fileName: 'profiles', extension: '.json', fullPath: '...' }
// 5. file URL File Path
const localPath = tool.toFilePath('file:///app/project/config/app.json');
console.log('Local Path:', localPath);
// /app/project/config/app.json
❓ Perguntas Frequentes
P: Qual é a diferença entre
path.joinepath.resolve? R:path.joinsimplesmente concatena segmentos de caminho e os normaliza; não garante que o resultado seja um caminho absoluto.path.resolveresolve o caminho da direita para a esquerda até que um caminho absoluto seja produzido; se nenhum caminho absoluto for encontrado, ele usaprocess.cwd()como base.
P: Por que usar
path.joinem vez da concatenação de strings? R:path.joinusa automaticamente o separador de caminho do sistema atual, lida com a normalização de..e.e evita problemas de compatibilidade entre plataformas causados pela codificação estática de/ou\.
P: É possível usar __dirname no ESM? R: Não. As variáveis globais __dirname e __filename não existem nos módulos ESM; é necessário usar
path.dirname(fileURLToPath(import.meta.url))para obter valores equivalentes.
P: O
url.parsefoi considerado obsoleto? R: Sim, ourl.parsefoi marcado como obsoleto. Recomendamos usar o construtornew URL()do padrão WHATWG, que oferece melhor tratamento de erros e suporte integrado parasearchParams.
P: Como posso garantir a compatibilidade de caminhos entre o Windows e o macOS/Linux? R: Sempre use
path.joinoupath.resolvepara concatenar caminhos, usepath.seppara especificar o separador, usepath.delimiterpara lidar com variáveis de ambiente e evite qualquer string de separador codificada diretamente.
P: O que
import.meta.urlretorna? R: Retorna a string da URL do protocolofile://para o módulo atual (por exemplo,file:///app/src/index.js), que deve ser convertida em um caminho do sistema de arquivos usandofileURLToPath().
P: O
path.isAbsolutese comporta de maneira consistente em diferentes plataformas? R: Não, não se comporta. Em sistemas POSIX,/usr/localé um caminho absoluto, enquanto no Windows,C:\Usersé um caminho absoluto e/usr/localnão é.path.isAbsolutedetermina o resultado com base na plataforma atual.
📖 Resumo
- 1 Matéria: Conceitos-chave e implicações de um desastre de implantação causado por um delimitador
- Conceitos fundamentais e uso dos métodos principais no módulo de 2 caminhos
- Conceitos básicos e uso das constantes multiplataforma de 3 caminhos
- 4 Conceitos fundamentais e uso do módulo url e do construtor de URL
- 5 Conceitos-chave e uso de __dirname / __filename em comparação com import.meta.url
- Caminho 6: Guia de referência rápida aos conceitos fundamentais e métodos de uso
- 7 conceitos fundamentais e melhores práticas para o tratamento de caminhos entre plataformas
- 8 Exemplo abrangente: conceitos básicos e uso de uma ferramenta de caminho de arquivo multiplataforma
📝 Exercícios
- Conclua todos os exemplos de código desta lição e certifique-se de que cada um deles seja executado corretamente.
- Modifique o exemplo completo e adicione suas próprias extensões
- Analise a documentação oficial, identifique 1 ou 2 APIs que não foram abordadas nesta aula e escreva um código de teste para elas.
- Reflexão: Como você aplicaria o que aprendeu nesta aula a um projeto do mundo real?
- Tente combinar o que você aprendeu nesta aula com o conteúdo das aulas anteriores para criar um pequeno projeto.