生成vuepress 菜单

lishihuan大约 2 分钟

生成vuepress 菜单

目录结构生成

执行node add_vuepress_menu.js

add_vuepress_menu.js 代码如下

const fs = require('fs');
const path = require('path');

function generateMenus(dirPath, prefix = '') {
  const files = fs.readdirSync(dirPath);
  const menus = [];

  files.forEach((file) => {
    const filePath = path.join(dirPath, file);
    const isDirectory = fs.statSync(filePath).isDirectory();

    if (isDirectory) {
      const submenuPrefix = `${prefix}/${file}`;
      const submenu = {
        text: file,
        prefix: submenuPrefix
      };
	  const childrenMenu = generateMenus(filePath, submenuPrefix)
	  if (childrenMenu && childrenMenu.length>0) {
		  submenu.children = childrenMenu;
	  }
		  
      menus.push(submenu);
    } else if (path.extname(file) === '.md') {
		const fileName = path.basename(file, '.md');
      const menuItem = {
        text: fileName,
        link: `${prefix}/${fileName}`,
      };
      menus.push(menuItem);
    }
  });

  return menus;
}

const dirPath = path.resolve('src');
const outputPath = path.resolve(__dirname, 'menus.json'); // 当前目录下创建menus.json文件
// const outputPath = path.resolve(__dirname, '..', '.vuepress', 'menus.json'); // 当前文件夹下.vuepress目录下创建menus.json文件

const menus = generateMenus(dirPath);

fs.writeFileSync(outputPath, JSON.stringify(menus, null, 2));

console.log(`菜单已生成并保存到 ${outputPath}`);

异常说明

require is not defined

const fs = require('fs');           
					^ 
ReferenceError: require is not defined in ES module scope, you can use import instead

在JavaScript中,有两种模块系统:CommonJS和ES模块。它们有不同的语法和加载方式。在Node.js中,默认使用的是CommonJS模块系统,其中使用require关键字来引入模块。而ES模块是ES6引入的标准模块系统,使用import关键字来引入模块。

当Node.js检测到文件扩展名为.js且包含package.json文件中的"type"字段设置为"module"时,它会将该文件视为ES模块进行处理。这就是你遇到的错误信息。

要解决这个问题,你可以采取以下几种方法之一:

  1. 将脚本文件的扩展名改为.cjs,例如add_vuepress_menu.cjs,这样Node.js会将其视为CommonJS模块。
  2. package.json文件中将"type"字段的值改为"commonjs",以将整个项目视为CommonJS模块。
  3. 将脚本中的require语句改为import语句,以符合ES模块的语法要求。

针对 const dirPath = path.resolve(__dirname, '..', 'src', 'notes'); 无法识别 __dirname 可以通过 下面的方式实现

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

function generateMenus(dirPath, prefix = '') {
  const files = fs.readdirSync(dirPath);

  let menus = '';

  files.forEach((file) => {
    const filePath = path.join(dirPath, file);
    const isDirectory = fs.statSync(filePath).isDirectory();

    if (isDirectory) {
      menus += `${prefix}├─ ${file}\n`;
      menus += generateMenus(filePath, `${prefix}`);
    } else if (path.extname(file) === '.md') {
      menus += `${prefix}├─ ${path.basename(file, '.md')}\n`;
    }
  });

  return menus;
}

const currentUrl = import.meta.url;
const currentPath = fileURLToPath(currentUrl);
const currentDir = path.dirname(currentPath);
const dirPath = path.resolve(currentDir, '..', 'notes', 'src');
const outputPath = path.resolve(currentDir, 'menu.txt');

const menus = generateMenus(dirPath);

fs.writeFileSync(outputPath, menus);

console.log(`菜单已生成并保存到 ${outputPath}`);