---
name: webpack_build.aicomponent
description: 通用 Webpack 5 构建配置。提供 TypeScript + Phaser 项目的标准 webpack 打包方案，支持开发模式热更新和生产模式单文件构建。不依赖任何特定投放平台。
triggers: 需要初始化项目构建配置、配置 webpack、设置开发服务器、打包生产产物时触发。
---

# 通用 Webpack 构建配置（Generic Webpack Build）

## 说明

为 Phaser + TypeScript 试玩广告项目提供**不依赖任何平台**的标准构建方案：

- **开发模式**（`pnpm dev`）：webpack-dev-server + 热更新 + source map
- **生产模式**（`pnpm build`）：压缩打包，输出到 `dist/`

本 skill 替代 `playable_scripts_build.aicomponent`（后者绑死 `@tencent/playable-scripts`）。

## Scaffold

| 目标路径 | 来源 | 说明 |
|---------|-----|------|
| `webpack.config.js` | `ref/webpack.config.js` | Webpack 5 完整配置 |
| `package.json` (merge) | `ref/package.json` | scripts + devDependencies |

## 文件详解

### webpack.config.js

```javascript
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.ts',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
    clean: true,
  },
  resolve: {
    extensions: ['.ts', '.js', '.json'],
    alias: {
      assets: path.resolve(__dirname, 'assets'),
    },
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|jpg|jpeg|webp|svg|gif)$/,
        type: 'asset/resource',
      },
      {
        test: /\.(mp3|ogg|wav|m4a)$/,
        type: 'asset/resource',
      },
      {
        test: /\.json$/,
        type: 'json',
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],
  devServer: {
    static: './dist',
    hot: true,
    open: true,
    port: 3000,
  },
};
```

### package.json（需合并的字段）

```json
{
  "scripts": {
    "dev": "webpack serve --mode development",
    "build": "webpack --mode production"
  },
  "devDependencies": {
    "typescript": "^5.3.0",
    "webpack": "^5.90.0",
    "webpack-cli": "^5.1.0",
    "webpack-dev-server": "^5.0.0",
    "ts-loader": "^9.5.0",
    "html-webpack-plugin": "^5.6.0",
    "css-loader": "^6.10.0",
    "style-loader": "^3.3.0"
  }
}
```

## 使用方式

```bash
pnpm install     # 安装依赖
pnpm dev         # 启动开发服务器（localhost:3000，自动打开浏览器）
pnpm build       # 生产构建（输出到 dist/）
```

## 资源处理规则

| 文件类型 | Webpack 处理方式 | 代码中引用方式 |
|---------|-----------------|--------------|
| `.ts` | ts-loader 编译 | `import { Foo } from "./foo"` |
| `.css` | style-loader + css-loader | `import "./index.css"` |
| `.png/.webp/.jpg` | asset/resource（输出文件，返回 URL） | `import img from "assets/images/foo.webp"` |
| `.mp3/.ogg/.wav` | asset/resource | `import sfx from "assets/sounds/foo.mp3"` |
| `.json` | 内置 JSON 模块 | `import data from "./levels.json"` |

## alias 配置

`assets` alias 指向项目根目录的 `assets/` 文件夹：

```typescript
// 以下两种写法等价：
import car from "assets/images/car.webp";      // ✅ 使用 alias
import car from "../../assets/images/car.webp"; // ✅ 相对路径（不推荐）
```

**注意**：使用 alias 时 `tsconfig.json` 中也需要对应的 `paths` 配置：
```json
{
  "compilerOptions": {
    "paths": {
      "assets/*": ["./assets/*"]
    }
  }
}
```

## 常见问题

### Q: 开发模式修改代码后浏览器没有更新？
A: 确保 `devServer.hot: true`，且没有缓存问题。尝试强制刷新（Ctrl+Shift+R）。

### Q: 生产构建体积太大？
A: webpack production 模式默认开启 terser 压缩。如需进一步优化：
- 确认 Phaser 没有被重复打包（使用 `externals` 或 CDN）
- 检查是否有大图片被 inline（asset/resource 不 inline，已正确配置）

### Q: 如何同时支持多渠道构建？
A: 如需批量构建，参考 `builds.config.js` 模式（见 `playable_scripts_build.aicomponent`），或自行扩展 webpack 配置为多 entry/多 output。

## Imports

- `phaser.aicomponent`（配合使用：提供项目骨架文件）

## Skill Definition

```yaml
tools:
  - read_file
  - write_file
inputs:
  - source: ref/webpack.config.js
  - source: ref/package.json
outputs:
  - webpackConfig: webpack.config.js
  - buildScripts: dev / build npm scripts
  - buildDeps: webpack + ts-loader + plugins devDependencies
```

## Recipe

| 决策 | 原因 |
|------|------|
| **与引擎 skill 分离** | 构建工具链与游戏运行时无关；分离允许在不改动 phaser/threejs skill 的情况下替换构建方案 |
| **替代私有包** | 原 `@tencent/playable-scripts` 是黑盒私有包，无法在非腾讯环境使用；标准 webpack 5 可控、可调试、社区生态完整 |
| **`asset/resource` 类型** | 图片、音频文件输出为独立文件（非 inline base64），保持产物体积可控，且 URL 字符串类型与 Phaser `load.image()` API 直接兼容 |
| **单 entry 单 output** | 试玩广告以单 HTML+JS 为目标，多 entry 需求由上层管线（builds.config.js）扩展，不写入本 skill |

## Adapter

- **Role**: `buildToolchain` — Webpack 5 开发与生产构建管线
- **Provides**: `webpack.config.js` 配置、`pnpm dev`（dev server）、`pnpm build`（生产构建）、资源 alias 映射 `assets/*`
- **Requires**: 与 `phaser.aicomponent` 或 `threejs.aicomponent` 配套（提供项目骨架入口文件）
- **Consumed by**: 所有需要本地开发和构建的 Remix 项目（作为工程基座，无上游 skill 依赖）
- **Integration point**: 根目录 `webpack.config.js` + `package.json` scripts，`phaser.aicomponent` 的 `src/index.ts` 作为 webpack entry

## 替代说明

本 skill 替代 `playable_scripts_build.aicomponent`：

| 维度 | playable_scripts_build | webpack_build（本 skill） |
|------|----------------------|--------------------------|
| 构建工具 | @tencent/playable-scripts（私有包） | webpack 5（公开、标准） |
| 环境要求 | 腾讯内部 npm registry | 标准 npm/pnpm |
| 多渠道构建 | 内置 | 需自行扩展（或不需要） |
| 灵活性 | 黑盒 | 完全可控的 webpack.config.js |
| 社区支持 | 无 | webpack 社区生态 |
