Мне нужно создать API с данными из моих файлов уценки.
У меня есть около 100 файлов уценки с такими данными в верхней части файла:
---
title: Lorem ipsum
category: component
primaryKeywords: curved horizon
secondaryKeywords: css block content seperator
---
Желаемый результат - это один файл .json со всеми данными из моего файла .md в виде объектов в массиве.
Пример:
[
{
"title": "Lorem ipsum",
"category": "component",
"primaryKeywords": "curved horizon",
"secondaryKeywords": "css block content seperator"
},
{
"title": "Lorem ipsum",
"category": "component",
"primaryKeywords": "curved horizon",
"secondaryKeywords": "css block content seperator"
},
{
"title": "Lorem ipsum",
"category": "component",
"primaryKeywords": "curved horizon",
"secondaryKeywords": "css block content seperator"
}
]
Файл JSON должен быть сгенерирован как часть моей сборки внешнего интерфейса. Я использую глоток.
Я пытался сделать что-то вроде этого:
gulp.task('search-api', function (cb) {
const fs = require('fs');
const matter = require('gray-matter');
const str = fs.readFileSync('./src/docs/01-Components/02-Layout/03-bow.md', 'utf8');
console.info(matter(str));
});
Я могу показать данные из 1 файла в консоли, делая это. Но мне нужна помощь, чтобы показать данные из всех файлов в ./src/docs/
, а затем объединить их в 1 результат и проанализировать в 1 файл JSON.
Как я могу это сделать? Вся помощь и предложения приветствуются.
В основном то, что вы хотите сделать, это
Добавить объект
цикл для каждого файла: добавьте запятую ","
Для этого вы можете использовать пакет walk
.
const fs = require('fs');
const walk = require('walk');
const matter = require('gray-matter');
const dirname = "./src/docs";
const path = require('path');
const walker = walk.walk(dirname);
let prefix = ""
const stream = fs.createWriteStream("json.json", {flags:'a'});
stream.write("[\n");
walker.on("file", (root, fileStats, next) => {
const str = fs.readFileSync(path.join(root, fileStats.name), 'utf8');
stream.write(prefix);
stream.write(JSON.stringify(matter(str),null, 4));
prefix = ","
next();
});
walker.on("errors", function (root, nodeStatsArray, next) {
next();
});
walker.on("end", function () {
stream.write("\n]");
stream.end();
});
PS: Этот код я сделал из головы, чтобы дать вам какую-то подсказку. Не стесняйтесь редактировать, если есть ошибки.
для этого вы хотите path.join
имя файла. Отредактировал ответ. @BenderBoii Отредактируйте path.join по своему усмотрению (console.info содержимое path.join для подтверждения)
Все еще не могу заставить этот пример работать. Некоторые файлы уценки находятся во вложенных папках, и по этой причине возникает ошибка. fs.js:115 throw err; ^ Error: ENOENT: no such file or directory, open 'src\docs\02-Installation-and-Usage.md'
этот файл находится в подпапке с именем 03-Code Guidelines
, поэтому правильный путь к этому файлу src\docs\03-Code Guidelines\02-Installation-and-Usage.md
Есть предложения, как это исправить?
Отредактировал ответ, используйте переменную root
. Он содержит путь к папке. Снова проверьте это с помощью консоли, регистрирующей путь
Спасибо! Заработало, удалив dirname
и используя только root
.
Я сделал это как «упражнение», используя узел, а не глоток:
const fs = require('fs');
const glob = require('glob');
const os = require('os');
const markdownFiles = glob.sync("./markdown/*.md"); // an array of files in the 'markdown' directory
let finalArray = [];
function buildJSONfile() {
let contents;
markdownFiles.forEach((nextFile) => {
contents = fs.readFileSync(nextFile, "UTF8");
// os.EOL = \r\n for windows, \n for POSIX
let grayMatter = contents.match(new RegExp(`---${os.EOL}((.*${os.EOL})*?)---`)); // get just the content between the "---"s in array[1]
// add quotes around all the keys and values and add commas between key:value pairs
let addedQuotes = grayMatter[1].replace(/^([^:]*)(:\s*)(.*)(\s*)/mg, '"$1"$2"$3",');
addedQuotes = addedQuotes.slice(0, addedQuotes.length - 1); // remove the extra comma at the end of the last value
let addedBrackets = `{${addedQuotes}}`; // add brackets around the whole thing so that we can use JSON.parse
let JSONobject = JSON.parse(addedBrackets);
finalArray.push(JSONobject);
});
// write to a file : result.json
fs.writeFileSync("./result.json", JSON.stringify(finalArray, null, '\t'), "UTF8");
};
buildJSONfile(); // comment out if using gulp
Беги с node yourFileNameHere.js
.
Вы также можете поместить его в gulpfile.js и запустить через gulp buildJSONfile
.
Довольно круто. Спасибо! Хотя я не могу приступить к работе. Я получаю: [10:50:46] TypeError: Cannot read property '1' of null at markdownFiles.forEach (D:\dna\gulpfile.js:555:33) at Array.forEach (<anonymous>) at Gulp.gulp.task (D:\dna\gulpfile.js:548:17)
Есть идеи?
Я использовал папку для файлов уценки под названием markdown
в инструкции glob.sync
. Измените это на свой путь к файлам уценки.
@Mark, я использую nuxt. Можно ли использовать ваш код с webpack?
Спасибо! Я вижу, что ты делаешь. Ваш пример не работает, я получаю:
Error: ENOENT: no such file or directory, open '03-bow.md'
но я посмотрю, смогу ли я найти решение для этого. В любом случае шаги хороши, и мне нравится подход.