Agent Skillsgrowilabs/growi › build-optimization

build-optimization

GitHub

针对Next.js 16 Turbopack的构建优化指南,涵盖自定义Loader、解析别名及CSS兼容规范。

apps/app/.claude/skills/build-optimization/SKILL.md growilabs/growi

触发场景

配置Turbopack 解决构建错误 优化前端构建性能

安装

npx skills add growilabs/growi --skill build-optimization -g -y
更多选项

非标准路径

npx skills add https://github.com/growilabs/growi/tree/master/apps/app/.claude/skills/build-optimization -g -y

不安装直接使用

npx skills use growilabs/growi@build-optimization

指定 Agent (Claude Code)

npx skills add growilabs/growi --skill build-optimization -a claude-code -g -y

安装 repo 全部 skill

npx skills add growilabs/growi --all -g -y

预览 repo 内 skill

npx skills add growilabs/growi --list

SKILL.md

Frontmatter
{
    "name": "build-optimization",
    "description": "GROWI apps\/app Turbopack configuration, module optimization, and build measurement tooling. Auto-invoked when working in apps\/app.",
    "user-invocable": false
}

Build Optimization (apps/app)

Next.js Version & Bundler

  • Next.js 16 (^16.0.0) with Turbopack bundler (default)
  • Build: next build; Dev: Express server calls next({ dev }) which uses Turbopack by default
  • React stays at ^18.2.0 — Pages Router has full React 18 support in v16
  • Webpack has been fully removed (no webpack() hook, no --webpack flag)

Turbopack Configuration

Custom Loader Rules (turbopack.rules)

Rule Pattern Condition Purpose
superjson-ssr-loader *.page.ts, *.page.tsx { not: 'browser' } (server-only) Auto-wraps getServerSideProps with SuperJSON serialization
  • Loaders are registered in next.config.ts under turbopack.rules
  • condition: { not: 'browser' } restricts the loader to server-side compilation only
  • as: '*.ts' / as: '*.tsx' tells Turbopack to continue processing the transformed output as TypeScript

Resolve Aliases (turbopack.resolveAlias)

4 server-only packages + fs are aliased to ./src/lib/empty-module.ts in browser context:

Package Reason
fs Node.js built-in, not available in browser
mongoose MongoDB driver, server-only
i18next-fs-backend File-system i18n loader, server-only
core-js Server-side polyfills
  • Uses conditional { browser: './src/lib/empty-module.ts' } syntax so server-side resolution is unaffected
  • resolveAlias requires relative paths (e.g., ./src/lib/empty-module.ts), not absolute paths — absolute paths cause "server relative imports are not implemented yet" errors
  • If a new server-only package leaks into the client bundle, add it to resolveAlias with the same pattern

SuperJSON Serialization Architecture

The next-superjson SWC plugin was replaced by a custom loader:

  • Build time: superjson-ssr-loader.ts auto-wraps getServerSideProps in .page.{ts,tsx} files with withSuperJSONProps() via Turbopack rules
  • Runtime (server): withSuperJSONProps() in src/pages/utils/superjson-ssr.ts serializes props via superjson
  • Runtime (client): _app.page.tsx calls deserializeSuperJSONProps() for centralized deserialization
  • No per-page changes needed — new pages automatically get superjson serialization
  • Custom serializers registered in _app.page.tsx (ObjectId, PageRevisionWithMeta)

CSS Modules Turbopack Compatibility

:global Syntax

Turbopack only supports the function form :global(...). The block form :global { ... } is NOT supported:

// WRONG — Turbopack rejects this
.parent :global {
  .child { color: red; }
}

// CORRECT — function form
.parent {
  :global(.child) { color: red; }
}

Nested blocks must also use function form:

// WRONG
.parent :global {
  .child {
    .grandchild { }
  }
}

// CORRECT
.parent {
  :global(.child) {
    :global(.grandchild) { }
  }
}

Other Turbopack CSS Restrictions

  • Standalone :local / &:local: Not supported. Inside :global(...), properties are locally scoped by default — remove &:local wrappers
  • @extend with :global(): @extend .class fails when target is wrapped in :global(.class) — Sass doesn't match them as the same selector. Use shared selector groups (comma-separated selectors) instead
  • IE CSS hacks: *zoom:1, *display:inline, filter:alpha() cannot be parsed by Turbopack's CSS parser (lightningcss). Avoid CSS files containing these hacks

Vendor CSS Imports

Global CSS cannot be imported from files other than _app.page.tsx under Turbopack Pages Router. See the vendor-styles-components skill for the precompilation system that handles per-component vendor CSS.

Module Optimization Configuration

  • serverExternalPackages: ['handsontable'] — packages excluded from server-side bundling
  • optimizePackageImports — 11 @growi/* packages configured (expansion to third-party packages was tested and reverted — it increased dev module count)

Effective Module Reduction Techniques

Techniques that have proven effective for reducing module count, ordered by typical impact:

Technique When to Use
next/dynamic({ ssr: true }) Heavy rendering pipelines (markdown, code highlighting) that can be deferred to async chunks while preserving SSR
next/dynamic({ ssr: false }) Client-only heavy components (e.g., Mermaid diagrams, interactive editors)
Subpath imports Packages with large barrel exports (e.g., date-fns/format instead of date-fns)
Deep ESM imports Packages that re-export multiple engines via barrel (e.g., react-syntax-highlighter/dist/esm/prism-async-light)
resolveAlias Server-only packages leaking into client bundle via transitive imports
Lightweight replacements Replace large libraries used for a single feature (e.g., tinykeys instead of react-hotkeys, regex instead of validator)

Techniques That Did NOT Work

  • Expanding optimizePackageImports to third-party packages — In dev mode, this resolves individual sub-module files instead of barrel, resulting in MORE module entries. Reverted.
  • Refactoring internal barrel exports — Internal barrels (states/, features/) are small and well-scoped; refactoring had no measurable impact.

i18n HMR

I18NextHMRPlugin was removed during the Turbopack migration. Translation file changes require a manual browser refresh. The performance gain from Turbopack (faster Fast Refresh overall) outweighs the loss of i18n-specific HMR. Monitor if i18next-hmr adds Turbopack support in the future.

版本历史

  • 0dc62d2 当前 2026-08-20 19:46

同 Skill 集合

.claude/skills/detect-flaky-ci/SKILL.md
.claude/skills/essential-test-design/SKILL.md
.claude/skills/essential-test-patterns/SKILL.md
.claude/skills/investigate-flaky-test/SKILL.md
.claude/skills/kiro-debug/SKILL.md
.claude/skills/kiro-discovery/SKILL.md
.claude/skills/kiro-impl/SKILL.md
.claude/skills/kiro-review/SKILL.md
.claude/skills/kiro-spec-batch/SKILL.md
.claude/skills/kiro-spec-cleanup/SKILL.md
.claude/skills/kiro-spec-design/SKILL.md
.claude/skills/kiro-spec-init/SKILL.md
.claude/skills/kiro-spec-quick/SKILL.md
.claude/skills/kiro-spec-requirements/SKILL.md
.claude/skills/kiro-spec-tasks/SKILL.md
.claude/skills/kiro-steering-custom/SKILL.md
.claude/skills/kiro-steering/SKILL.md
.claude/skills/kiro-validate-design/SKILL.md
.claude/skills/kiro-validate-gap/SKILL.md
.claude/skills/kiro-validate-impl/SKILL.md
.claude/skills/kiro-verify-completion/SKILL.md
.claude/skills/mongoose-to-prisma/SKILL.md
apps/app/.claude/skills/app-architecture/SKILL.md
apps/app/.claude/skills/app-commands/SKILL.md
apps/app/.claude/skills/app-specific-patterns/SKILL.md
apps/app/.claude/skills/next-express-route-consistency/SKILL.md
apps/app/.claude/skills/vendor-styles-components/SKILL.md
.claude/skills/kiro-spec-status/SKILL.md
.claude/skills/suggest-path-evaluator/SKILL.md
apps/app/.claude/skills/esm-merge-coverage/SKILL.md

元信息

文件数
0
版本
b2fbe5b
Hash
14efd24a
收录时间
2026-08-20 19:46

首页 - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-09-21 16:50
浙ICP备14020137号-1