1. 运行指令
在package.json添加生成组件模板指令
{
"scripts": {
...
"new": "node build/new-script.js"
},
}
在终端输入单层文件 npm run new test src/views(创建位置选填,默认src/conponents)
效果: 在创建位置生成组件名的文件夹test, test文件夹下面有 index.vue、 index.scss、 index.ts。
如果输入多层文件 如:
npm run new login/foo则会先检测conponents文件夹下是否存在login,如不存在,先创建login文件夹,然后创建foo的组件。
2. 编写生成组件模板脚本
获取终端输入的参数
process.argv 第一个参数为nodejs.exe的应用所在绝对路径,第二个参数为当前脚本所在的绝对路径,第三参数是new指令后面的参数
fs模块
fs模块用于对系统文件及目录进行读写操作,本次主要用到的fs模块的功能有:
fs.existsSync(path)检测文件夹是否存在,一个同步的API,只接受一个路径参数,当前版本异步的废弃了。
fs.mkdir(path,callback)创建文件夹,异步,两个必填参数,路径和回掉。
fs.writeFile(path,data,callback)写文件,接受三个参数,文件路径,向文件中写的数据,回掉。脚本流程
检测空文件夹 --> 创建文件夹/拼接路径 --> 组件模板写入组件
----------- new-script.js -----------
if (!process.argv[2]) {
console.error('[组件名]必填 - Please enter new component name')
process.exit(1)
}
let fs = require('fs'); // fs模块
let basePath = process.argv[3] ? (process.argv[3].slice(-1) === '/' ? process.argv[3] : (process.argv[3] + '/')) : 'src/components/'; // 组件保存路径
let path = process.argv[2].split('/'); // 文件名或文件夹/文件名
let name = path[path.length - 1]; // 文件名
/**
* 检测文件夹是否存在
* @returns
*/
function exists() {
return new Promise((resolve) => {
(async function () {
// 路径里面有空文件夹
const basePathList = basePath.split('/')
basePathList.reduce((prev,cur) => {
const newPath = prev? (prev+ '/'+ cur) : cur
if (cur && !fs.existsSync(newPath)) {
fs.mkdir(newPath, (err) => {
});
}
return newPath
},'')
// 文件名里面有空文件夹
for (let a of path) {
fs.existsSync(basePath + a) ? basePath = `${basePath}${a}/` : await mkdir(a);
}
resolve(basePath);
})()
})
}
/**
* 创建文件夹
* @param {string} a 文件夹名称
* @returns
*/
function mkdir(a) {
return new Promise((resolve, reject) => {
fs.mkdir(basePath + a, (err) => {
if (err) reject(err);
basePath = `${basePath}${a}/`
resolve(basePath);
});
})
}
// 模板内容
const files = [
{
filename: 'index.vue',
content:
`<template>
<div class="${name}">
<!--Vue模板编写区域-->
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, computed } from 'vue'
import usePage from './index'
const { } = usePage()
</script>
<style scoped lang="scss">
@import './index.scss';
</style>`
},
{
filename: 'index.ts',
content:
`import { ref, onMounted, watch, computed } from 'vue'
const usePage = () => {
return {}
}
export default usePage
`
},
{
filename: 'index.scss',
content:
`.${name} {
}`
},
]
/**
* 生成文件并写入内容
* @returns
*/
function writeFile() {
return new Promise((resolve, reject) => {
(async function () {
for (let i = 0; i < files.length; i++) {
await fs.writeFile(`${basePath}${files[i].filename}`,
files[i].content, (err) => {
if (err) reject(err)
})
}
resolve('success');
})()
})
}
/**
* 创建文件
*/
(async function newComponent() {
try {
await exists(); // 检测文件名文件夹
await writeFile(); //写入组件
}
catch (err) {
console.error(err);
}
})()