likes
comments
collection
share

从零开始搭建前端脚手架(五)-- [动态添加项目配置]

作者站长头像
站长
· 阅读数 51

一、前言

本篇文章主要讲述前端脚手架如何通过用户选择结果,动态给项目模板添加配置项,如让用户选择使用哪种UI框架、配置项目作者、是否私有等。

本文使用的node版本为16.15.1

从零开始搭建前端脚手架(五)-- [动态添加项目配置]

二、实现方案

实现动态添加配置项,主要使用插件为ejs中文文档地址

简介:EJS 是一套简单的模板语言,帮你利用普通的 JavaScript 代码生成 HTML 页面。EJS 没有如何组织内容的教条;也没有再造一套迭代和控制流语法;有的只是普通的 JavaScript 代码而已。

  1. 将项目模板通过ejs设置为可配模板
  2. 脚手架设置相应的项目配置交互命令
  3. 通过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
评论
请登录