【vscode自定义插件】三、新建项目模板

背景

vscode的代码片段可以通过预置的代码模板快速生成一段代码,那么如果通过预置好的项目模板快速生成项目,代码片段就处理不了了。但是利用自定义插件功能可以做到。

抽离模板

保留一些固定的文件和代码,抽离出最基本的代码结构。在代码模板中,和包名一样的变量我们可以用【packageName】、【PackageName】一些特殊的字符来进行占位,后续在快速生产模板时,可以利用正则的方式来进行替换。

├── template
|   ├── api  
|   |  ├── index.ts 
|   |  ├── service.ts 
|   ├── index.html
|   ├── main.ts
|   ├── config.json
|   ├── App.vue
|   ├── store
|   |  ├── index.ts

最后将代码模板拷贝到插件工程中,我们接下来就可以编写插件的新建模板功能了。

新建模板

说是新建模板,其实就是将预置的模板拷贝到指定目录,拷贝的过程中替换上一步定义占位符即可。
定义copy文件的方法

const path = require('path')
const fs = require('fs')
const stream = require('stream')
const vscode = require('vscode')

/**
 * 复制文件夹到目标文件夹
 * @param {string} src 源目录
 * @param {string} dest 目标目录
 * @param {function} callback 回调
 */
const copyDir = (src, dest, callback) => {
  const packageName = dest.split('/').pop()
  const copy = (copySrc, copyDest) => {
    fs.readdir(copySrc, (err, list) => {
      if (err) {
        callback(err)
        return
      } else {
        list.forEach(item => {
          const ss = path.resolve(copySrc, item)
          fs.stat(ss, (err, stat) => {
            if (err) {
              callback(err)
            } else {
              const curSrc = path.resolve(copySrc, item)
              const curDest = path.resolve(copyDest, item)

              if (stat.isFile()) {
                // 文件,直接复制
                const writer = fs.createWriteStream(curDest)
                const reader = fs.createReadStream(curSrc)
                // 替换占位符
                const transform = stream.Transform({
                  highWaterMark: 2,
                  transform: function (buf, enc, next) {
                    const upperChunk = buf
                      .toString()
                      .replaceAll('[packageName]', packageName)
                      .replaceAll(
                        '[PackageName]',
                        packageName[0].toUpperCase() + packageName.substr(1)
                      )
                    next(null, upperChunk)
                  }
                })
                reader.pipe(transform).pipe(writer)
              } else if (stat.isDirectory()) {
                // 目录,进行递归
                fs.mkdirSync(curDest, { recursive: true })
                copy(curSrc, curDest)
              }
            }
          })
        })
      }
    })
  }

  fs.access(dest, err => {
    if (err) {
      // 若目标目录不存在,则创建
      fs.mkdirSync(dest, { recursive: true })
    } else {
      vscode.window.showErrorMessage('该目录已存在!')
      return
    }
    copy(src, dest)
  })
}

module.exports = copyDir

利用了node的stream流,来对内容进行处理。

插件部分代码:

  context.subscriptions.push(
    vscode.commands.registerCommand('demo.createPackage', async uri => {
      const packageName = await vscode.window.showInputBox({
        prompt: '输入项目名称',
        validateInput: input => {
          if (input.length > 0 && /^[a-zA-Z0-9]+$/.test(input)) {
            return ''
          } else {
            return '输入有效名称'
          }
        }
      })
      if (!packageName) {
        return
      }
      copyDir(path.resolve(__dirname, './template'), uri.path.slice(1) + '/' + packageName)
    })
  )

效果展示

在文件目录右键选择新建项目,输入项目名称后,自动生产对应目录,并且代码中占位符地方也替换成输入的名称。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值