如何为 next.js 启用树摇动?

Jon*_*sen 15 webpack tree-shaking next.js

是否有一些东西可以让 next.js 执行树摇动/从依赖项中删除死代码?我已经导出了两个这样的对象:

library.js

export const foo = {foo:"foo"}
export const bar = {bar:"bar"}
Run Code Online (Sandbox Code Playgroud)

在我的 next.js 应用程序中,我喜欢这样:

page.tsx

import { foo } from 'library';
console.log(foo);
Run Code Online (Sandbox Code Playgroud)

所以现在我预计生产构建将包含bar,并且确实有些事情似乎是正确的,因为生成了这一行:

.next/server/chunks/621.js

/* unused harmony exports bar */
Run Code Online (Sandbox Code Playgroud)

但令人困惑的是,当我在浏览器中加载应用程序时,网络流量表明包含未使用的导出

http://localhost:3001/_next/static/chunks/pages/page-0b2b13a7513f2849d855.js

(self.webpackChunk_N_E = self.webpackChunk_N_E || []).push([[3031], {
    80621: function(e, r, n) {
        "use strict";
        ...
        const l = a.object({
            foo: "foo"
        });
        a.object({
            bar: "bar"
        });
    },
Run Code Online (Sandbox Code Playgroud)

为什么构建会识别未使用的导出,但不会将它们从传输到浏览器的有效负载中删除?Next 是否有一个设置希望我们启用?某种后处理实际上会修剪未使用的导出?

Tan*_*kom 0

我相信您的示例的问题在于 Next.js 能够对原始值(布尔值、字符串、int 等)和具有原始值的对象/数组进行 tree-shake。

但是,Next.js 中使用的捆绑器 webpack 无法识别函数调用是否有任何副作用。

从这个Github Issue #12557中,一些用户报告说,设置"sideEffects:false甚至package.json修改 webpack 解决next.config.js了这个问题。

这些都不适合我。/*#__PURE__*/相反,使用注释将函数标记为无副作用是有效的。

例子:

const createApi = (message) => {
  console.log(message);
  return () =>{}
}

export const serverApi = /*#__PURE__*/ createApi("I should only be available server side.")

export const clientApi = /*#__PURE__*/ createApi("I should only be available client side.")
Run Code Online (Sandbox Code Playgroud)

像上面这样编写我的代码会导致serverApi无法包含在客户端捆绑包中。

应该注意的是,注释的语法是/*#__PURE__*/ fn(). 所有其他用途都将不起作用。