Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/privatenumber/md-vue-loader

Webpack loader for compiling Markdown to Vue
https://github.com/privatenumber/md-vue-loader

inline-demos loader markdown markdown-vue-loader markdownit md-vue-loader vue webpack webpack-loader

Last synced: about 16 hours ago
JSON representation

Webpack loader for compiling Markdown to Vue

Awesome Lists containing this project

README

        

# md-vue-loader

`md-vue-loader` is a Webpack loader to import Markdown files as Vue components.

## :raising_hand: Why?
- **🙌 Decoupled from Vue** Compatible with any version of [Vue](https://github.com/vuejs/vue) ([`vue-loader`](https://vue-loader.vuejs.org)/`vue-template-compiler`)!
- **👩‍🎨 Vue code rendering** Render Vue code-blocks to inline demos!
- **⚙️ Customizable** Configure your demo to be syntax-highlighted, or wrapped in any component!

## :rocket: Install
```bash
npm i -D md-vue-loader
```

## 🚦 Quick Setup
Add to your Webpack config:

```diff
module.exports = {
module: {
rules: [
+ {
+ test: /\.md.vue$/,
+ use: [
+ 'vue-loader',
+ 'md-vue-loader'
+ ]
+ }
]
},

/// ...
}
```

## 👨🏻‍🏫 Examples

### Inlining Vue demos
You can inline `vue` codeblocks like the following as inline-demos by enabling the `buildDemos` option.

````
```vue

Hello world!

```
````

To enable `buildDemos`, pass in options in your Webpack config:

```diff
module.exports = {
module: {
rules: [
{
test: /\.md$/,
use: [
'vue-loader',
+ {
+ loader: 'md-vue-loader',
+ options: {
+ buildDemos: true
+ }
+ }
]
}
]
},

/// ...
}
```

### Multi-file demos
Demos can be multi-file by naming code-blocks by prepending it with the filename in wrapped in underscores. You can import these code-blocks within the `doc` alias.

Name a code-block:
````
_HelloWorld.vue_
```vue


Hello World

```
````

Import the code-block from `doc/HelloWorld.vue`:
````
```vue

import HelloWorld from 'doc/HelloWorld.vue';

export default {
components: {
HelloWorld
}
}

```
````

### Wrapping demos in custom markup
You might want more control over how your demo is inlined to have it wrapped for styling, or to have the source-code next to it.

To configure the demo markup, you can pass in a function to control how the component is inlined: `function (demoTag, files)`. In the function context, you have access to `this.addComponent([...named imports], 'module-name')` to register external components.

In this example, I use [`vue-demo-collapse`](https://www.npmjs.com/package/vue-demo-collapse) to wrap my demo with an expandable container to show the demo source-code:

```diff
module.exports = {
module: {
rules: [
{
test: /\.md$/,
use: [
'vue-loader',
{
loader: 'md-vue-loader',
options: {
+ buildDemos(Tag, demoFiles) {
+ this.addComponent(['DemoCollapse', 'SrcFile'], 'vue-demo-collapse');
+
+ const listFiles = demoFiles
+ .map((file) => `${ent.encode(file.content)}`)
+ .join('');
+
+ return `
+
+ ${Tag}
+ ${listFiles}
+
+ `;
+ }
}
}
]
}
]
},

/// ...
}
```

## ⚙️ Options

- `buildDemos` (`Boolean`|`Function`)
- `Boolean` Renders Vue code-blocks as inline demos
- `Function(Tag, demoFiles)` Enable inline Vue demos and customize how they're inlined. Outputs the new template.
- `Tag` is the tag-name of the demo component. Make sure to use it in your output to output the demo.
- `demoFiles` (`Array`) contains all the source code releavnt to the demo

- `markdownItOpts` (Object): An object to configure [MarkdownIt](https://www.npmjs.com/package/markdown-it) — the Markdown compiler.

_Example:_
```js
({
// ...,
options: {
markdownItOpts: {
html: true,
linkify: true,
typographer: true
}
}
})
```

- `markdownItPlugins` (`Array`): An array of [MarkdownIt Plugins](https://www.npmjs.com/search?q=keywords:markdown-it-plugin).

_Example:_
```js
const markdownItAnchor = require('markdown-it-anchor')

// ...

module.exports = {
module: {
rules: [
{
// ...
options: {
markdownItPlugins: [
[markdownItAnchor, {
permalink: true,
permalinkBefore: true,
permalinkSymbol: ''
}]
]
}
}
]
}
}
```