npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

markdone-vue-loader

v1.0.11

Published

load vue component from md files

Downloads

9

Readme

markdone-vue-loader

webpack loader for transform markdown file to Vue Single-File Components.

If target markdown file contains Vue code and wrapped between :::demo and :::, then rendered it as children Vue component , also retain the source Vue code.

It useful for put demo code in md file when writting Vue components libary.

Note: For markdown-vue-loader has been registed, I used markdone.

Note: In this document, the Vue demo code means that code wrapped between :::demo and :::.

中文说明

Usage

  1. Installation
npm install markdone-vue-loader vue-loader
  1. Configuration webpack
// webpack.conf.js
module: {
    rules: [{
        test: /\.vue$/,
        loader: 'vue-loader'
    },{
        test: /\.js$/,
        loader: 'babel-loader?cacheDirectory',
        exclude: /node_modules/
    },{
        test: /\.md$/,
        use: [{
            loader: 'vue-loader'
        },{
            loader: 'markdone-vue-loader',
            options: {
                ...
            }
        }]
    }]
}
  1. Then your markdown files are Vue Single-File Components, the Vue demo code support all vue-loader Features as an child Vue Single-File.
  2. Download this repository and run npm install && npm run dev, to show the demo.

How it works

The following section is the internal implementation details of markdone-vue-loader, for interested readers, for easy use.

The md file first pass this loader:

  1. Use markdown-it convert md file to html.
  2. Mark the Vue demo code as <component0></component0>,<component1></component1>... with the help of markdown-it-container.
  3. Config md.renderer.rules.fence to hold the source code, use vue built-in directivev-pre skip compile.
  4. Use template wrapper up steps's result as Vue Single-File template.
  5. Append script to regist child component for vue demo code:
<script>
	import component0 from './this-markdown.md?fence&componentIndex=0';
    import component1 from './this-markdown.md?fence&componentIndex=1';
    export default {
        name: 'ComponentDoc',
        components: {
            component0: component0,
            component1: component1
        }
    };
</script>

Then, md files has been convert to Vue Single-File, and the next loader is vue-loaderimport component0 from './this-markdown.md?fence&componentIndex=0'; will resolve this md file again with some params.

The md file pass this loader second:

  1. Parse the params, fence used to distinguish whether it is the first processing , the componentIndex used to get which Vue demo code will return.
  2. Use regexp to get the real Vue demo code and return it, then hand it back to vue-loader.

At this point, the processing flow has been completed.

Convert sample

The convert sample will help to beautify the final results.

/**
 * markdone-vue-loader convert sample
 * 
 * srouce code:
 * 
 * some markdown content...
 * :::${containerName: demo} some code descriptions
 *  ``` vue
 *      vue demo code
 *  ```
 * :::
 * some markdown content...
 * 
 * ===> convert result
 * 
 * <template>
 *  <div class="${templateClass}">
 *      some markdown content ...
 *      <div class="${demoWrapperClass}">
 *           <slot name="${beforeDemoSlotName}"></slot>
 *               vue demo code render result
 *           <slot name="${afterDemoSlotName}"></slot>
 *      </div>
 *      
 *      <div class="${descClass}">
 *           <slot name="${beforeDescSlotName}"></slot>
 *               some code descriptions
 *          <slot name="${afterDescSlotName}"></slot>
 *      </div>
 *      
 *      <div class="${highlightClass}">
 *           <slot name="${beforeCodeSlotName}"></slot>
 *           <prev><code class="html" v-pre >
 *               source vue demo code
 *           </code></prev>
 *           <slot name="${afterCodeSlotName}"></slot>
 *      </div>
 *      some markdown content ...
 *  </div>
 * </template>
 */

Note: The variables wrapper ${} will be setted in loader options by yourself. The class and slot property related content do not be convert if not setted.

Loader Options

/**
 * markdone-vue-loader options
 */
interface Options {
    /**
     * As a mark of `vue demo code` 
     * @default "demo"
     */
    readonly containerName?: string;
    /**
     * the div className wrapped all markdown file
     */
    readonly templateClass?: string;
    /**
     * the div className wrapped `vue demo code` render result
     */
    readonly demoWrapperClass?: string;
    /**
     * the div className wrapped the `vue demo code` descriptions
     */
    readonly descWrapperClass?: string;
    /**
     * the div className wrapped the `vue demo code` source code
     */
    readonly highlightClass?: string;
    /**
     * the slot's name before `vue demo code` render result
     */
    readonly beforeDemoSlotName?: string;
    /**
     * the slot's name after `vue demo code` render result
     */
    readonly afterDemoSlotName?: string;
    /**
     * the slot's name before `vue demo code` descriptions
     */
    readonly beforeDescSlotName?: string;
    /**
     * the slot's name after `vue demo code` descriptions
     */
    readonly afterDescSlotName?: string;
    /**
     * the slot's name before `vue demo code` source code
     */
    readonly beforeCodeSlotName?: string;
    /**
     * the slot's name after `vue demo code` source code
     */
    readonly afterCodeSlotName?: string;
    /**
     * markdownit configuration:http://markdown-it.docschina.org/
     * @default 
     * {
     *  html: true,
        breaks: true,
        linkify: true
     * }
     */
    readonly markdownConfig?: MarkdownIt.Options;
    /**
     * custom markdownit plugins
     * @example 
     * [{
     *  plugin: require('markdown-it-anchor'),
     *  options: [{
     *      level: 2,
            slugify: slugify,
            permalink: true,
            permalinkBefore: true
     *  }]
     * }]
     * =>
     * md.use(plugin, ...options)
     * @default []
     */
    readonly plugins?: MarkdownItPluginOptions[]
}