Vue component mode doesn't work on Vue 3 project due to this plugin is stuck on Vue 2 compiler; `vue-template-compiler`
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.
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.
Thanks for answering! I'll build a small repository so you can see the exact point I'm working at!
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. 🤔
Great! Thanks for your generous/quick dedications ✨ let me look into later today/tomorrow.
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. 😅
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.
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! 😄
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 />
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! 😮