vite2 + vue3 md插件,自定义块转换插件

170 阅读1分钟

md插件

市面上搜 vite + md 插件大部分会搜到以下内容

import path from 'path'
import fs from 'fs'
import marked from 'marked'

const mdToJs = str => {
  const content = JSON.stringify(marked(str))
  return `export default ${content}`
}

export function md() {
  return {
    configureServer: [ // 用于开发
      async ({ app }) => {
        app.use(async (ctx, next) => { // koa
          if (ctx.path.endsWith('.md')) {
            ctx.type = 'js'
            const filePath = path.join(process.cwd(), ctx.path)
            ctx.body = mdToJs(fs.readFileSync(filePath).toString())
          } else {
            await next()
          }
        })
      },
    ],
    transforms: [{  // 用于 rollup // 插件
      test: context => context.path.endsWith('.md'),
      transform: ({ code }) => mdToJs(code)
    }]
  }
}

可能是由于我版本原因以上代码无法使用

image.png

如果你的依赖跟我一样,或许会遇到差不多的问题 这里给一种新的写法

import path from 'path'
import fs from 'fs'
import marked from 'marked'

const mdToJs = str => {
    const content = JSON.stringify(marked(str))
    return `export default ${content}`
}

function send(body) {
    let chunk = body;
    if (chunk) {
        chunk = Buffer.from(chunk, 'utf-8');
        this.setHeader('Content-Length', chunk.length);
    }
    this.setHeader('Content-Type', 'application/javascript; charset=utf-8');
    this.statusCode = 200;
    this.end(chunk, 'utf8');
}

const handler = (req, res, string) => {
    return res.send(string)
}

export const md = {
    name: 'md',
    transform: (code, id) => {
        if (!/.md/.test(id)) return
        return mdToJs(code)
    },
    configureServer: ({app}) => {
        app.use(async (req, res, next) => {
            if (/.md/.test(req.url)) {
                // console.log(req._parsedUrl.pathname);
                const filePath = path.join(process.cwd(), req._parsedUrl.pathname)
                const string = mdToJs(fs.readFileSync(filePath).toString());
                res.send = send;
                handler(req, res, string);
            } else {
                next()
            }
        })
    },
}

原写法中的 ctx 参数已经没有了另外 thansforms 方法也需要变成 transform

自定义块转换 (vueCustomBlockTransforms)

当前版本的依赖下已经没有 vueCustomBlockTransforms 这个配置项了,还是需要通过transform 来转换

import path from 'path'
import fs from 'fs'
import {baseParse} from '@vue/compiler-core'
import marked from 'marked'

export const vueShowCode = {
    name: 'vue-show-code',
    transform: (code, id) => {
        if (!/vue&type=demo/.test(id)) {
            return
        }
        const path = id.split('?')[0]
        const file = fs.readFileSync(path).toString()
        const parsed = baseParse(file).children.find(n => n.tag === 'demo')
        const title = parsed.children[0].content
        const main = file.split(parsed.loc.source).join('').trim()
        return `export default  (Component) => {
        Component.__sourceCode = ${
            JSON.stringify(main)
        }
        Component.__sourceCodeTitle = ${JSON.stringify(title)}
      }`.trim()
    }
}

用法就不讲了,跟原来的没差别,就是代码要改一下,这样写是不是最好的,或者说可能是我哪里搞错了其实可以不用这样写,我也不大清楚,反正这个代码可以跑就是了,有懂的大手子,可以留言一下。 vite插件的原理与细节 可以看www.bilibili.com/video/BV1jb… 讲得不错