在项目中有个需求,几个项目组想共用一套代码,我们抽离了一些公共模块,这些公共模块写法一致。 比如以模块名称命名文件夹,文件夹下有vue文件,有配置文件,有vuex store文件。例如:
所以想提供一个vscode插件来生成。用户输入模块名称,并选中要把此模块放置的路径,则自动生成此模块。
下面分几个步骤来完成此插件:
1. 用脚手架生成一个hello world 插件
npm install -g yo generator-code
运行 yo code 按提示操作生成hello world 插件
按F5键 调试代码, 这时会新弹窗一个vscode 窗口, 按Ctrl + Shift + p 弹出输入框,输入插件名称 hello world 运行插件,这时会弹出一个toast提示。
2. 修改脚手架生成的hello world插件
2.1 修改插件名称
脚手架生成的Hello world插件是用命令激活插件的,也就是安装完插件之后,插件并没有被激活,当我们按Ctrl + Shift + p 弹出输入框时,输入hello world时才会激活此插件。我们这个需求也适合用命令来激活,所以我们只需要把hello world 修改为自己的命令就可以了,这里修改为zj
在package.json 和 extension.js 两个文件中把hello world 替换为zj即可。
2.2 实现插件功能
根据需求实现自己的插件功能就可以了,这里我们重点说下用到的vscode 开发插件所需要的api
vscode.window.showInformationMessage
vscode.window.showErrorMessage
vscode.window.showInputBox //弹出输入框供用户输入,我们这个插件需要它来输入模块名称
vscode.window.showOpenDialog //弹窗对话框,根据传入参数,我们这个插件需要它定位到把模板代码插入的地方
源代码如下:
const vscode = require('vscode');
const path = require("path");
const fs = require("fs");
const _moduleIndexStr = `<template>
<view>
</view>
</template>
<script>
export default {
data(){
return {
}
},
method:{
}
}
</script>
<style lang="scss" scoped>
</style>
`
const _moduleConfigStr = `
//配置文件。配置此模块下的所有页面路径,以及用到的网络请求URL
const isIgnoreFolder = false // 如果设置为true,则此模块下所有页面不打包进项目
const pagesPath = [{
"path": "",
"style": {
"navigationBarTitleText": ""
}
}]
//注意, 要以模块名为前缀,防止多个模块间命名冲突
const pagesUrls = [
// {
// key: '',
// url: '',
// method: ''
// }
]
module.exports = {
pagesPath,
pagesUrls,
isIgnoreFolder
}
`
const writeFile = (path, data) => {
return new Promise((resolve, reject) => {
fs.writeFile(path, data, (error) => {
if (error) {
vscode.window.showErrorMessage('写入模块失败,内容是' + error.message);
reject(error);
return;
}
resolve('write success');
});
});
};
const virtualFileCreator = async (path, fileName) => {
await writeFile(`${path}/${fileName}.vue`, _moduleIndexStr)
await writeFile(`${path}/PagesConfig.js`, _moduleConfigStr)
const _moduleStoreStr = `
const ${fileName} = {
namespaced: true, //为了解决不同模块命名冲突的问题
state: {
},
mutations: {
},
}
export default ${fileName}
`
fs.mkdirSync(path + '/store');
await writeFile(`${path}/store/index.js`, _moduleStoreStr)
vscode.window.showInformationMessage('模块配置文件创建成功,请继续开发您的模块');
};
async function createModule(){
const _moduleName = await vscode.window.showInputBox({
password: false,
placeHolder: '请输入模块名称: ',
ignoreFocusOut:true,
prompt: '输入模块名称后,按回车键,去选择要生成模块代码的位置'
})
if(!_moduleName.length){
vscode.window.showInformationMessage('您没有输入模块名称,请重新输入');
return null
}
const folderUris = await vscode.window.showOpenDialog({
canSelectFolders: true,
canSelectFiles: false,
canSelectMany: false,
openLabel: 'Select save place',
});
if (!folderUris) {
vscode.window.showErrorMessage('请选择模块存放位置');
return null;
}
const _path = path.join(folderUris[0].path, _moduleName)
const isExistMoudle = fs.existsSync(_path)
if(isExistMoudle){
vscode.window.showErrorMessage('您输入的模块已存在,请重新输入');
return null
}
fs.mkdirSync(_path);
virtualFileCreator(_path, _moduleName)
}
module.exports = {
createModule
}