Skip to content

Instantly share code, notes, and snippets.

@aelbore
Last active February 1, 2019 03:40
Show Gist options
  • Save aelbore/4700170b79e79c49cef55dd0af022727 to your computer and use it in GitHub Desktop.
Save aelbore/4700170b79e79c49cef55dd0af022727 to your computer and use it in GitHub Desktop.
vue file to js file
const ts = require('typescript');
const fs = require('fs');
const path =  require('path');
const prettier = require('prettier');

const { promisify } = require('util');
const { globFiles, clean, mkdirp } = require('aria-fs');

const writeFileAsync = promisify(fs.writeFile);
const readFileAsync = promisify(fs.readFile);
const copyFileAsync = promisify(fs.copyFile);

const compiler = require('vue-template-compiler');

function transformer(result) {
  return (context) => {
    const visitor = (node) => {
      if (Array.isArray(node.statements)) {
        node.statements = node.statements.map(statement => {
          if (ts.isExportAssignment(statement)) {
            const template = ts.createPropertyAssignment('template', 
              ts.createNoSubstitutionTemplateLiteral(result.template.content)
            )
            const style = ts.createPropertyAssignment('style', 
              ts.createNoSubstitutionTemplateLiteral(
                result.styles.map(style => style.content).join('\n').replace(/\n/g, '')
              )
            )
            statement.expression.properties.push(template);
            statement.expression.properties.push(style);
          }
          return statement;
        })
      }
      return ts.visitEachChild(node, (child) => visitor(child), context);
    }
    return visitor;
  }
}

(async function() {
  const files = await globFiles([ './src/**/*.vue', './src/**/*.js' ]);
  
  await clean('.tmp');
  await Promise.all(files.map(async file => {
    const destFile = file.replace('src', '.tmp').replace('.vue', '.js');
    mkdirp(path.dirname(destFile));
    if (path.extname(file) === '.js') {
      await copyFileAsync(file, destFile);
    } else {
      await readFileAsync(file, 'utf8')
        .then(content => compiler.parseComponent(content))
        .then(result => {
          return ts.transpileModule(result.script.content, {
            compilerOptions: { module: ts.ModuleKind.ES2015, target: ts.ScriptTarget.ES2018 },
            transformers: {  before: [ transformer(result) ] }
          })
        }).then(code => {
          return writeFileAsync(destFile, 
            prettier.format(code.outputText, { tabWidth: 2, parser: 'babel', proseWrap: 'preserve' })
          ) 
        })
    }
  }))
  
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment