第2章 夹具工程初始化与环境搭建
本章正式进入工程化环节,你将完成 Material 3 组件夹具的开发环境搭建。我们同时提供 Vite + React 和 Next.js 两种主流方案,并统一加入 TypeScript 严格模式、ESLint 代码规范以及 M3 官方依赖。最终输出一个可直接运行的验证工程,为后续所有章节的组件封装与测试夹具提供一致的基线。
2.1 构建工具选型对比
根据项目需求选择合适的构建工具。对于组件夹具库,Vite 的轻量开发服务器和极速 HMR 更适配;若夹具需要集成到现有 Next.js 项目中,则选择后者。下表列出关键差异:
| 维度 | Vite + React | Next.js 14+ |
|---|---|---|
| 启动速度 | 秒级(ESM native) | 中等(需要预编译) |
| 路由支持 | 需额外安装 react-router | 内置文件系统路由 |
| SSR/SSG | 无 | 全套服务端渲染 |
| M3 集成难度 | 直接使用 Web Components | 需关闭 SSR 或使用 dynamic import |
| 推荐场景 | 纯组件夹具库 独立演示页面 | 全栈应用 + 夹具演示 |
2.2 项目初始化(Vite 方案)
执行以下命令创建 Vite + React + TypeScript 项目:
npm create vite@latest m3-fixtures -- --template react-ts
cd m3-fixtures
npm install
若选择 Next.js:
npx create-next-app@latest m3-fixtures --typescript --eslint
cd m3-fixtures
2.3 安装 Material 3 依赖
Google 官方 M3 Web 组件库 @material/web 是唯一官方依赖。它基于 Lit 构建,可在任何框架中使用。安装命令:
npm install @material/web
同时建议安装 react 和 react-dom 的类型声明(Vite 模板已包含)。若你使用 React 封装 Web Components,无需额外适配器,直接导入组件标签即可。
💡 提示:
@material/web 包含 50+ 组件,无需逐个安装。项目中只需 import 所需组件样式或注册组件。2.4 TypeScript 严格模式配置
编辑 tsconfig.json,确保严格模式开启并添加路径别名:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"noUncheckedIndexedAccess": true,
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"jsx": "react-jsx",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"noEmit": true
},
"include": ["src"]
}
关键项说明:
- strict: true —— 开启所有严格类型检查,杜绝隐式 any。
- noUncheckedIndexedAccess —— 防止数组/对象索引未定义访问。
- paths —— 配合 Vite 的 resolve.alias,实现
@/导入。
2.5 ESLint 配置
Vite 模板已内置 eslint 与 typescript-eslint。额外安装 React Hooks 规则和 import 排序:
npm install -D eslint-plugin-react-hooks eslint-plugin-import
在项目根目录创建 eslint.config.js(Flat Config 格式):
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import reactHooks from "eslint-plugin-react-hooks";
import importPlugin from "eslint-plugin-import";
export default tseslint.config(
js.configs.recommended,
...tseslint.configs.recommended,
{
plugins: {
"react-hooks": reactHooks,
import: importPlugin,
},
rules: {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"import/order": ["warn", { alphabetize: { order: "asc" } }],
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
},
}
);
⚠️ 注意:ESLint 9+ 默认使用 Flat Config(eslint.config.js),旧版 .eslintrc 不再推荐。若使用 Next.js 14,保留项目自动生成的配置即可。
2.6 验证:渲染一个 M3 按钮
在 src/App.tsx 中导入并使用 @material/web 的按钮组件:
import "@material/web/button/filled-button.js";
import "@material/web/button/outlined-button.js";
function App() {
return (
主要操作
次要操作
);
}
export default App;
运行开发服务器:
npm run dev
浏览器中应显示两个 Material 3 按钮,带有涟漪动画和形态主题色。
2.7 环境搭建流程图
下图展示了从零到验证的完整初始化流程:
2.8 常见错误排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
npm install 卡死 | 网络代理或 registry 问题 | 设置 npm config set registry https://registry.npmmirror.com |
| TypeScript 提示 "Cannot find module '@material/web'" | 未安装或路径别名冲突 | 确认 import 路径为 @material/web/button/...,检查 node_modules 存在 |
| ESLint 报 "React Hook useXXX" 规则未定义 | 缺少 react-hooks 插件 | 安装 eslint-plugin-react-hooks 并启用 rules |
| 按钮无涟漪动画 | 未加载 Web Components polyfill | 在入口文件添加 import '@material/web/button/filled-button.js'(已包含 polyfill) |
| Next.js 报错 "document is not defined" | Web Components 在 SSR 环境下运行 | 动态加载组件:const MdButton = dynamic(() => import('@material/web/button/filled-button.js'), { ssr: false }) |
2.9 性能与稳定性建议
- 依赖锁定:使用
package-lock.json或pnpm-lock.yaml锁定版本,避免队友或 CI 环境安装不同版本导致组件行为差异。 - 按需加载:只 import 实际使用的 M3 组件 JS 文件,而非全量导入
@material/web/all.js,减少 bundle 体积。 - TypeScript 增量构建:在
tsconfig.json中开启"incremental": true加速二次编译。 - ESLint 缓存:在 lint 命令后添加
--cache,避免重复检查未变更文件。