说明: 当作一个简单的脚手架来使用 只分析 yarn create @vitejs/app的过程 不涉及vite的具体功能实现
1. 初始化项目
// create-app是在vite仓库下作为monorepo中的一个子项目
// 当我们执行yarn create @vitejs/app 的时候就是安装@vitejs/app
// yarn create会完成两件事情
// 1.全局安装@vitejs/app(存在就更新为最新的)
// 2.运行package.json中的bin 转发 <args>
复制代码
-
lerna init 初始化 执行yarn
-
创建子项目
- lerna create @ishopee/vite
- lerna create @ishopee/create-vite-app
- 在package.json中指明workspaces
"workspaces": [
"packages/*"
],
复制代码
-
增加license文件(npm发包使用的)
-
在create-vite-app的package.json中配置bin字段
"bin": {
"create-vite-app": "index.js",
// "cva": "index.js"
},
// 设置files
"files": [
"index.js",
"template-*"
],
复制代码
- 在create-vite-app项目中新建四个目录作为模板文件
- template-react
- template-vue
- template-react-ts
- template-vue-ts
- 安装依赖
// minimist轻量的命令行参数的工具 command
// prompts用户交互
// kolorist轻量命令行输出工具 chalk
yarn workspace @ishopee/create-vite-app add minimist prompts kolorist
复制代码
2. 10行代码实现index.js
#!/usr/bin/env node
async function init() {
// 获取用户选择的结果
let result = await prompts([]);
// 项目名和当前的路径
const root = path.join(cwd, targetDir);
// 拿到用户选择的结果 framework是选择的框架 packageName项目名 variant选择特性(ts)
const { framework, packageName, variant } = result;
// 找到对应的模版目录 如果选择的是vue+ts就对应template-vue-ts
const templateDir = path.join(__dirname, `template-${template}`);
// 写入文件
const write = (file, content) => {
// package.json
if (content) fs.writeFileSync(targetPath, content);
else copy(path.join(templateDir, file), targetPath);
};
// 读取文件
const files = fs.readdirSync(templateDir);
// 遍历files写入文件 排除package.json
for (const file of files.filter((f) => f !== "package.json")) {
write(file);
}
// ok
}
复制代码
3.发布npm包
npm publish --access public
lerna publish
复制代码
4.测试
yarn create init @ishopee/vite-app hello-world
代码地址: https://gitee.com/ishopee/vite
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END