
发布 1 个 npm 包就能拥有团队专属 umi 模板从目录结构到 umi create 验证的完整流程【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi团队新项目开工会后动作总是重演一遍跑umi create官方 app 模板生成再手动补上公司内部的 request 封装、公共组件库、eslint 预设……create-umiumi create 命令背后的 npm 包其实留了一个官方扩展点umi create --template但源码里两条模板路径行为差异很大坑基本都出在这个差异上。 create-umi 找模板的两种路径内置渲染 vs 外部解压先说结论模板只有两条路。内置的 4 个模板app / max / vue-app / plugin走BaseGenerator渲染.tpl结尾的文件会做{{{ 变量 }}}占位替换再落盘通过--template传入的外部模板则是纯粹的npm 源查最新版 → 下载 tar 包 → 解压到目标目录不做任何渲染。外部路径的核心逻辑在 packages/create-umi/src/template.ts解压就三步查${registry}/{包名}/latest拿版本号、拼出 tarball 地址、把响应流 pipe 给tar的unpack({ C: dest, strip: 1 })。strip: 1表示 tarball 根层的package/目录会被剥掉包内文件直接落在项目根目录。而 packages/create-umi/src/index.ts 里只有没传--template时才会走injectInternalTemplateFilesBaseGenerator那条路两条路互不掺和。这个差异决定了模板的写法外部模板必须写成品文件——不带变量不带 .tpl。前置条件umi CLI 和一个能发 umijs 作用域 npm 包的账号需要准备两样东西全局安装 umi 的 CLINode.js 14npm/yarn/pnpm 任一用于后续umi create验证一个可以发布到 npm 的账号且模板包名必须形如umijs/xxx-template第二点是写死在源码里的约束UmiTemplate类型就是umijs/${string}-templateunpackTemplate会把任何输入归一化成这个命名——你传mid-admin它就去拉umijs/mid-admin-template。所以模板包必须发布在umijs作用域下需要对应的发布权限例如 umijs 组织成员流程见 CONTRIBUTING.md。拿不到权限的话直接跳到文末换个思路那节看替代方案。模板包怎么搭照抄官方 app 模板的目录结构搭模板最稳的方式是把仓库里官方 app 模板的结构抄下来再裁剪对照 packages/create-umi/templates/app/官方 app 模板结构你的模板包照此组织 ├── package.json ← 官方是 package.json.tpl你这里就是包自身的 package.json ├── tsconfig.json ├── typings.d.ts └── src/ ├── layouts/index.tsx └── pages/ ├── index.tsx └── docs.tsx官方模板用.tpl后缀是因为它走渲染路径你的模板包里所有文件都直接用最终文件名。准备哪三样东西结论一个可运行的 umi 工程骨架 依赖清单 团队公共代码三样齐了就是一个有效模板。工程骨架src/pages/、src/layouts/、tsconfig.json、typings.d.ts把团队希望每个新项目都有的页面和布局写进去依赖与脚本package.json里的dependencies和scripts决定新项目装什么、怎么跑公共代码业务公共组件放src/components/请求封装放src/utils/会随解压一起进入新项目package.json 要写成成品文件模板包里最重要的文件是 package.json。因为 npm tarball 根层会被剥掉一级包自身的 package.json 就是生成出来的项目的 package.json——新项目叫什么、依赖哪个版本的 umi、启动脚本长什么样都由这一个文件决定{ name: umijs/mid-admin-template, version: 1.0.0, scripts: { dev: umi dev, build: umi build, postinstall: umi setup }, dependencies: { umi: ^4.0.0, acme/ui: ^1.2.0 } }name字段必须和发布名一致所以只能保持模板名生成的项目 package name 会临时是模板名建完项目改一下即可比在发布流程里做技巧省事。src 下的文件就是普通源码src/里的文件会被原样复制写法和普通 umi 工程完全一样。可以参照官方模板的首页写法默认导出的函数组件umi dev启动后第一个看到的就是它。 发布与验证npm publish 之后用一条 umi create 命令建项目发布模板包发布前先用npm pack --dry-run看一眼文件清单确认.git、node_modules这类本地开发文件没被打包进去然后npm publish --access public用 umi create --template 建项目CLI 会把mid-admin自动补全为umijs/mid-admin-template去下载umi create my-project --template mid-admin按交互提示选 npm 客户端和源npm 或 taobao 两个选项预期结果是生成同名项目目录内容就是你的模板包文件依赖已装好。进目录跑pnpm dev应看到你在模板里写的首页仓库里的 examples/create-umi-simple/ 是一个用 create-umi 生成的示例工程可以对照它的目录结构检查自己的模板。 解压环节要留意的 4 个坑名字对不上报Template ... not found——CLI 拉取的名字由输入归一化而来发布前先npm view umijs/mid-admin-template确认注册表里的名字拼写完全一致。文件放深了一层——项目文件放进template/子目录的话解压后新项目里也会多一层template/目录因为解压是成品不做二次处理。文件直接放包根目录。用内置模板的思维写 .tpl——外部模板不渲染文件叫x.tpl就在项目里保留x.tpl内容里的{{{ }}}原样保留为字面文本。变量替换应放在发布脚本prepublish里做而不是指望生成时做。源选错了——创建时的交互提示只有 npm 和 taobaonpmmirror两个源如果你的模板发布到了别的私有 registry这条链路根本拉不到它。需要变量渲染或交互参数换个思路渲染路径{{{ 变量 }}}替换 prompts 交互提问目前只服务仓库内置的 4 个模板——提问流程项目名、模板类型、npm 客户端、源就在 packages/create-umi/src/index.ts 里packages/utils/src/BaseGenerator/BaseGenerator.ts 则负责把 context 替换进.tpl文件。如果你的团队确实需要创建时问几个问题、按答案生成不同目录有两条现实路径把模板贡献给 umi放进packages/create-umi/templates/走官方的渲染 交互流程自己写一个 create CLI仓库的 examples/cli-custom/ 是一个自定义 CLI 的最小示例提问和生成逻辑自己定不改动 umi 的折中做法在模板包的prepublishOnly脚本里按发布时环境变量做变量替换发布出去的依然是成品生成侧无需任何额外机制。把照抄 app 模板结构 → 写好 package.json 成品 → 发布并用 umi create 验证这条链路跑通团队新建项目就都从同一个骨架出发了。生成结果和预期不一致时先按坑一节对照 4 项检查再考虑文末的替代路径。延伸阅读docs/ 是 umi 的官方文档。【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考