Skip to content

Eliminação de código morto

O minificador Oxc suporta eliminar código morto. Por exemplo, remove as declarações dentro de um bloco if (false) e campos de classe privados não usados.

Esse recurso fica sempre ligado, mas você pode remover mais código habilitando algumas opções.

Recursos úteis no transformador

Além das opções abaixo, você pode usar o recurso define no transformador para substituir identificadores globais por expressões constantes e eliminar mais código morto.

Remover console

Você pode remover todas as chamadas console.* habilitando a opção dropConsole. Ela se comporta de forma parecida com a opção drop_console do Terser e com a opção drop: ['console'] do esbuild.

js
// entrada
const bar = window.bar();
console.log("foo", bar, baz());

// saída
const bar = window.bar();
js
// Exemplo
import { minify } from "oxc-minify";

const result = await minify("lib.js", code, {
  compress: {
    dropConsole: true,
  },
});

Toda a chamada é removida

Essa opção remove a expressão de chamada inteira, incluindo os argumentos. Isso é intencional: não avaliar os argumentos da chamada melhora o desempenho em tempo de execução quando eles são caros. Porém, se algum argumento tiver efeitos colaterais, a transformação mudará o comportamento. Se quiser manter os argumentos, use compress.treeshake.manualPureFunctions: ['console'].

Remover debugger

Você pode remover todas as declarações debugger com a opção dropDebugger. Ela vem habilitada por padrão. Comportamento semelhante ao drop_debugger do Terser e ao drop: ['debugger'] do esbuild.

js
// entrada
debugger;

// saída
js
// Exemplo
import { minify } from "oxc-minify";

const result = await minify("lib.js", code, {
  compress: {
    dropDebugger: true,
  },
});

Remover labels

Você pode remover todas as declarações rotuladas com os rótulos indicados usando dropLabels. Comportamento semelhante à opção dropLabels do esbuild.

js
// entrada
DEV: console.log("foo");
console.log("bar");

// saída
console.log("bar");
js
// Exemplo
import { minify } from "oxc-minify";

const result = await minify("lib.js", code, {
  compress: {
    dropLabels: ["DEV"],
  },
});

Declarações não usadas

Por padrão, todas as declarações de função, classe ou variável não usadas são removidas. Para mantê-las, use a opção unused.

js
// entrada
{
  function foo() {}
}

// saída
js
// Exemplo
import { minify } from "oxc-minify";

const result = await minify("lib.js", code, {
  compress: {
    unused: true, // ou "keep_assign"
  },
});

Manter valores da propriedade name

Por padrão, o minificador Oxc parte do princípio de que o código não depende da propriedade name de funções ou classes — o name é inferido do nome da função/classe ou do identificador da variável, e preservar o original impede reduzir o tamanho da saída.

Para preservar os valores de name, use keepNames.

js
// entrada
var bar = function foo() {};

// saída
var bar = function foo() {};
js
// Exemplo
import { minify } from "oxc-minify";

const result = await minify("lib.js", code, {
  compress: {
    keepNames: true, // atalho para { function: true, class: true }
  },
});

Opção mangle.keepNames

Se você usar mangling, pode querer também a opção mangle.keepNames.

Controlar detecção de efeitos colaterais

Há várias opções para controlar a detecção de efeitos colaterais.

Anotações puras

Por padrão, o minificador Oxc respeita anotações puras — comentários que marcam expressões que podem ser removidas com segurança se o valor de retorno não for usado. Veja a proposta de especificação em rascunho.

Isso pode ser desligado definindo compress.treeshake.annotations como false.

#__PURE__ / @__PURE__

#__PURE__ marca chamadas de função que podem ser removidas se o valor de retorno não for usado. Marca apenas a chamada em si, não cobre os argumentos.

Para marcar outras expressões ou incluir argumentos, envolva com uma IIFE e coloque #__PURE__ nela.

js
// entrada
/* #__PURE__ */ foo();
/* #__PURE__ */ new Foo();
/* #__PURE__ */ foo(bar());
/* #__PURE__ */ (() => {
  foo(bar());
})();
console.log(/* #__PURE__ */ foo());
console.log(/* #__PURE__ */ new Foo());

// saída
bar();
console.log(foo());
console.log(new Foo());

“Puro” não exige pureza estrita

Apesar do nome, a função não precisa ser “pura” no sentido de função pura (Wikipédia). Também não indica que chamadas podem ser memorizadas; não precisa ser referencialmente transparente (referential transparency — Wikipédia).

#__NO_SIDE_EFFECTS__ / @__NO_SIDE_EFFECTS__

#__NO_SIDE_EFFECTS__ marca uma declaração de função de modo que todas as chamadas podem ser removidas se o retorno não for usado — útil quando a mesma função aparece em vários pontos.

js
// entrada
/* #__NO_SIDE_EFFECTS__ */
export function foo() {}
/* #__NO_SIDE_EFFECTS__ */
export const bar = () => {};
foo();
bar();

// saída
export function foo() {}
export const bar = () => {};

Definir funções puras

Em vez de anotações por comentário, você pode marcar funções com compress.treeshake.manualPureFunctions: array de nomes. Semelhante à opção treeshake.manualPureFunctions do Rollup e pure_funcs do Terser.

js
// entrada
foo();
foo.bar();
bar();
bar.baz();
new foo();
foo``;

// saída
bar();
js
// Exemplo
import { minify } from "oxc-minify";

const result = await minify("lib.js", code, {
  compress: {
    treeshake: {
      manualPureFunctions: ["foo", "bar.baz"],
    },
  },
});

Ignorar efeitos colaterais de leitura de propriedade

Por padrão, assume-se que leituras de propriedade tenham efeitos colaterais (acesso a null, getters com efeitos). Você pode pedir ao minificador para ignorar essa possibilidade com compress.treeshake.propertyReadSideEffects: false. Semelhante à opção treeshake.propertyReadSideEffects do Rollup e pure_getters do Terser.

js
// entrada
const foo = {
  get bar() {
    console.log("effect");
    return "bar";
  },
};
foo.bar;

// saída (com `compress.treeshake.propertyReadSideEffects: false`)

Ignorar efeitos de acesso a variável global

Por padrão, assume-se que acessos a globais tenham efeitos (globais inexistentes lançam; getters globais podem ter efeito). Use compress.treeshake.unknownGlobalSideEffects: false para ignorar isso. Semelhante à opção treeshake.unknownGlobalSideEffects do Rollup.

js
// entrada
const jQuery = $;

// saída (com `compress.treeshake.propertyReadSideEffects: false`)

Ignorar efeitos de import inválido

Por padrão, assume-se que import não tem efeitos colaterais. Há efeito quando:

  • o import não pode ser resolvido
  • o nome importado não é exportado pelo módulo

Para preservar esses casos, use compress.treeshake.invalidImportSideEffects: true.

js
// entrada
import { existing } from "cannot-be-resolved";
import { missing } from "somewhere";

// saída (com `compress.treeshake.invalidImportSideEffects: true`)
import { existing } from "cannot-be-resolved";
import { missing } from "somewhere";

// saída (com `compress.treeshake.invalidImportSideEffects: false`)