Webpack Loader for: FrontMatter (.md) -> HTML + Attributes (+ Vue component)
Clone or download
Latest commit 7f61766 Dec 31, 2018

README.md

frontmatter-markdown-loader

npm CircleCI

Webpack Loader for: FrontMatter (.md) which returns Compiled HTML + Attributes (+ Compiled object as a Vue component)

This FrontMatter markdown file something.md:

---
subject: Hello
tags:
  - tag1
  - tag2
---
# Title

message

is loaded as:

import fm from "something.md"

fm.attributes // FrontMatter attributes => { subject: "Hello", tags: ["tag1", "tag2"] }
fm.body // Markdown source => "# Title\n\nmessage\n"
fm.html // Compiled markdown as HTML => "<h1>Title</h1>\n<p>message</p>\n"

Instllation

$ npm i -D frontmatter-markdown-loader

Or

$ yarn add -D frontmatter-markdown-loader

Setup

Configure the loader for Markdown files like:

{
  test: /\.md$/,
  loader: 'frontmatter-markdown-loader'
}

Then you can get frontmatter attributes and compiled markdown 🎉

import fm from "something.md"

Options

Use your own markdown compiler

{
  test: /\.md$/,
  loader: 'frontmatter-markdown-loader'
  options: {
    markdown: (body) => {
      return compileWithYourMDCompiler(body)
    }
  }
}

As default, compiling markdown body with markdown-it with allowing HTML. So behave as same as:

const md = require('markdown-it')

...

{
  test: /\.md$/,
  loader: 'frontmatter-markdown-loader'
  options: {
    markdown: (body) => {
      return md.render(body)
    }
  }
}

Vue template

The loader could compile HTML section of files as Vue template. (Excepting code snipets as Markdown which will be compiled to <code>)

Then you need to install vue-template-compiler and vue-template-es2015-compiler to your project (These are in optional dependencies).

{
  test: /\.md$/,
  loader: 'frontmatter-markdown-loader'
  options: {
    vue: true
  }
}

By this option, the loader provides vue.component which is extendable as Vue's component

import fm from "something.md"

export default {
  extends: fm.vue.component,
  components: {
    OtherComponent // If markdown has `<other-component>` in body, will work :)
  }
}

This component renders the compiled markdown including workable OtherComponent 🎉

Or can take functions by compiled template as string `render`, `staticRenderFns` which are Vue component requires.
import fm from "something.md"

fm.vue.render //=> render function as string
fm.vue.staticRenderFns //=> List of staticRender function as string

so, you can use them in your Vue component:

import OtherComponent from "OtherComponent.vue"

export default {
  data () {
    return {
      templateRender: null
    }
  },

  components: {
    OtherComponent // If markdown has `<other-component>` in body, will work :)
  },

  render (createElement) {
    return this.templateRender ? this.templateRender() : createElement("div", "Rendering");
  },

  created () {
    this.templateRender = new Function(fm.vue.render)();
    this.$options.staticRenderFns = new Function(fm.vue.staticRenderFns)();
  }
}

Component's root element

Also you can give the class name of body html with options.vue.root.

{
  test: /\.md$/,
  loader: 'frontmatter-markdown-loader'
  options: {
    vue: {
      root: 'dynamicContent'
    }
  }
}

Inspired/Referred

Contributor

License

  • MIT Copyright Kengo Hamasaki