2023 年 06 月 16 日原创
0
手写命令生成 Vue 组件套件
单个项目业务量越来越大,紧急开发下很多功能点没有时间抽出做成业务组件,为了让代码文件不那么臃肿以及 vscode or IDE 打开不卡顿,因此实现该命令。
以下是源代码,如果要在自己项目中使用需要修改 srcPath 常量,这是用来指定生成套件的根目录的。
例如 generate.js 放在项目根目录,srcPath 应为:
const srcPath = resolve(__dirname, 'src')
源代码中的 generate.js 放在 YourProject/src/scripts 目录,以下是文件源代码:
/**
* 快速生成文件目录,并对 vue 进行代码分离 html|js|css
*
* create 2023/05/19 p.m.
*
* 使用方法 npm run view-generate [filename] [lang]
* @filename 在 src 下创建目录并在目录下生成 index.(vue,{js|ts},scss) 3 个文件
* @lang 业务逻辑文件后缀,即 js | ts
*
* # 用法
* npm run generate views/example
* npm run generate views/example js
*
* # 生成目录及文件
* | views
* | -- example
* | ---- index.scss
* | ---- index.ts
* | ---- index.vue
*
*/
const fs = require('fs');
const path = require('path');
let filename = process.argv[2];
const jsOrTs = process.argv[3] || 'ts';
const srcPath = __dirname.substring(0, __dirname.length - 'scripts'.length)
// 检查参数
const checkedLastString = () => {
if (!filename) {
throw new Error("缺少参数(必填),依赖该参数创建文件")
}
const lastString = filename.substring(filename.length - 1, 1);
if (lastString === '/') {
filename = filename.substring(0, filename.length - 1);
}
}
/**
* 检查文件夹是否已创建
*/
const checkedAndMkdirFolder = async (folderPath, folderNames) => {
if (!folderNames || !folderNames.length) return true;
const checkPath = path.resolve(folderPath, folderNames[0]);
const hasFolder = fs.existsSync(checkPath);
if (!hasFolder) {
fs.mkdirSync(checkPath);
}
folderNames.splice(0, 1);
checkedAndMkdirFolder(checkPath, folderNames);
}
// 生成 .vue 文件
const generateVueFile = async () => {
await checkedAndMkdirFolder(srcPath, filename.split('/'));
console.info("正在生成 .vue 文件");
const fileContent = `<template>\n<p>{{ msg }}</p>\n</template>\n\n<script ${jsOrTs === 'ts' ? 'lang="ts"' : ''}>\nimport business from './index';\nexport default business;\n</script>`;
const err = fs.writeFileSync(
path.resolve(srcPath, filename, 'index.vue'),
fileContent
);
if (err) throw new Error(err);
await generateScssFile();
}
// 生成 .scss 文件
const generateScssFile = async () => {
console.info("正在生成 .scss 文件");
const fileContent = ``;
const err = fs.writeFileSync(
path.resolve(srcPath, filename, 'index.scss'),
fileContent
);
if (err) throw new Error(err);
await generateTsFile();
}
// 生成 .ts 文件
const generateTsFile = async () => {
console.info(`正在生成 .${jsOrTs} 文件`);
const fileContent = `import { defineComponent, ref } from 'vue';
import './index.scss';
export default defineComponent({
setup (props, { emit }) {
const msg = ref("${filename}/index.vue");
return {
msg
}
}
});
`;
const err = fs.writeFileSync(
path.resolve(srcPath, filename, `index.${jsOrTs}`),
fileContent
);
if (err) throw new Error(err);
}
const generateVueComponentFiles = async () => {
checkedLastString();
await generateVueFile();
console.info("已生成文件套件并写入基础内容。");
}
generateVueComponentFiles();