h2vue
Version:
Migrate Huli file structure to a single-file .vue component
140 lines (126 loc) • 5.21 kB
JavaScript
const fs = require('fs');
const path = require('path');
const promptly = require('promptly');
const shell = require("shelljs");
// Run script caller dirname
const directoryPath = path.resolve('.');
const practiceRoot = 'practice-web';
const practiceDir = directoryPath.split(practiceRoot)[0];
const practiceJSRoot = `${practiceRoot}/src/public/app/`;
const practiceJSPath = directoryPath.split(practiceJSRoot)[1];
(async () => {
// Ask for component name
const componentName = await promptly.prompt('Component? ');
// Huli format file paths
const scriptFilename = `${componentName}_component.js`;
const scriptFilepath = path.join(directoryPath, scriptFilename);
const templateFilename = `${componentName}_template.html`;
const templateFilepath = path.join(directoryPath, templateFilename);
const stylesFilename = `${componentName}_styles.scss`;
const stylesFilepath = path.join(directoryPath, stylesFilename);
try {
if (fs.existsSync(scriptFilepath) && fs.existsSync(templateFilepath)) {
// Content holders
let jsContent, htmlContent, scssContent;
const existsStyles = fs.existsSync(stylesFilepath);
// Load javascript content
console.log(`Processing ${scriptFilepath}`);
jsContent = await new Promise((resolve, reject) => {
fs.readFile(scriptFilepath, 'utf8', (err, data) => {
// Handle read error
if (err) {
console.error('Unable to read component: ' + err);
reject(err);
}
let js = data.trim();
// Remove template references
js = js.replace(/import template from (.*);\n/i,'');
js = js.replace(/ template,\n/i,'');
js = js.replace(/ template: template,\n/i,'');
// [Optional] Remove style references
if (existsStyles) {
js = js.replace(`import '${practiceJSPath}/${stylesFilename}';\n`,'');
}
resolve(js);
});
});
// Load html (template) content
console.log(`Processing ${templateFilepath}`);
htmlContent = await new Promise((resolve, reject) => {
fs.readFile(templateFilepath, 'utf8', (err, data) => {
// Handle read error
if (err) {
console.error('Unable to read template: ' + err);
reject(err);
}
const tab = ' ';
data = tab + data.trim();
resolve(data.replace(/(\n)/g,'\n' + tab));
});
});
// [Optional] Load scss (styles) content
if (existsStyles) {
console.log(`Processing ${stylesFilepath}`);
scssContent = await new Promise((resolve, reject) => {
fs.readFile(stylesFilepath, 'utf8', (err, data) => {
// Handle read error
if (err) {
console.error('Unable to read styles: ' + err);
reject(err);
}
resolve(data.trim());
});
});
}
// Compose single-file component Vue
let vue =
`<script>
${jsContent}
</script>
<template>
${htmlContent}
</template>`;
if (existsStyles) {
vue = `
${vue}
<style lang="scss">
${scssContent}
</style>`;
}
// Write single-file component Vue
const vueFilename = `${componentName}_component.vue`;
fs.writeFile(vueFilename, vue, err => {
if (err) {
console.error('Unable to write vue: ' + err);
}
});
// Apply prettier
console.log('Prettify!');
shell.exec(`prettier --config ${practiceDir}/${practiceRoot}/.prettierrc --parser vue --write ${vueFilename}`);
// Delete old files
console.log('Deleting old files');
fs.unlink(scriptFilepath, err => { if (err) throw err; });
fs.unlink(templateFilepath, err => { if (err) throw err; });
if (existsStyles) fs.unlink(stylesFilepath, err => { if (err) throw err; });
} else {
console.error('Component does not exists or is missing template');
}
} catch(err) {
console.error(err);
}
})();
// fs.readdir(directoryPath, function (err, files) {
// // Handle read error
// if (err) {
// return console.log('Unable to scan directory: ' + err);
// }
// // List all files using forEach
// files.forEach(function (file) {
// // Do whatever you want to do with the file
// console.log(file);
// });
// });
// var shell = require("shelljs");
// shell.exec("echo shell.exec works");
// shell.exec("git add -A . && git commit -a -m 'gh-pages update'");