russellmania
russellmania

Reputation: 749

How do I read a local Markdown file in Node?

I am using a library called react-markdown. If you know React, it's implementation is very simple.

import React from 'react';
import ReactDOM from 'react-dom';
import ReactMarkdown from 'react-markdown';

var content = '# This is a header\n\nAnd this is a paragraph';

ReactDOM.render(
  <ReactMarkdown source={content} />,
  document.getElementById('root')
);

The demo for the library only discusses creating the Markdown string as a variable, not an locally located file. The obvious thing to me to do was to use fs in Node. So I wrote the following:

import React from 'react';
import ReactDOM from 'react-dom';
import ReactMarkdown from 'react-markdown';
import * as fs from 'fs';
import content from './content/generic.md';

fs.readFile(content, (err, data) => {
  if (err) throw err;
  console.log(data);
});

Before I can provide the ReactMarkdown element with content, Webpack complains that readFile is not a function!

Specifically, it highlights the fs.readFile line and says:

TypeError: __WEBPACK_IMPORTED_MODULE_5_fs___default.a.readFile is not a function

This same error occurs if I use import {readFile } from 'fs' and it also occurs when I use fs.stat or fs.open. Isn't fs a default library for node? Should it be included in package.json for the webpack? Even if I run npm install --save fs I still can't access these functions. (P.S. I am using create-react-app)

Moreover, if I can't do this with fs, is there another method?

Upvotes: 6

Views: 17957

Answers (1)

Andrew Li
Andrew Li

Reputation: 57964

The fs module does not have a default export, and so importing it with default import syntax won't work. The fs module only exports named exports, so import all of them under the name fs like so:

import * as fs from 'fs'

This will import all the named exports as properties of one object named fs. That will allow you to do fs.readFile. Better yet, you could use named export importing to import just the function you need:

import { readFile } from 'fs'

Secondly, pass readFile a path to the Markdown file, don't import it directly with import syntax:

fs.readFile('./content/generic.md', 'utf8', (err, data) => {
    ...
});

Unless you have the correct loader to import the file, do not import it with require or import. Node will treat it as a JavaScript file and try to interpret the Markdown as JavaScript. Pass the path of the Markdown file directly to readFile. Also make sure to specify the encoding as utf8 to get the string content of the file.

Upvotes: 11

Related Questions