Skip to content

死代码消除

Oxc 压缩器支持消除死代码。例如,它会移除 if (false) 块内的语句以及未使用的私有类字段。

此功能始终启用,但您可以通过启用一些选项来移除更多代码。

transformer 中的有用功能

除了以下选项外,您还可以使用 transformer 中的 define 功能将全局标识符替换为常量表达式,以移除更多死代码。

移除 Console

您可以通过启用 dropConsole 选项来移除所有 console.* 调用。此选项的行为类似于 Terserdrop_console 选项和 esbuild 的 drop: ['console'] 选项

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

// 输出
const bar = window.bar();
js
// 示例
import { minify } from "oxc-minify";

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

整个调用表达式会被移除

请注意,此选项会移除整个调用表达式,包括参数。这是有意为之的,因为如果参数计算成本高昂,移除调用参数的求值有助于提高运行时性能。但是,如果这些参数有任何副作用,此转换将改变代码的行为。如果您想保留参数,可以使用 compress.treeshake.manualPureFunctions: ['console'] 选项。

移除 Debugger

您可以通过启用 dropDebugger 选项来移除所有 debugger 语句。此选项默认启用。此选项的行为类似于 Terserdrop_debugger 选项和 esbuild 的 drop: ['debugger'] 选项

js
// 输入
debugger;

// 输出
js
// 示例
import { minify } from "oxc-minify";

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

移除标签

您可以通过启用 dropLabels 选项来移除具有指定标签的所有标签语句。此选项的行为类似于 esbuild 的 dropLabels 选项

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

// 输出
console.log("bar");
js
// 示例
import { minify } from "oxc-minify";

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

未使用的声明

默认情况下,所有未使用的函数/类/变量声明都会被移除。您可以使用 unused 选项保留它们。

js
// 输入
{
  function foo() {}
}

// 输出
js
// 示例
import { minify } from "oxc-minify";

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

保留 name 属性值

默认情况下,Oxc 压缩器假设您的代码不依赖函数/类的 name 属性。这是因为 name 属性是从函数/类名或变量名推断出来的,保留原始名称会阻止减小输出大小。

要保留 name 属性值,可以使用 keepNames 选项。

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

// 输出
var bar = function foo() {};
js
// 示例
import { minify } from "oxc-minify";

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

mangle.keepNames 选项

如果您正在使用混淆功能,可能还需要启用 mangle.keepNames 选项

控制副作用检测

有多个选项可以控制副作用检测。

纯注解

默认情况下,Oxc 压缩器会遵循纯注解。纯注解是标记表达式的注释,表示如果其返回值未被使用,可以安全地移除。详见规范提案草案

可以通过将 compress.treeshake.annotations 选项设置为 false 来禁用此功能。

#__PURE__ / @__PURE__

#__PURE__ 注解用于标记函数调用,表示如果其返回值未被使用,可以安全地移除。注意,它只标记函数调用本身,不包括其参数。

如果您想标记其他表达式或覆盖参数,可以将它们包装在 IIFE 中并在其上放置 #__PURE__ 注解。

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

// 输出
bar();
console.log(foo());
console.log(new Foo());

函数不必是纯的

尽管名称如此,函数不必是纯的(纯函数 - 维基百科)。它不表示调用可以被缓存。换句话说,函数不必是引用透明的(引用透明 - 维基百科)。

#__NO_SIDE_EFFECTS__ / @__NO_SIDE_EFFECTS__

#__NO_SIDE_EFFECTS__ 注解用于标记函数声明,表示对其的所有调用如果返回值未被使用,可以安全地移除。如果您在多个位置调用该函数,这很有用。

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

// 输出
export function foo() {}
export const bar = () => {};

定义纯函数

除了使用纯注解标记函数外,您还可以通过 compress.treeshake.manualPureFunctions 选项标记函数。此选项是函数名称数组。此功能类似于 Rollup 的 treeshake.manualPureFunctions 选项Terserpure_funcs 选项。

js
// 输入
foo();
foo.bar();
bar();
bar.baz();
new foo();
foo``;

// 输出
bar();
js
// 示例
import { minify } from "oxc-minify";

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

忽略属性读取副作用

默认情况下,Oxc 压缩器假设属性读取有副作用。这是因为访问 null 的属性会抛出错误。此外,属性可能是 getter,而 getter 可能有副作用。您可以通过将 compress.treeshake.propertyReadSideEffects 选项设置为 false 来告诉 Oxc 压缩器忽略这些可能性。此功能类似于 Rollup 的 treeshake.propertyReadSideEffects 选项Terserpure_getters 选项。

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

// 输出(启用 `compress.treeshake.propertyReadSideEffects: false` 时)

忽略全局变量访问副作用

默认情况下,Oxc 压缩器假设全局变量访问有副作用。这是因为访问不存在的全局变量会抛出错误。此外,全局变量可能是 getter,而 getter 可能有副作用。您可以通过将 compress.treeshake.unknownGlobalSideEffects 选项设置为 false 来告诉 Oxc 压缩器忽略这些可能性。此功能类似于 Rollup 的 treeshake.unknownGlobalSideEffects 选项

js
// 输入
const jQuery = $;

// 输出(启用 `compress.treeshake.propertyReadSideEffects: false` 时)

忽略无效导入语句副作用

默认情况下,Oxc 压缩器假设导入语句没有副作用。导入语句在以下情况下有副作用:

  • 导入无法解析
  • 导入名称未从被导入模块导出

如果需要保留这些副作用,可以通过将 compress.treeshake.invalidImportSideEffects 选项设置为 true 来告诉 Oxc 压缩器保留它们。

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

// 输出(启用 `compress.treeshake.invalidImportSideEffects: true` 时)
import { existing } from "cannot-be-resolved";
import { missing } from "somewhere";

// 输出(启用 `compress.treeshake.invalidImportSideEffects: false` 时)