# Preset unenv

O pacote `@aziontech/unenv-preset` é o preset da [Azion Lib](/pt-br/documentacao/devtools/azion-lib/) para o unenv: um objeto de configuração que lista os globais, os módulos e os polyfills do Node.js que um build para o [Azion Runtime](/pt-br/documentacao/devtools/runtime/) substitui. O preset é aplicado pelo Azion Bundler, que a Azion CLI executa para fazer o build de um projeto. O pacote não tem funções para chamar: uma [function](/pt-br/documentacao/plataforma/functions/) acessa os polyfills ao importar módulos `node:*`, como `node:fs` e `node:crypto`.

Instale o pacote:

```bash
npm install @aziontech/unenv-preset
```

O exemplo do preset nesta página é um módulo ES em JavaScript que roda no Node.js. Os exemplos de function rodam dentro de uma function servida localmente com o [azion dev](/pt-br/documentacao/devtools/cli/dev-comando/). Para saber o que o `node:fs` retorna em uma function após o deploy, consulte [node:fs](/pt-br/documentacao/devtools/runtime/node/fs/).

---

## Objeto do preset

O export padrão de `@aziontech/unenv-preset` é o objeto do preset, `{ inject, alias, external, polyfill }`. O pacote não tem exports nomeados, então `import { preset } from '@aziontech/unenv-preset'` retorna `undefined`. Importe o objeto como export padrão:

```javascript
import preset from '@aziontech/unenv-preset';

// The package has a default export only: { inject, alias, external, polyfill }
console.log('keys:', Object.keys(preset));
console.log('inject:', Object.keys(preset.inject));
console.log('alias:', Object.keys(preset.alias));
console.log('external:', preset.external);
console.log('polyfill:', preset.polyfill);
```

Saída:

```text
keys: [ 'inject', 'alias', 'external', 'polyfill' ]
inject: [
  '__dirname',
  '__filename',
  'import.meta.url',
  'process',
  'performance',
  'setInterval',
  'clearInterval',
  'console',
  'asyncStorage',
  'dateToString'
]
alias: [
  '@aziontech/utils',
  '@aziontech/utils/edge',
  '@aziontech/utils/node',
  'fetch-to-node',
  'accepts',
  'assert',
  'buffer',
  'https',
  'module',
  'string_decoder',
  'timers',
  'util',
  'zlib'
]
external: [
  'node:async_hooks',
  'node:fs/promises',
  'node:stream',
  'node:crypto'
]
polyfill: [
  'aziondev:async_hooks:/async-hooks/async-hooks.polyfills.js',
  'aziondev:fs:/fs/fs.polyfills.js',
  'aziondev:fs/promises:/fs/promises/promises.polyfills.js',
  'aziondev:stream:/stream/stream.polyfills.js',
  'aziondev:crypto:/crypto/crypto.polyfills.js',
  'azionprd:fs:/fs.js'
]
```

O objeto tem quatro propriedades:

| Propriedade | Tipo       | Descrição                                                                                                                                                                                                                                                                           |
| ----------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inject`    | `object`   | Os globais que o build injeta, cada chave mapeada para uma string. Para a lista, consulte [Polyfills globais](#polyfills-globais).                                                                                                                                                  |
| `alias`     | `object`   | Os nomes de módulo que o build mapeia para um substituto, cada chave mapeada para uma string: `@aziontech/utils`, `@aziontech/utils/edge`, `@aziontech/utils/node`, `fetch-to-node`, `accepts`, `assert`, `buffer`, `https`, `module`, `string_decoder`, `timers`, `util` e `zlib`. |
| `external`  | `string[]` | Quatro nomes de módulo: `node:async_hooks`, `node:fs/promises`, `node:stream` e `node:crypto`.                                                                                                                                                                                      |
| `polyfill`  | `string[]` | As entradas de polyfill. As entradas que começam com `aziondev:` atendem builds de desenvolvimento e cobrem `async_hooks`, `fs`, `fs/promises`, `stream` e `crypto`. A única entrada `azionprd:` atende builds de produção e cobre `fs`.                                            |

O build aplica esse objeto por você, então um projeto não o passa para o unenv manualmente. O preset unenv não é o campo `preset` de `build` no [azion.config.js](/pt-br/documentacao/devtools/cli/azion-config-js/#build), que nomeia o preset de framework ou de linguagem de um projeto.

---

## Polyfills globais

A propriedade `inject` do preset unenv lista os globais do Node.js que o build adiciona a uma function. Uma function usa esses globais como faria no Node.js, sem importar nada.

| Global        | Descrição                                                                 |
| ------------- | ------------------------------------------------------------------------- |
| `__dirname`   | O nome do diretório atual.                                                |
| `__filename`  | O nome do arquivo atual.                                                  |
| `process`     | Informações do processo e o ambiente, incluindo as variáveis de ambiente. |
| `performance` | Medição de tempo de performance.                                          |

O preset também injeta `import.meta.url`, `setInterval`, `clearInterval`, `console`, `asyncStorage` e `dateToString`.

---

## Módulos do Node.js em uma function

Uma function acessa os polyfills do preset unenv pelos nomes de módulo do Node.js. Importe `node:fs` ou `node:crypto` no código da function, e o build coloca o polyfill no lugar quando `build.polyfills` é `true` no [azion.config.js](/pt-br/documentacao/devtools/cli/azion-config-js/#build). O template JavaScript que o `azion init` cria define `polyfills` como `true`.

Importe o módulo do Node.js, nunca um arquivo do pacote. Os arquivos de polyfill de `@aziontech/unenv-preset` não podem ser importados no Node.js nem em uma function, e o pacote não tem arquivo de polyfill de `crypto`. As mensagens que cada tentativa retorna estão em [Erros](#erros).

As chamadas de `node:fs` leem os arquivos que `build.memoryFS` incorpora ao build. Um arquivo é lido pelo caminho relativo a `removePathPrefix`. Os exemplos de `node:fs` desta página usam um projeto cujo `azion.config.js` define `build.memoryFS` como `{ injectionDirs: ['./data'], removePathPrefix: './data' }`. A pasta `data/` desse projeto contém `hello.txt`, `index.html`, `about/index.html` e `docs/readme.txt`, então `data/hello.txt` é lido como `/hello.txt`.

No `azion dev`, o `node:fs` lê os arquivos incorporados da pasta `.edge/storage/` do projeto. O `node:fs` local não tem `writeFileSync`, `mkdirSync` nem `readSync`.

---

## createHash e randomUUID

As funções `createHash` e `randomUUID` vêm de `node:crypto`. `createHash` retorna um objeto de hash para um algoritmo, como `sha256`, e `randomUUID` retorna um UUID aleatório. Para o módulo completo, consulte [node:crypto](/pt-br/documentacao/devtools/runtime/node/crypto/).

Esta function gera o hash de uma string e gera um UUID:

```javascript
import { createHash, randomUUID } from 'node:crypto';

export default {
  async fetch() {
    // Create a hash
    const hash = createHash('sha256');
    hash.update('some data');
    const digest = hash.digest('hex');

    // Generate a UUID
    const uuid = randomUUID();

    return new Response(`sha256=${digest}\nuuid=${uuid}\n`);
  },
};
```

Servida localmente com `azion dev`, a function retorna:

```text
$ curl http://localhost:3333/x
HTTP/1.1 200 OK
content-type: text/plain;charset=UTF-8

sha256=1307990e6ba5ca145eb35e99182a9bec46531bc54ddf656a602c780fa0240dee
uuid=e2ebf3ce-e7e9-4393-855c-ccdd93ea26f3
```

---

## readFileSync

A função `readFileSync` de `node:fs` lê o conteúdo completo de um arquivo que `build.memoryFS` incorpora ao build.

| Parâmetro | Tipo     | Obrigatório | Descrição                                         |
| --------- | -------- | ----------- | ------------------------------------------------- |
| `path`    | `string` | Sim         | O caminho do arquivo.                             |
| `options` | —        | Não         | Opções para a leitura, como a codificação `utf8`. |

Retorna o conteúdo do arquivo como uma `string` ou um `Buffer`. Com a codificação `utf8`, o conteúdo é uma `string`.

Esta function retorna o conteúdo de `/hello.txt`, o arquivo `data/hello.txt` do projeto:

```javascript
import { readFileSync } from 'node:fs';

export default {
  async fetch() {
    // Read a file embedded with build.memoryFS (data/hello.txt is served as /hello.txt)
    const content = readFileSync('/hello.txt', 'utf8');
    return new Response(content);
  },
};
```

Servida localmente com `azion dev`, a function retorna:

```text
$ curl http://localhost:3333/x
HTTP/1.1 200 OK
content-type: text/plain;charset=UTF-8

Hello from memoryFS
```

---

## readdirSync

A função `readdirSync` de `node:fs` lista o conteúdo de um diretório que `build.memoryFS` incorpora ao build.

| Parâmetro | Tipo     | Obrigatório | Descrição               |
| --------- | -------- | ----------- | ----------------------- |
| `path`    | `string` | Sim         | O caminho do diretório. |
| `options` | —        | Não         | Opções para a listagem. |

Retorna um `string[]` com os nomes dos arquivos e diretórios do diretório.

Esta function lista o diretório raiz e o diretório `/docs`:

```javascript
import { readdirSync } from 'node:fs';

export default {
  async fetch() {
    // List directory contents
    const files = readdirSync('/');
    const docs = readdirSync('/docs');
    return Response.json({ files, docs });
  },
};
```

Servida localmente com `azion dev`, a function retorna:

```text
$ curl http://localhost:3333/x
HTTP/1.1 200 OK
content-type: application/json

{"files":["about","docs","hello.txt","index.html"],"docs":["readme.txt"]}
```

---

## statSync e existsSync

A função `existsSync` de `node:fs` verifica se um caminho existe nos arquivos que `build.memoryFS` incorpora.

| Parâmetro | Tipo     | Obrigatório | Descrição              |
| --------- | -------- | ----------- | ---------------------- |
| `path`    | `string` | Sim         | O caminho a verificar. |

Retorna `true` quando o caminho existe e `false` quando não existe.

A função `statSync` de `node:fs` retorna as estatísticas de um arquivo ou de um diretório.

| Parâmetro | Tipo     | Obrigatório | Descrição                             |
| --------- | -------- | ----------- | ------------------------------------- |
| `path`    | `string` | Sim         | O caminho do arquivo ou do diretório. |
| `options` | —        | Não         | Opções para a chamada.                |

Retorna um objeto `fs.Stats`, com `size`, `isFile()` e `isDirectory()`.

Esta function verifica `/hello.txt`, lê as estatísticas dele e verifica um caminho que o build não incorporou:

```javascript
import { statSync, existsSync } from 'node:fs';

export default {
  async fetch() {
    const lines = [];
    // Check if file exists
    if (existsSync('/hello.txt')) {
      // Get file stats
      const stats = statSync('/hello.txt');
      lines.push(`File size: ${stats.size}`);
      lines.push(`Is directory: ${stats.isDirectory()}`);
      lines.push(`Is file: ${stats.isFile()}`);
    }
    lines.push(`existsSync('/missing.txt'): ${existsSync('/missing.txt')}`);
    return new Response(lines.join('\n') + '\n');
  },
};
```

Servida localmente com `azion dev`, a function retorna:

```text
$ curl http://localhost:3333/x
HTTP/1.1 200 OK
content-type: text/plain;charset=UTF-8

File size: 20
Is directory: false
Is file: true
existsSync('/missing.txt'): false
```

---

## openSync e closeSync

A função `openSync` de `node:fs` abre um arquivo.

| Parâmetro | Tipo     | Obrigatório | Descrição                                |
| --------- | -------- | ----------- | ---------------------------------------- |
| `path`    | `string` | Sim         | O caminho do arquivo.                    |
| `flags`   | `string` | Sim         | O modo de abertura, como `'r'` ou `'w'`. |
| `mode`    | —        | Não         | O modo do arquivo.                       |

Retorna o descritor de arquivo, um `number`.

A função `closeSync` de `node:fs` fecha um descritor de arquivo.

| Parâmetro | Tipo     | Obrigatório | Descrição                        |
| --------- | -------- | ----------- | -------------------------------- |
| `fd`      | `number` | Sim         | O descritor de arquivo a fechar. |

Esta function abre `/hello.txt` e fecha o descritor de arquivo dele:

```javascript
import { openSync, closeSync } from 'node:fs';

export default {
  async fetch() {
    // Open file and get file descriptor
    const fd = openSync('/hello.txt', 'r');
    // Close file descriptor
    closeSync(fd);
    return new Response(`opened and closed fd ${fd}\n`);
  },
};
```

Servida localmente com `azion dev`, a function retorna:

```text
$ curl http://localhost:3333/x
HTTP/1.1 200 OK
content-type: text/plain;charset=UTF-8

opened and closed fd 17
```

No `azion dev`, o descritor de arquivo é um que o sistema operacional atribui.

---

## Erros

Estas mensagens aparecem quando o código importa um arquivo de `@aziontech/unenv-preset` ou chama uma função de `node:fs` que o runtime local não tem.

| Mensagem                                                                                                       | Causa                                                                                                                                                                                                          | O que fazer                                                                                            |
| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `ERR_MODULE_NOT_FOUND` `Cannot find module '…/node_modules/@aziontech/unenv-preset/src/polyfills/node/crypto'` | O código importa `@aziontech/unenv-preset/polyfills/node/crypto`. O pacote não tem arquivo de polyfill de `crypto`.                                                                                            | Importe de `node:crypto` em uma function, como em [createHash e randomUUID](#createhash-e-randomuuid). |
| `TypeError: Cannot read properties of undefined (reading '__FILES__')`                                         | Um script Node.js importa `@aziontech/unenv-preset/polyfills/node/fs.js`. O arquivo lê os arquivos incorporados de um build, que um script Node.js não tem.                                                    | Importe de `node:fs` em uma function cujo build a Azion CLI faz.                                       |
| `ReferenceError: SRC_NODE_FS is not defined`                                                                   | Uma function importa `@aziontech/unenv-preset/polyfills/node/fs.js`, e o `azion dev` para na inicialização do servidor.                                                                                        | Importe de `node:fs`, como em [readFileSync](#readfilesync).                                           |
| `TypeError: (void 0) is not a function`                                                                        | Uma function chama `writeFileSync`, `mkdirSync` ou `readSync` de `node:fs` no `azion dev`. O build avisa que o import `will always be undefined because there is no matching export in "internal-env-dev:fs"`. | Leia arquivos com as chamadas desta página.                                                            |

---

## Recursos relacionados

- [Como a Azion Lib funciona](/pt-br/documentacao/devtools/azion-lib/como-funciona.md): Onde cada módulo da Azion Lib roda, no Node.js ou em uma function, e o que muda entre os dois.
- [Use APIs do Node.js com polyfills](/pt-br/documentacao/guias/desenvolvimento-de-aplicacoes/functions-e-runtime/use-polyfills.md): Crie um projeto de function, importe uma API do Node.js e execute-a localmente e após o deploy.
- [APIs do Node.js](/pt-br/documentacao/devtools/runtime/node.md): Os módulos do Node.js que o Azion Runtime resolve, com o comportamento de cada um.
- [azion.config.js](/pt-br/documentacao/devtools/cli/azion-config-js.md): As configurações `build.polyfills` e `build.memoryFS`, que definem quais polyfills e arquivos um build carrega.
