Skip to main content

博客-Docusaurus版

之前用的是vuepress v2,由于过于激进,很多插件和功能都不完善,加上对vue的语法不适,遂找了另一个基于React的文档生成工具Docusaurus,又是一轮折腾.

诉求

  • yarn build: 生成公开网站
    • 仅包含private: true的文档
      • VuePress版本为layout: Privatelayout: Draft,Docusaurus这东西似乎不支持layout
    • 不要对图片生成hash版本
    • doCopy: true的文件进行复制
    • doLink: true的附件进行链接转换
  • yarn build:private: 生成私有网站
    • 打包所有文档,包括private: true的;
    • 不要对图片生成hash版本;

分析


async function processImageNode(
node: Image,
{filePath, staticDirs}: PluginOptions,
) {
if (!node.url) {
throw new Error(
`Markdown image URL is mandatory in "${toMessageRelativeFilePath(
filePath,
)}" file`,
);
}

const parsedUrl = url.parse(node.url);
if (parsedUrl.protocol) {
// pathname:// is an escape hatch,
// in case user does not want his images to be converted to require calls going through webpack loader
// we don't have to document this for now,
// it's mostly to make next release less risky (2.0.0-alpha.59)
if (parsedUrl.protocol === 'pathname:') {
node.url = node.url.replace('pathname://', '');
}
}
// images without protocol
else if (path.isAbsolute(node.url)) {
// absolute paths are expected to exist in the static folder
const possibleImagePaths = staticDirs.map((dir) =>
path.join(dir, node.url),
);
const imagePath = await findImage(possibleImagePaths, filePath);
createJSX(node, posixPath(imagePath));
}
// We try to convert image urls without protocol to images with require calls
// going through webpack ensures that image assets exist at build time
else {
// relative paths are resolved against the source file's folder
const expectedImagePath = path.join(path.dirname(filePath), node.url);
await ensureImageFileExist(expectedImagePath, filePath);
createJSX(node, node.url.startsWith('./') ? node.url : `./${node.url}`);
}
}

当图片的url指定了协议时,不会进行处理,特别是协议为pathname://时,会进行移除.

其他的情况,不管是相对路径还是绝对路径,都会交给file-loader来处理,不仅会检查文件是否存在,还会将图片拷贝一份到build/assets/images/[name]-[hash].[ext].

这跟我的诉求是不相符的,我希望自己处理.

解决方案

  • 图片hash问题
    • beforeDefaultRemarkPlugins插入一个自定义插件,把图片的url改为绝对路径(对于项目来说),并加上pathname://头;
    • 使用插件来加头,是为了保证markdown文件本身的完整性,不能完全依赖框架或工具,应能单独预览;
    • 后续插件会自动将pathname://移除;

TypeScript支持

yarn add --dev typescript @docusaurus/module-type-aliases @tsconfig/docusaurus

这不是真正的TypeScript支持

  • 可以用来写主题等
  • 不能用来写配置(docusaurus.config.js依然只能用js)

自定义插件

使用(后面介绍各插件):

// docusaurus.config.js
const config = {
presets: [
[
'@docusaurus/preset-classic',
({
blog: {
beforeDefaultRemarkPlugins: [
// 注意顺序
require('./src/plugins/remark-read-frontmatter'),
]
}
})
]
]
}

remark-rebase-assets

  • 说明 本插件将相对路径转换为相对项目的相对路径

  • 示例

// ${projectDir}/blog/dir1/test.md
![img](../../assets/images/xxx.png)

将被转换为

// ${projectDir}/blog/test.md
![img](/assets/images/xxx.png)

remark-read-frontmatter

  • 注意 本插件提供frontmatter信息,使用frontmatter信息的插件需要放在本插件后面.

  • 说明 由于docusaurusremark中移除了frontmatter,所以自定义的remark插件正常情况是访问不到frontmatter数据的

但是很多情况下必须根据文档的情况来做一些判断,所以这些数据还是很有必要.就自己整一个吧.

  • 配置 本插件不需要配置.

  • 效果 vfile.data.frontmatter保存了frontmatter的信息,供后面的插件使用

remark-copy-assets

  • 说明 本插件将符合条件的链接(对应的文件)复制到另一个目录

  • 配置

    • targetDir: 目标目录,文件将复制到这里,并保持原来的子目录结构
    • flag:
      • 0 不进行操作
      • 1 对私有文件进行操作
      • 2 对公开文件进行操作
      • 3 对私有文件即公开文件进行操作

remark-prefix-assets

  • 说明: 本插件将符合条件的链接增加一个前缀

  • 配置

    • prefix: 前缀
    • flag:
      • 0 不进行操作
      • 1 对私有文件进行操作
      • 2 对公开文件进行操作
      • 3 对私有文件即公开文件进行操作

构建说明

参数情况

方案文档类型复制附件公开链接备注
start公开保持为普通md文档
start私有
build公开✔️
build私有
build:asset公开✔️
build:asset私有不处理私有文档
build:private公开素材库包含公开附件
build:private私有