从零开始搭建前端脚手架(五)-- [动态添加项目配置]
一、前言
本篇文章主要讲述前端脚手架如何通过用户选择结果,动态给项目模板添加配置项,如让用户选择使用哪种UI框架、配置项目作者、是否私有等。
本文使用的node版本为16.15.1
二、实现方案
实现动态添加配置项,主要使用插件为ejs
。中文文档地址
简介:EJS 是一套简单的模板语言,帮你利用普通的 JavaScript 代码生成 HTML 页面。EJS 没有如何组织内容的教条;也没有再造一套迭代和控制流语法;有的只是普通的 JavaScript 代码而已。
- 将项目模板通过ejs设置为可配模板
- 脚手架设置相应的项目配置交互命令
- 通过ejs编译输入最终结果
1.实现项目模板的设置
咱们先来讲,给项目名称、作者、是否私有这几个字段设置可配置的。如图所示
我们最终要实现的是让用户通过选择,配置对应的UI框架。
vue项目加载UI框架,需要在入口文件main.js
中配置
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
并且在package.json
中,添加对应的依赖项
"dependencies": {
"element-ui": "^2.15.10",
},
以上是我们常规通过命令去安装和引入之后的效果,但是我们想让用户通过脚手架在命令行的交互中选择安装哪一个UI框架。所以我们需要将其提前用ejs
语法配置好,如下所示通过判断显示引入哪个
// main.js
<%_ if (UI === 'element') { _%>
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
<%_ } _%>
<%_ if (UI === 'iview') { _%>
import ViewUI from 'view-design'
import 'view-design/dist/styles/iview.css'
Vue.use(ViewUI);
<%_ } _%>
// package.json
"dependencies": {
<%_ if (UI === 'element') { _%>
"element-ui": "^2.15.10",
<%_ } _%>
<%_ if (UI === 'iview') { _%>
"view-design": "^4.0.0",
<%_ } _%>
},
通过用户选择UI的值,来判断加载哪一项。
这个项目模板就是用户通过脚手架下载下来的模板,我们将其中几项需要用户输入作为结果的配置,通过ejs语法配置好。
以上我们就配置好了,模板这边的动态变量值。
2.脚手架用户交互配置
这里我们需要配置新的问题项,让用户输入项目名称、作者并选择UI框架,命令代码如下
const diyQuestion = [
{
name: 'author',
message: "请输入项目作者", // 选项提示语
type: 'input'
},
{
name: 'description',
message: "请输入项目描述", // 选项提示语
type: 'input'
},
{
name: 'private',
message: "是否为私有项目", // 选项提示语
type: 'confirm'
},
{
name: 'UI',
message: "选择UI框架", // 选项提示语
type: 'list',
choices: [ // 具体的选项
{
name: "element", // 选项展示的名称
value: "element", // 用户最终选择的值
},
{
name: "iview",
value: "iview"
}
]
}
]
这里咱们作为例子,仅提供了两个UI框架可做选择。咱们为了方便做示例,就直接将配置项目相关的问题直接放到选择模板的问题中了。如下所示
// 设置让用户选择模版的问题项
const question = [
{
name: "features", // 选项名称
message: "请选择要创建的项目模板", // 选项提示语
type: "list", // 选项类型 另外还有 confirm check 等
choices: templateList
},
...diyQuestion
]
3.通过用户结果编译模板
这段代码里面的letDownload
方法就是咱们在上一篇文章中,拆出来的下载模板的对应方法。
这里就用到了ejs.render()
这个方法来编译模板了。代码如图所示
const letDownload = (projectName) => {
inquirer.prompt(question).then(res => {
let answers = Object.assign({}, res)
/*** 初始化loading图标文字 start */
const spinner = ora('模版下载中 ...')
/*** 初始化loading图标文字 end */
spinner.start()
// 获取到第一项中,用户选择的值,这里偷了个懒,大家可以根据答案和问题获取对应下载链接。
let info = question[0].choices.find(item => item.value === res.features)
const targetDir = path.join(process.cwd(), projectName)
download(`direct:${info.link}`, sourceDir, {clone: true}, (err) =>{
if (err) {
spinner.fail()
console.log(chalk.red(err))
console.log(chalk.red('获取模版失败'))
} else {
// 获取所有的用户问题答案,并以用户create名称为项目名称
let obj = {name: projectName, ...answers}
// 处理package.json对应交互变更
fs.readFile(path.join(sourceDir , 'package.json')).then(res => {
// 将buffer转成string,ejs.render()第一个参数接受string类型
let str = res.toString()
// 编译并输入结果
let html = ejs.render(str, obj)
// 重新写入对应文件
fs.writeFile(path.join(sourceDir , 'package.json'), html)
})
// 处理入口文件相关变更main.js
fs.readFile(path.join(sourceDir , '/src/main.js')).then(res => {
let str = res.toString()
let html = ejs.render(str, obj)
fs.writeFile(path.join(sourceDir , '/src/main.js'), html)
})
}
spinner.stop()
})
})
}
以上我们就完成了根据用户配置,对模板项目进行配置的目的。执行命令行air create demo9
,效果如图所示
三、后记
这样我们就实现了通过脚手架动态添加项目配置项,根据用户的选择,加载对应的模板。到这里脚手架的基本功能咱们就都实现了,当然咱们还是有很多地方不够完善,比如如何后续通过命令行添加的模板如何实现动态配置,这个就需要约定好动态生成对应的问题数据;项目是下载下来后再去修改的配置,用户可见的,这里问题咱们可以在本机的缓存中去生成项目,配置好之后再复制回来;可能还有好多我没有想到的。后续再说啦。
本篇完结! 撒花! 感谢观看! 希望能帮助到你。
转载自:https://juejin.cn/post/7148369991690092581