loading...

Working with Pug and Markdown in Vue-CLI

patarapolw profile image Pacharapol Withayasakpunt ・2 min read

Using Pug is as simple as npm i pug-plain-loader pug, and it will modify the Webpack config for you.

Using Markdown is a little harder. Usually, you might use markdown-loader (or frontmatter-markdown-loader), but what I suggest is you can inline Markdown in Pug (and can inline Pug in Markdown as well, as I ranted here.)

You can do it using Pug filters, but you will also have to modify pug-plain-loader config. Inspect first.

$ vue inspect # or vue inspect > webpack.config.js

Now, look for pug-plain-loader. And tap the webpack config in vue.config.js accordingly

My solution is this,

const dotProp = require('dot-prop')
const showdown = require('showdown')
const mdConverter = new showdown.Converter({
  simpleLineBreaks: true
})

module.exports = {
  chainWebpack: (config) => {
    config.module.rule('pug').oneOf('raw-pug-files').use('pug-plain').loader('pug-plain-loader')
      .tap((options) => {
        options = options || {}
        dotProp.set(options, 'filters.markdown', (s) => {
          return mdConverter.makeHtml(s)
        })
        return options
      })

    config.module.rule('pug').oneOf('vue-loader').use('pug-plain').loader('pug-plain-loader')
      .tap((options) => {
        options = options || {}
        dotProp.set(options, 'filters.markdown', (s) => {
          return mdConverter.makeHtml(s)
        })
        return options
      })
  }
}

options is actually undefined, BTW. For dot-prop, I use it so as not to override any config unnecessarily.

Now, vue inspect again, to double check your solution.

Now, you can use Markdown in Pug.

<template lang="pug">
.columns
  .column.is-8-desktop.is-offset-2-desktop
    .content
      :markdown
        # hello
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'

@Component
export default class Home extends Vue {}
</script>

Bonus

As I work with TypeScript and Vue a lot, and the default TypeScript Vue snippet (as in Vetur) is not what I wanted, so I created a new snippet.

Find User Snippet in Preferences, and click it.

User Snippet VS Code

Find Vue.

My vue.json is as follows.

{
    "ts-property": {
        "prefix": "ts",
        "body": [
            "<script lang=\"ts\">",
            "import { Vue, Component } from 'vue-property-decorator'",
            "",
            "@Component",
            "export default class ${0:App} extends Vue {}",
            "</script>",
            ""
        ]
    }
}

Posted on by:

patarapolw profile

Pacharapol Withayasakpunt

@patarapolw

Currently interested in TypeScript, Vue, Kotlin and Python. Looking forward to learning DevOps, though.

Discussion

markdown guide