hmsk / frontmatter-markdown-loader

📝 Webpack Loader for: FrontMatter (.md) -> HTML + Attributes (+ React/Vue Component)
https://hmsk.github.io/frontmatter-markdown-loader/
MIT License
255 stars 18 forks source link

Vue component mode doesn't work on Vue 3 project due to this plugin is stuck on Vue 2 compiler; `vue-template-compiler` #238

Open yuigoto opened 3 years ago

yuigoto commented 3 years ago

Hi!

I'm building a custom Webpack-based Vue project in here using vue-loader, for an educational project I'm working on. But I'm having issues with this library. I've used it the same way I did with a React project of the same nature:

config.plugins = [
  // ... other plugins here
  {
    test: /\.vue$/,
    use: "vue-loader",
  },

  {
    test: /\.md$/,
    loader: "frontmatter-markdown-loader",
    options: {
      mode: [
        mode.VUE_COMPONENT
      ],
      vue: {
        root: "markdown-content",
      },
    },
  },
  // ... other plugins here
];

config.plugins = [
  new VueLoaderPlugin(),
];

But I've had this issue, importing a Markdown file:

ERROR in ./src/views/Main.vue
Module build failed (from ./node_modules/frontmatter-markdown-loader/index.js):
Error: Failed to import vue-template-compiler or/and @vue/component-compiler-utils:
If you intend to use 'vue-component', `vue-render-functions` mode, install both to your project:
https://hmsk.github.io/frontmatter-markdown-loader/vue.html 
    at Object.module.exports (F:\Git\GitHub\vue-webpack-base\node_modules\frontmatter-markdown-loader\index.js:73:13)
 @ ./src/index.js 2:0-34 6:22-26

I've also tried using the loader like this, for MD files, to no success:

config.plugins = [
  // ... other plugins here
  {
    test: /\.md$/,
    use: [
      "vue-loader",
      {
        loader: "frontmatter-markdown-loader",
        options: {
          mode: [
            mode.VUE_COMPONENT
          ],
          vue: {
            root: "markdown-content",
          },
        },
      },
    ],
  },
  // ... other plugins here
];

I'm currently using Vue @ 3.1.4, with @vue/compiler-sfc (^3.1.4) and @vue/component-compiler-utils (^3.2.2), and I tried installing vue-template-compiler, but I'm stuck with this error.

I'm wondering if I'm doing something wrong, or loading it the wrong way, or if I should explicitly declare vue-loader to use @vue/compiler-sfc.

hmsk commented 3 years ago

Thanks for your feedback! It'd be great if you provide a minimum reproducible repository to confirm the exact trouble. I never tried this plugin with Vue 3 project so might see unintentional behavior with newer compilers.

yuigoto commented 3 years ago

Thanks for answering! I'll build a small repository so you can see the exact point I'm working at!

yuigoto commented 3 years ago

Here's a repository mirroring exactly what I'm working on: https://github.com/yuigoto/vue-webpack-example

I did the same with React and it went fine (html, body, meta, component), but with Vue I get stuck with the component. 🤔

hmsk commented 3 years ago

Great! Thanks for your generous/quick dedications ✨ let me look into later today/tomorrow.

yuigoto commented 3 years ago

Nice! Will keep trying stuff and see if more warnings appear.

For now, I'll stick with the stringified HTML output and keep testing. I was mostly worried because I wondered what did I do wrong. 😅

hmsk commented 3 years ago

Alright, I confirmed vue-template-compiler is only for Vue 2 and this plugin doesn't work with Vue 3 project.

The error message you caught was inappropriate, that was suppressing the original error by Vue compiler. So I hastened to release v3.6.3 to show up the message.

I'm going to work on supporting Vue in some point but not so prioritized since Vue 3 is still in pre-release state so far. I will let you know on this issue when it's supported.

yuigoto commented 3 years ago

All right, thanks! 😉

I totally understand that, will see if Vue 2 works for what I've in mind as of now. Though I'm pretty happy with the rendered body string so far, so it's not that much of an issue. 😅

Will keep an eye on it, and see if I can contribute somehow after I finish some tasks I've got in here! 😄

mdwheele commented 3 years ago

Hello @yuigoto @hmsk!

We're upgrading our applications to Vue 3 and I stumbled across this issue. For what it's worth, we decided (for now) to change to Mode.HTML and use the defineComponent API in Vue 3 to achieve wrapping Markdown content in a Vue component as the rest of our application expects. I'd be happy to help work on a patch for frontmatter-markdown-loader that's portable between Vue 2 and 3 if you'd like.

In the meantime, this is what worked for us (using the vue-cli sample application as a baseline):

src/App.vue

<template>
  <div>
    <component :is="component" />
  </div>
</template>

<script>
import { defineComponent, shallowRef } from 'vue'
import fm from './index.md'
import HelloWorld from './components/HelloWorld.vue'

const component = defineComponent({
  name: 'FrontmatterMarkdownShim',
  template: fm.html,

  // We can allow custom components in Markdown like so...
  components: { HelloWorld }
})

export default {
  name: 'App',
  data() {
    return {
      component: shallowRef(component)
    }
  }
}
</script>

src/index.md

---
title: Hello, World
published: true
---

# frontmatter-markdown-loader

<HelloWorld />
yuigoto commented 3 years ago

Ooh! Nice! Will try this solution later! Been doing some stuff at work with other frameworks a didn't have the time to properly tinker with Vue lately. 😞

Gotta get into it asap! 😮