一个仿照vite的快速生成前端项目的脚手架
前言
今天,给大家分享如何定制一个属于我们自己的脚手架,它不仅能够提供命令式的选项,还能帮我们快速生成我们想要的代码模板;废话不多说,我们开干😊
1.依赖了解
再开始之前,我们先了解几个基础的依赖,方便我们之后的开发。
commomd
: 用于解析命令行参数的模块(当我们输入指令后,它能够解析指令,并执行指令对应的逻辑)inquirer
: 提供交互式命令行界面的模块;chalk
: 用于输出带颜色的日志;ora
: 提供炫酷的loading动画;execa
: Node.js 有一个内置child_process
模块。它提供了一些方法,允许我们编写在子进程中运行命令的脚本, 这些命令可以运行安装在我们运行脚本的机器上的任何程序,execa
为child_process
模块提供了一个包装器,以便于使用。
当然还有一些nodejs内置模块,比如fs, path等,在这里就不多介绍了。
2.项目初始化
cd projects
mkdir my-cli
pnpm init
脚手架工程创建好后,我们首先创建一个bin目录,并创建一个启动文件my-cli.js;
首先们需要在文件头部添加 #!/usr/bin/env node
,用于告诉操作系统这是一个 Node.js 可执行文件。
mkdir bin
touch my-cli.js
# 打开my-cli.js文件头部添加
#!/usr/bin/env node
ok,创建好启动文件后,我们开始进入核心部分。
3.指令式的创建项目
首先我们先创建一个lib目录用于存放我们所有操作,如创建命令行和问题等。在lib下先创建一个create.js文件,作为创建脚手架的入口文件
touch create.js
在这个文件里我们首先创建一个create函数用于接收commond的create命令传进来的projectName,拿到projectName后我们要检查当前目录是否存在和该项目同名的工程,如果有重名,是否覆盖。
const inquirer = require('inquirer')
async function create(projectName) {
const cwd = process.cwd() // 获取当前运行node的目录
const projectPath = path.resolve(cwd, projectName)
// 判断是否有重名的项目,有重名是否覆盖
if(exist(projectPath)) {
const answers = await inquirer.prompt([
{
type: "confirm",
message: "Target directory exists. Do you want to replace it?",
name: "ok",
},
])
if(answers.ok) {
console.log(chalk.yellow("Deleting old project ..."))
rm(projectPath)
await create(projectName)
}
} else {
// 不重名
}
}
如果不存在重名的工程,那么我们就已该projectName重新创建一个工程。
通常一个优秀的脚手架会继续提问你,你想选用的技术栈,如当前比较流行的vue、react等,这里我们只拿vue和react做演示;当然还有更多选项我们都可以通过inquirer
,模块去完成。这里我们在lib目录下新建一个ask.js用于收集用户问题;
const { prompt } = require('inquirer')
const questions = [
{
name: 'tech_stack',
type: 'list',
message: '您是想要那个技术栈呢?',
choices: [{
name: 'Vue',
value: 'vue',
}, {
name: 'React',
value: 'react',
}]
},
]
function ask() {
return prompt(questions)
}
module.exports = ask
当我输入完技术框架选型时,我们可以根据用户技术选型和projectName去拉取对应的模板;我们须提前在github或者gitee上做好一个完整的、适合自己公司的Vue模板和react模板;然后通过execa执行node脚本命令从仓库拉去。
const answers = await ask()
const { tech_stack } = answers
let rep, templateName
if(tech_stack == 'vue') {
rep = 'https://gitee.com/xxxxxx/vue-template.git'
templateName = 'vue-template'
} else if(tech_stack) {
rep = 'https://gitee.com/xxxxx/react-template.git'
templateName = 'react-template'
}
spinner.start('get the template...')
await exec(`git`, ['clone', rep], { cwd: './' })
console.log(`✨ Creating project in ${chalk.yellow(projectPath)}`);
await exec(`mv`, [templateName, projectName])
spinner.succeed()
console.log(`🗃 进入${projectName}`)
await exec(`cd`, [`${projectName}`], {cwd: process.cwd()})
spinner.start('install dependence...')
await exec('npm', ['install'], {cwd: path.resolve(process.cwd(), projectName)})
spinner.succeed()
console.log(
`👉 Get started with the following commands:\n\n` +
chalk.cyan(` ${chalk.gray("$")} npm run dev`)
);
完成上面两部核心操作后,我们需要导出create方法,并做异常处理。
module.exports = (...args) => {
return create(...args).catch((err) => {
spinner.fail("create error");
console.error(chalk.red.dim("Error: " + err));
process.exit(1);
});
}
通过以上几步,核心部分我们已经搞定,接下来,我们还需要去启动文件加入入口,我们打开,my-cli.js
文件,加入commond指令
#!/usr/bin/env node
const { program } = require('commander');
program.version(require('../package.json').version, '-v', '版本信息').usage('<command> [options]');
program
.command('create <project-name>')
.description('create a new project')
.action((projectName) => {
require('../lib/create.js')(projectName);
});
program.parse(process.argv);
就这样一个简单且实用的脚手架就搞定。我们可以测试下:在终端执行my-cli.js,可以发现效果刚刚的
4.打包与发布
继续以往,我们还是用tsup进行打包,对于tsup不熟的同学可以自行了解。
打包
我们在my-cli
工程下创建tsup.config.js
,然后以bin/my-cli.js
为入口,dist
为出口,同时打出支持ems,和cjs的包。
打完包后,我们需要到package.json更改几个数据
"name": "my-cli",
"version": "1.0.0",
"description": "A nice and simple CLI tool",
"files": ["dist"], // 发布npm时上传的包
"main": "./dist/my-cli.js", // 使用require引用时的包
"bin": {
"starter": "./dist/my-cli.js"
},
发布
现在,我们已经完成了一个基本的前端脚手架,可以快速生成项目模板。接下来,我们可以将其发布到 npm 上,供全球开发者使用。
首先,我们需要创建一个 npm 账号。然后,在终端中使用 npm login
命令登录 npm。
接下来,我们可以使用 npm publish
命令将包发布到 npm 上。
在发布之前,我们需要注意以下几点:
- 确认包名不会与已有的包名重复。
- 确认版本号的格式为
x.y.z
,其中x
表示主版本号,y
表示次版本号,z
表示修订版本号。 - 确认包中没有包含不必要的文件,以减小包的大小。
- 确认包中没有包含私密信息,例如个人密码等。
执行发布命令:
npm publish
此命令会将dist目录下的所有文件其发布到 npm 上。发布完成后,我们可以在 npm 上搜索包名,查看已经发布的包。
5.总结
本文介绍了如何使用 Node.js 开发一个基本的前端脚手架,其主要功能是快速生成项目模板。我们使用了一些常见的 Node.js 模块,例如 inquirer
、commond
和 execa
等。通过这个例子,我们可以了解到,Node.js 是一个非常适合用于开发命令行工具的平台,其强大的生态系统和丰富的模块库为开发者提供了很多便利。
当然如果你想做一个更加复杂,比如支持更多的用户选项,如语言类型选择,项目校验规则等等,其实都是可以,我们可以在此基础上可以获取package.json文件然后更改和添加用户的选项和依赖即可。
今天就像分享到这里,欢迎大家点赞加收藏,然后实践起来😉😉😉
转载自:https://juejin.cn/post/7217386885794250813