邂逅CLI开发-woker开发过程
在前端开发过程中,我们会使用各种各样的脚手架 vue-cli、create-react-app等工具。
这些工具是怎么开发出来的?当我们输入一个命令其内部帮我们处理了哪些事情?
最近写了一个叫 woker 的小工具,记录下其开发过程。文档会分成两部分
CLI 脚手架开发过程;
woker 使用介绍;
Vue 项目模板:github.com/coderx-wape…
脚手架地址:github.com/coderx-wape…
如对你有帮助,欢迎一键三联~ 点个 star 还是要 求一下的?
开发过程
一、项目开始
-
创建空文件夹 作为我们项目的存放位置
例如:cd woker 复制代码
-
创建 package.json文件
在终端执行
npm init -y
,即可生成 package.json 文件{ "name": "woker", "version": "1.0.1", "description": "vue-cli", "main": "index.js", "bin": { "woker": "index.js" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": ["vue-cli","coderz","vue","woker"], "author": "coderz", "license": "ISC", "homepage": "https://github.com/coderx-waper/woker.git", "repository": { "type": "git", "url": "https://github.com/coderx-waper/woker.git" }, "dependencies": { "commander": "^7.2.0", "download-git-repo": "^3.0.2", "ejs": "^3.1.6", "inquirer": "^8.0.0" } } 复制代码
-
配置文件夹
最终 woker 项目中文件目录结构
├── lib | ├── config // 配置文件 │ │ └── repo_config.js | ├── core // 核心文件 │ │ ├── react // 待增加... │ │ ├── vue │ │ ├── └── action.js │ │ ├── └── create.js │ │ ├── └── help.js | ├── templates // ejs 模板文件 │ │ └── vue-component.ejs │ │ └── vue-router.ejs │ │ └── vue-store.ejs │ │ └── vue-types.ejs | ├── untils // │ │ └── terminal.js │ │ └── utils.js ├── index.js ├── package-lock.json ├── package.json ├── README.md 复制代码
二、创建命令
必须注意一点 ,这段代码必须放在 index.js 文件的最上面
#!/usr/bin/env node
复制代码
修改 package.json 文件
"bin": {
"woker": "index.js"
},
复制代码
执行 npm link
woker 才会生效
创建命令需要借助 commander
库来实现,用法可自行参考官网 commander
三、创建项目指令
program.command('create <project> [others...]')
.description('clone repo into a folder')
.action(createVueProjectAction)
复制代码
createVueProjectAction
是封装在 action.js 文件中的一个动作,在action中的创建过程:
// create a vue template action
const createVueProjectAction = async (project, others) => {
console.log(project, others)
// 1 clone project
console.log('coderz helps you clone a vue template, this requires a budget...')
await download(vuerepo, project, {
clone: true
});
// 2 npm install
const commandTerminal = process.platform === 'win32' ? 'npm.cmd' : 'npm'
await commandSpawn(commandTerminal, ['install'], {
cwd: `./${project}`
})
// 3 run serve
commandSpawn(commandTerminal, ['run', 'serve'], {
cwd: `./${project}`
})
// 4 z-vue-template install it --open
}
复制代码
这里涉及几个几个问题:
- download :可以进行 clone 的一个第三方库
download-git-repo
可自行在 npm 中查看其用法 - commandSpawn:执行终端命令的函数 可在 terminal.js 文件中找到其实现方法
- vuerepo:vue-template 模板地址,封装在 lib/config/repo-config.js 中,后续考虑可自定义模板地址,目前使用自己写的
z-vue-template
四、添加组件指令
添加指令
program.command('addcpn <name>')
.description('add vue component, eg: addcpn NavBar [-d src/components]')
.action((name) => {
addComponentAction(name, program.dest || 'src/components')
})
复制代码
- addComponentAction 逻辑
// create component action
const addComponentAction = async (name, dest) => {
// needs ejs template -> .vue
const result = await compile('vue-component.ejs', {
name,
lowerName: name.toLowerCase()
})
// write to source folder
const targetPath = path.resolve(dest || 'src/components', `${name}.vue`)
writeFile(targetPath, result)
}
复制代码
这里面存在一个问题即创建当文件夹不存的时,创建会出错,故而在调用 writeFile 中进行了文件夹的递归调用根据targetPath创建对应文件夹,其中的实现逻辑:
const mkdirSync = (dirname) => {
if (fs.existsSync(dirname)) {
return true
} else {
// 不存在,判断上一级文件夹是否存在?
if (mkdirSync(path.dirname(dirname))) {
// 存在父文件,就直接新建该文件
fs.mkdirSync(dirname)
return true
}
}
}
复制代码
添加组件需要去了解 ejs
用法,项目中已经根据需要提前写好了vue-component.ejs
模板
<template>
<div class="<%= data.lowerName %>">
<h2>{{ message }}</h2>
</div>
</template>
<script>
export default {
name: "<%= data.name %>",
components: {
},
mixins: [],
props: {
},
data: function() {
return {
message: "Hello <%= data.name %>"
}
},
created: function() {
},
mounted: function() {
},
computed: {
},
methods: {
}
}
</script>
<style scoped>
.<%= data.lowerName %> {
}
</style>
复制代码
模板ejs 编译核心:需要使用到 ejs
库
/**编译文件 */
const compile = (template, data) => {
// 获取 路径
const temp = `../templates/${template}`
const temPath = path.resolve(__dirname, temp)
return new Promise((resolve, reject) => {
ejs.renderFile(temPath, {
data
}, {}, (err, result) => {
if (err) {
reject(err)
}
resolve(result)
})
})
}
复制代码
五 、添加其他指令
添加 page指令和 store 指令同上,逻辑可以查看 woker 中的实现。这里不再累述。
六、发布到npm
在发布之前,所有指令必须测试无问题
修改package.json:添加 homepage、repository
"homepage": "https://github.com/coderx-waper/woker.git", //此处填写你的 homepage
"repository": {
"type": "git",
"url": "https://github.com/coderx-waper/woker.git" //此处填写你的 repository
},
复制代码
在命令行中登录:
npm login //根据提示输入信息即可
复制代码
发布到npm registry中
npm publish
复制代码
woker使用介绍
-
woker 是什么?
Front-end scaffolding, currently supports vue
-
后续打算?
支持 支持 react template
如何安装?
npm install -g woker
复制代码
创建项目
目前woker
仅支持vue,cli已经帮你配置了
- 常用的目录结构
- axios
- vue-router
- vuex
- vue.config.js
创建项目
woker create <project>[^project]: 你的项目名称 例如: woker create demo
复制代码
自动拉取z-vue-template项目模板,自动打开 http://localhost:8080/
、启动项目
创建组件
woker addcpn <component>[^component]: 你的组件名称 例如: woker addcpn HelloWold
复制代码
创建页面
创建页面过程中会自动配置路由
woker addpage <profile>[^profile]: 你的页面名称 例如: woker addpage profile
复制代码