《Cocos 游戏开发入门》附录 C:环境与离线复现速查

本附录固定《Cocos 游戏开发入门》的环境口径:Node 26.5.0 的安装与校验、npm 与 pnpm 的源切换、/tmp/cocosbook 工作目录的 package.json 与依赖清单、tsconfig / vitest / vite 三份配置全文、Node 26 的可擦除语法约束、Playwright 安装与截图脚本,以及断网时的零网络复现步骤与一分钟自检。

附录 C:环境与离线复现速查

正文里每一章的代码都假定你的环境与本书一致:Node 26.5.0、TypeScript 7.0.2、vitest 5.0.3、vite 8.3.4,外加一份真实的 Cocos Creator 3.8.8 类型声明。环境不一致时,报错会伪装成「代码写错了」,白白耗掉调试预算。这一页把所有版本、配置与命令固定下来,并给出断网时还能跑什么的核对表。

本附录里的每个版本号与每条命令都在本机实测过。标了「不可用」的写法是真实失败,不是传闻。

C.1 实测版本表

正文提到版本号时,以此表为准。

组件版本作用
Node.js26.5.0直接运行 .ts(只做类型剥离)
npm11.17.0随 Node 安装
TypeScript7.0.2tsc --noEmit 类型检查
vitest5.0.3L1 逻辑单测与假时钟
Vite8.3.4打包成单文件 bundle
Playwright1.59.1无头浏览器截图回归
@cocos/creator-types3.8.8仅类型声明,供 L2 检查
Cocos Creator3.8.8全书锁定,编辑器本机未装

关键前提:mini2d(卷一绝大部分章节)是纯 TypeScript + 浏览器原生 Canvas2D,不引入任何游戏库。cc 只出现在 L2 片段里,且只用于类型检查,不参与运行。所以即使你完全没装 Cocos Creator 编辑器,也能读完全书前 17 章并跑通全部 mini2d 代码。

C.2 Node 26.5.0 安装与校验

C.2.1 安装

macOS 上用 Homebrew:

brew install node@26

Windows 上从官网下载 26.5.0 的 LTS 安装包,或使用 fnm / nvm-windows。无论哪种方式,装完都先校验版本——版本不对,后面每一步都会以奇怪的方式失败。

C.2.2 校验

node --version        # 期望:v26.5.0
npm --version         # 期望:11.17.0

Node 26 的关键特性是原生运行 TypeScript:node file.ts 无需编译、无需 ts-node。代价是它只做类型剥离(type stripping),不做语法转换——这条约束在 C.7 详述,它是本书代码风格的直接来源。

C.3 工作目录与依赖清单

C.3.1 工作目录

全书示例统一放在 /tmp/cocosbook:

mkdir -p /tmp/cocosbook/src
cd /tmp/cocosbook

目录划分遵循 1.1 节的三层职责:src/core/(循环、时钟)、src/math/(向量、矩阵)、src/render/(唯一碰 Canvas2D 的地方)、src/input/(输入)、src/game.ts(组装)。

C.3.2 package.json

{
  "name": "mini2d",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "test": "vitest run",
    "test:watch": "vitest",
    "typecheck": "tsc --noEmit"
  },
  "devDependencies": {
    "@cocos/creator-types": "^3.8.8",
    "@playwright/test": "^1.59.1",
    "typescript": "^7.0.2",
    "vite": "^8.3.4",
    "vitest": "^5.0.3"
  }
}

"type": "module" 让整个工程走 ESM。五个依赖全部是 devDependencies——mini2d 运行时零依赖,这些工具只在开发与测试阶段出现。

C.3.3 源切换

国内网络下 npm 官方源常超时,换成镜像源:

npm config set registry https://registry.npmmirror.com
npm config get registry      # 回显确认

用 pnpm 的话同理:

pnpm config set registry https://registry.npmmirror.com

装依赖:

npm install                  # 或 pnpm install

装完 node_modules/@cocos/creator-types/engine/cc.d.ts 应当存在,体积约 3.3 MB——这是真实的 3.8.8 引擎 API 声明,本书所有 L2 符号都以它为准。

C.4 tsconfig.json 全文

{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2022", "DOM"],
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "noEmit": true,
    "skipLibCheck": true,
    "erasableSyntaxOnly": true,
    "experimentalDecorators": true,
    "types": ["@cocos/creator-types/engine"]
  },
  "include": ["src", "*.ts"]
}

三个字段值得单独说明:

  • types: ["@cocos/creator-types/engine"]:加载 engine.d.ts,其内容是一行 /// <reference path="./engine/cc.d.ts"/>,于是 declare module "cc" 生效,from 'cc' 不再报「找不到模块」。注意包名必须带 /engine 后缀,写成 @cocos/creator-types 无效。
  • skipLibCheck: true:cc.d.ts 有 3.3 MB、大量交叉类型,逐行检查既慢又会带出无关噪声;我们只关心自己写的代码是否对得上 API 签名。
  • experimentalDecorators: true:@ccclass 是实验性装饰器语法,Cocos 组件脚本的前提。
  • erasableSyntaxOnly: true:让 tsc 主动拦住不可擦除语法,把 Node 26 的运行期约束提前到检查期。

C.5 vitest.config.ts

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    include: ['src/**/*.test.ts'],
    environment: 'node',
  },
});

environment: 'node' 是刻意的:src/core/ 与 src/math/ 不碰 DOM,测试就该在纯 Node 里跑,快且无浏览器噪声。需要 DOM 的渲染测试单独走 Playwright(C.8)。

C.6 vite.config.ts

import { defineConfig } from 'vite';

export default defineConfig({
  base: './',
  build: {
    outDir: 'dist',
    target: 'es2022',
    assetsInlineLimit: 100_000_000,
    cssCodeSplit: false,
    codeSplitting: false,
  },
});

assetsInlineLimit 调到极大并关掉代码分割,是为了把 JS、CSS、图片全部内联进一个 index.html——无头浏览器载入一个本地文件即可截图,不必起服务器。base: './' 保证用相对路径引用资源。

C.7 Node 26 可擦除语法约束

Node 26 只支持类型擦除:所有 TS 代码必须只用可擦除语法——类型注解被逐字删掉后,剩下的必须是合法 JS。加转换开关(如 --experimental-transform-types)会直接报 bad option。

语法能否擦除替代写法
类型注解 x: number可以直接用
interface / type 别名可以直接用
as 断言、泛型参数可以直接用
enum不行const 对象 + as const + 联合类型
namespace不行普通模块导出
构造函数参数属性不行声明字段 + 函数体内赋值

enum 的替代写法(本书统一采用):

const GameState = {
  Loading: 'loading',
  Playing: 'playing',
  Paused: 'paused',
} as const;

type GameState = (typeof GameState)[keyof typeof GameState];

// 用法:GameState.Playing,类型仍是字面量联合,编辑器可自动补全
const s: GameState = GameState.Playing;

构造函数里不要用参数属性。下面是不可用的写法(Node 26 会抛 SyntaxError):

// 不可用:参数属性会生成运行时代码,无法被擦除
class Runner {
  constructor(public speed: number) {}
}

改成声明字段 + 函数体内赋值即可:

class Runner {
  speed: number;

  constructor(speed: number) {
    this.speed = speed;
  }
}

C.8 Playwright 安装与截图脚本

Playwright 用于 L1 的渲染端到端测试:把 mini2d 画出的画面截成 PNG 做回归。

npm install -D @playwright/test
npx playwright install chromium      # 下载浏览器内核,只需一次

一个最小截图脚本 shot.mjs(用内置 Node 直接跑):

import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 960, height: 540 } });
await page.goto('http://127.0.0.1:4173/', { waitUntil: 'networkidle' });
await page.waitForTimeout(300);
await page.screenshot({ path: 'shot.png' });
await browser.close();
npm run build
npm run preview &                    # 起本地 HTTP 服务,默认 4173
node shot.mjs

必须走 HTTP:ES module 脚本在 file:// 下会被 CORS 拦下,页面白屏(详见附录 D)。waitUntil 用 networkidle 而非 load——load 只等资源加载,不等渲染,截图容易抢在首帧之前。

C.9 零网络复现步骤

npm 的包缓存(~/.npm/_cacache)已包含上述依赖时,断网也能复现:

npm install --offline        # 只从本地缓存安装,不联网
npm run typecheck
npm run test
npm run build

把这一节当成「断网时我还能跑什么」的核对表:

依赖必需性缺了会怎样
Node 26.5.0必需.ts 无法直接运行,可擦除语法约束也无从谈起
TypeScript 7.0.2必需无法做 L2 类型检查
@cocos/creator-types@3.8.8必需from 'cc' 报「找不到模块」
vitest 5.0.3推荐逻辑单测跑不了,但示例脚本仍可 node 直跑
vite 8.3.4推荐无法打包成单文件 bundle
Playwright + chromium可选只影响第 16 章的截图回归
Cocos Creator 3.8 编辑器可选只影响 L3 工程文件的查看,不影响本书任何可运行代码

断网也能跑完前 17 章:mini2d 零运行时依赖,测试零网络,截图只需本地 HTTP。只有 L3 的编辑器查看需要 GUI,而它本就不在命令行复现范围内。

C.10 一分钟自检

node --version                                   # v26.5.0
npx tsc --version                                # Version 7.0.2
npm run typecheck                                # 无输出即通过(cc 类型已接通)
npm run test                                     # 冒烟测试 1 passed
ls node_modules/@cocos/creator-types/engine/cc.d.ts   # 存在,约 3.3 MB

五条都过,说明你的环境与本书一致。任何一条失败,先回到 C.2 的 Node 校验、C.3 的依赖清单、C.4 的 types 数组,或 C.7 的可擦除语法排查。环境问题不该占用你的调试预算——真正要花时间的是引擎机制本身。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「cocos」更多文章

  1. 《Cocos 游戏联机实战》9.3 延迟补偿与体验权衡
  2. 《Cocos 游戏联机实战》9.2 网络状态 UI 与提示
  3. 《Cocos 游戏联机实战》9.1 同步表现与插值动画