简体   繁体   中英

import .md file error to render vue template

I base on Meteor + Vue . I try to import .md file to render vue template .

<template>
       <VueMarkshow :source="mdFile"></VueMarkshow>
</template>
<script>
import Vue from 'vue'
import VueMarkshow from 'vue-markdown'

import mdFile from './README.md'
export default {
  name: 'VueMarkdown',
  components:{VueMarkshow},
}
</script>

But it get error :

 [Vue warn]: Failed to resolve async component: function () {
    return module.dynamicImport('./Vue-Markdown.vue');
  }
Reason: Error: Cannot find module './README.md'

There are two solutions:

Do no use Meteor for building

This solution has two steps:

1) Replace Meteor building system by webpack

https://medium.com/the-guild/meteor-with-webpack-in-2018-faster-compilation-better-source-handling-benefit-from-bc5ccc5735ef

2) Use loader for markdown for webpack

https://www.npmjs.com/package/markdown-loader

Load markdown file on backend

This is simpler to achieve and I have sample of my code:

1) On front I display computed html from markdown

              <div v-html="compiledMarkdown"></div>

2) I have defined computed property:

  computed: {
    compiledMarkdown: function() {
      return marked(this.DOC_CONTENT, { sanitize: true });
    },
  },

When marked is library that convert markdown to html

import marked from "marked";

3) My DOC_CONTENT is loaded from backend:

  created() {
    Meteor.call("get_docs", (err, res) => {
      this.DOC_CONTENT = res;
    });
  },

4) On backend there is defined method

Meteor.methods({
  'get_docs'() {
    return Assets.getText("CHANGELOG.md");
  }
})

5) And my file CHANGELOG.md is located in /private folder in root of meteor project.

/private/CHANGELOG.md

You can't import an ordinary file like this:

import mdFile from './README.md'

because import is only for javascript code. - So we need to read the file in some other way.

It is not particularly easy to read files from client javascript code. You can use FileReader, which is HTML5 stuff, but you can't ask to read a file directly - for security reasons you have to first ask for the file from a file <input> .

However you can read a file from your /public folder. So if your README.md is in your /public folder you can do an ajax request as follows:

       var client = new XMLHttpRequest();
       client.open('GET', '/README.md');
       let self = this;
       client.onreadystatechange = function() {
           self.mdFile = client.responseText;
       }
       client.send();

Then you need a variable (I've called it mdFile ) to hold the string result of the ajax call in your data() function, which we will then place in the ' source ' parameter of vue-markdown .

Here is the complete code, which I have tested, and it works:

<template name="appLayout">

    <div>
        <vue-markdown :source="mdFile"></vue-markdown>
    </div>
</template>

<script>

    import {Meteor} from 'meteor/meteor';
    import VueMarkdown from 'vue-markdown';

   export default {
       data() {
           return {
               mdFile: '',
           };
       },
       components: {
           VueMarkdown
       },
       created() {
           var client = new XMLHttpRequest();
           client.open('GET', '/README.md');
           let self = this;
           client.onreadystatechange = function() {
               self.mdFile = client.responseText;
           }
           client.send();
       },
   }


</script>

Please note that vue-markdown has some kind of weird problem with babel, and there's an old bug still open in github. I found that I had to install babel-runtime twice:

meteor npm install --save @babel/runtime
meteor npm install --save babel-runtime 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM