Skip to content

Instantly share code, notes, and snippets.

@wonderful-panda
Last active December 19, 2017 08:49
Show Gist options
  • Select an option

  • Save wonderful-panda/d4ef9d319b9ad5ed05d11c6165dad0f8 to your computer and use it in GitHub Desktop.

Select an option

Save wonderful-panda/d4ef9d319b9ad5ed05d11c6165dad0f8 to your computer and use it in GitHub Desktop.
Use prettier with Vue single file component
// Example usage:
// node ./run-prettier.js "./**/*.{json,js,ts,vue}"
//
const prettier = require("prettier");
const glob = require("glob").sync;
const fs = require("fs");
const chalk = require("chalk");
/* RegExp to capture whole tag of script/style
*
* group 1: open tag (e.g. "<script lang="ts">\n")
* group 2: tagName(script or style)
* group 3: code inside tag
* group 4: close tag (e.g. </script>)
*/
const tagPattern = /(^<(script|style).*>\r?\n)((?:.|\r\n|\n)+?)(^<\/\s*\2>)/gm;
/* RegExp to capture lang name from open tag (e.g. <script lang="ts">)
*
* group 1: quotation
* group 2: lang name
*/
const langPattern = /\slang=('|"|)([a-z0-9]+)\1/i;
function formatVueFile(filepath, content, options) {
return content.replace(
tagPattern,
(match, openTag, tagName, code, closeTag) => {
const langMatch = langPattern.exec(openTag);
let ext;
if (langMatch) {
ext = "." + langMatch[2];
} else {
ext = (tagName === "script" ? ".js" : ".css");
}
const formatted = prettier.format(code, {
...options,
filepath: filepath + ext
});
return openTag + formatted + closeTag;
}
);
}
function processFile(filepath) {
const content = fs.readFileSync(filepath).toString();
const options = prettier.resolveConfig.sync(filepath) || {};
let newContent;
if (/\.vue$/i.test(filepath)) {
newContent = formatVueFile(filepath, content, options);
} else {
newContent = prettier.format(content, { ...options, filepath });
}
if (content === newContent) {
console.log(chalk.gray(filepath));
return;
}
fs.writeFileSync(filepath, newContent);
console.log(filepath);
}
function processFiles(files) {
let hasError = false;
for (let file of files) {
try {
processFile(file);
} catch (e) {
if (e instanceof SyntaxError) {
console.error(chalk.red(file));
console.error(e.message);
hasError = true;
} else {
throw e;
}
}
}
return hasError ? -1 : 0;
}
const pattern = process.argv[2];
if (!pattern) {
console.error(chalk.red("glob pattern is not provided"));
process.exit(-1);
}
ret = processFiles(glob(pattern));
process.exit(ret);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment