Search code examples
javascriptvue.jsbabeljs

Convert single-file .vue components to JavaScript?


Is there a tool out there that can take a .vue template like this:

<template>
  <div>Hello, {{ thing }}</div>
</template>

<script>
  export default {
    data() { return { thing: 'World' }; }
  }
</script>

<style>
  div { background: red; }
</style>

And convert it into a .js file, like this:

export default {
  template: `
    <div>Hello {{ thing }}</div>
  `,
  data() {
    return {
      thing: 'World'
    }
  }
}

(Not sure what magic it'd do with the CSS, but it'd do something.)

I'm trying to use native browser modules, which work great, but I'd like to use the .vue file syntax since it offers some nice things. I'd like to avoid using a bundler like Webpack or Browserify.

I am using Babel. I have the transform-vue-jsx plugin, but that can't handle the .vue format, only converting the JSX.


Solution

  • You can utilize vue-template-compiler to parse the *.vue files and extract the relevant sections.

    I've written a node script which should do the job:

    convert.js

    const compiler = require('vue-template-compiler');
    
    let content = '';
    
    process.stdin.resume();
    
    process.stdin.on('data', buf => {
        content += buf.toString();
    });
    
    process.stdin.on('end', () => {
        const parsed = compiler.parseComponent(content);
        const template = parsed.template ? parsed.template.content : '';
        const script = parsed.script ? parsed.script.content : '';
    
        const templateEscaped = template.trim().replace(/`/g, '\\`');
        const scriptWithTemplate = script.match(/export default ?\{/)
            ? script.replace(/export default ?\{/, `$&\n\ttemplate: \`\n${templateEscaped}\`,`)
            : `${script}\n export default {\n\ttemplate: \`\n${templateEscaped}\`};`;
    
        process.stdout.write(scriptWithTemplate);
    });
    

    To convert all *.vue files to *.vue.js, run the following bash command inside the directory containing the *.vue files (assuming you're using linux or macOS):

    find . -name '*.vue' -exec bash -c 'node convert.js < "{}" > "{}.js"' \;
    

    This will result in the following conversion:

    foo.vue

    <template>
        <div>a</div>
    </template>
    
    <script>
        export default {
            name: 'foo',
        };
    </script>
    
    <style>
        /* Won't be extracted */
    </style>
    

    foo.vue.js (generated)

    export default {
        template: `
            <div>a</div>
        `,
        name: 'foo',
    };
    

    You might want to tweak the script so that it deals with extracting the styles (however you want that to be handled) and fixing up whitespace and stuff like that.