@imhjh/webpack v4.8.3
@imhjh/webpack 文档
安装
# npm
npm install @imhjh/webpack --save-dev
# yarn
yarn add @imhjh/webpack --save
使用
以 MarkdownLoader
为例
webpack.config.js
const { MarkdownLoader } = require("@imhjh/webpack") module.exports = { module: { rules: [{ test: /\.md/, use: [MarkdownLoader] }] } }
react 配置
create-react-app
创建的项目默认webpack.config.js
是隐藏的,需要使用命令显示,但会造成项目臃肿。可以使用其他配置,以下以
@craco/craco
为例。// craco.config.js const { MarkdownLoader } = require("@imhjh/webpack") module.exports = { webpack: { configure: (webpackConfig, { env, paths }) => { // 需要将 loader 插入到 react-script 内置 webpack.config.js 的 loader 前面。 const oneOfRule = webpackConfig.module.rules.find((rule) => !!rule.oneOf) if (oneOfRule) { oneOfRule.oneOf.unshift({ test: /\.md$/, use: [MarkdownLoader] }) } return webpackConfig } } }
vue 配置
vue-cli
的配置方式// vue.config.js const { MarkdownLoader } = require("@imhjh/webpack") module.exports = { // vue.config.js 内部使用 webpack-chain 配置 webpack chainWebpack: (config) => { config.module .rule("markdown") // webpack-chain 内部用于辨别规则的名称 .test(/\.md$/) .use("markdown") // webpack-chain 内部用于辨别loader的名称 .loader(MarkdownLoader) .options({}) // 相关配置 } }
说明
由于项目通过 package#exports
配置导出。
因此在使用 typescript
时会出现警告,需要在 tsconfig.json
中添加以下配置:
{
"compilerOptions": {
"moduleResolution": "node16",
// 或
"moduleResolution": "nodenext"
}
}
loader
MarkdownLoader
用于加载 markdown 文件的 loader。代码块高亮默认利用 prismjs
进行解析。
插件只会将 markdown 解析为 html 代码,但不会添加样式,需要自行实现。所有样式需要自行实现。
内部使用了以下依赖:
目录生成 - markdown-it-toc-done-right
配置(下面参数显示的是默认配置)
// webpack 中配置 { /* markdown-it 的初始化配置 */ preset: "default", // markdown-it 的预设模式 html: undefined, // 在源码中启用 HTML 标签 xhtmlOut: undefined, // 使用 "/" 来闭合单标签 breaks: undefined, // 转换段落里的 '\n' 到 <br>。 langPrefix: undefined, // pre 代码块的 CSS 语言前缀 linkify: undefined, // 将类似 URL 的文本自动转换为链接 typographer: undefined, // 启用一些语言中立的替换 + 引号美化 quotes: undefined, // 双 + 单引号替换对,当 typographer 启用时 /* 锚点插件 markdown-it-anchor */ useAnchor: false, // 是否开启插件 // 使用 markdown-it-anchor 配置 anchorOptions: { slugify: (s) => encodeURIComponent(String(s).trim().toLowerCase().replace(/\s+/g, "-")), permalink: MarkdownItAnchor.permalink.linkInsideHeader({ class: "imhjh-md-anchor", placement: "before", space: false, symbol: "#" }) }, /* 目录插件 markdown-it-toc-done-right */ useTOC: false, // 是否使用开启插件 // 使用 markdown-it-toc-done-right 配置 TOCOptions: { slugify: (s) => encodeURIComponent(String(s).trim().toLowerCase().replace(/\s+/g, "-")), listType: "ul", containerClass: "imhjh-md-toc", linkClass: "imhjh-md-toc-anchor" }, /* 自定义容器插件 markdown-it-container */ useContainer: false, // 是否使用开启插件 // 使用 markdown-it-container 配置 containerOptions: { // 用于配合默认 default render,添加类型 containerClass: "imhjh-md-container", // 外层容器类名 titleClass: "imhjh-md-container-title", // 标题容器类名 bodyClass: "imhjh-md-container-body", // 内容容器类名 renderMap: {}, // 不同标识的渲染方式 // 以下为插件自带配置 marker: ":", validate: (params) => true, render: (tokens, idx) => { /* 内部进行了二次封装 1. 解析标题的第一段字符为容器名称 2. 根据容器名称从 renderMap 中调用渲染函数 3. 未匹配到的容器名称会调用默认的 default 函数渲染 */ /* render 查看 https://gitee.com/hjh925678208/webpack/blob/master/src/dev/utils/markdown.ts#L249 */ /* default 查看 https://gitee.com/hjh925678208/webpack/blob/master/src/dev/utils/markdown.ts#L135 */ } }, contentClass: "imhjh-md-content", // html 外层 div 的class /* prismjs 的语言配置, 完整语言列表 https://prismjs.com/#supported-languages */ languages: [], // 使用 "all" 表示加载所有语言 // 解析出未知语言时,映射为其他语言 languageMap: { default: "js" }, // default:所有未知语言都视作 "js" // 返回给 markdownIt 前,对高亮解析后的代码块 html 进行二次处理 codeHandler({ codeHTML, highlightLang, codeSource, sourceLang }) { // codeHTML 高亮解析后的代码块 html // highlightLang 基于那种语言进行高亮解析 // codeSource 高亮解析前的代码块 markdown // sourceLang 解析 markdown 代码块定义的语言 return codeHTML }, // 对初始化后的 markdown-it 实例进行处理 handler(markdownIt, simpleMarkdownIt) { // markdownIt:整个解析器的 markdown 实例 // simpleMarkdownIt:用于在内部对 container 标题等进行解析的 markdown 实例 // 相较于 markdownIt,simpleMarkdownIt 上没有添加 plugins 等配置 } }
页面导入 markdown 文件的效果
import MarkdownResult from "module.md" const { source, html, TOCCode } = MarkdownResult console.log(source) // 原始的 module.md 文本 console.log(html) // 解析后的 html console.log(TOCCode) // markdown-it-toc-done-right 编译出的目录 html
useMarkdownResolver
MarkdownLoader 内部使用的 markdown 代码解析函数。
用于直接在 browser 环境中使用。
因为 prismjs
的语言模板加载函数只能在 node
环境下使用,所以该函数无法使用 languages 配置。
因此使用 useMarkdownResolver
时若需要加载额外的语言模板,需要配置 babel-plugin-prismjs。
import { useMarkdownResolver } from "@imhjh/webpack/utils"
const { resolver, markdownIt, update, TOCCode } = useMarkdownResolver({
/* 支持除 languages 以外的所有 MarkdownLoader 配置 */
})
const html = resolver("# markdown 文本")
types
MarkdownLoader 相关
// MarkdownLoader 的配置
type MarkdownLoaderOptions = MarkdownResolverOptions & {
/** prismjs 加载的代码块语言类型:"all" | [langs]。*/
languages: "all" | string[]
}
// 代码块处理函数入参
interface CodeHandlerParams {
codeHTML: string /** 高亮解析后的代码块 html */
highlightLang: string /** 基于那种语言进行高亮解析 */
codeSource: string /** 高亮解析前的代码块 markdown */
sourceLang: string /** 解析 markdown 代码块定义的语言 */
}
// 代码块处理函数
interface CodeHandler {
(params: CodeHandlerParams): string
}
// 容器配置
type ContainerOpts = MarkdownResolverOptions["containerOptions"] & {}
// 容器渲染函数
interface ContainerRender {
(tokens: any[], idx: number, simpleMarkdownIt, opts: ContainerOpts): string
}
// useMarkdownResolver 配置
interface MarkdownResolverOptions {
preset?: "default" | "commonmark" | "zero" /** 预设模式 */
contentClass?: string /** 包裹整个 html 的 div.class */
languageMap?: { [k: string]: string } /** prismjs无法解析语言的映射:{ 读取的语言: 目标语言 } */
html?: boolean /** markdown-it 配置:是否在源码中启用 HTML 标签 */
xhtmlOut?: boolean /** markdown-it 配置:是否使用 "/" 来闭合单标签 */
breaks?: boolean /** markdown-it 配置:转换段落里的 '\n' 到 <br> */
langPrefix?: string /** markdown-it 配置:<code /> 代码块的 CSS 类名前缀,默认 imhjh-md- */
linkify?: boolean /** markdown-it 配置:将类似 URL 的文本自动转换为链接 */
typographer?: boolean /** markdown-it 配置:启用一些语言中立的替换 + 引号美化 */
quotes?: string /** markdown-it 配置:双 + 单引号替换对,当 typographer 启用时 */
codeHandler?: CodeHandler /* 在抛给 markdown-it 之前,对高亮解析后的代码块 html 进行二次处理 */
handler?: (markdownIt, simpleMarkdownIt) => void /** 使用 markdown 实例作为入参,提供更好的自定义 */
// 以下配置在 调用 update 时不生效
useAnchor?: boolean /** 是否使用 markdown-it-anchor 插件 */
anchorOptions?: object /** markdown-it-anchor 的配置 */
useTOC?: boolean /** 是否使用 markdown-it-toc-done-right 插件 */
TOCOptions?: object /** markdown-it-toc-done-right 的配置 */
useContainer?: boolean /** 是否使用 markdown-it-container 插件 */
/** markdown-it-container 配置 */
containerOptions?: {
containerClass?: string
titleClass?: string
bodyClass?: string
validate?: (params: string) => string
render?: (tokens: any[], idx: number) => string
marker?: string
renderMap?: { [k: string]: ContainerRender }
}
}
// useMarkdownResolver 返回值
interface MarkdownResolver {
markdownIt: any /** markdownIt 实例 */
resolver: (source: string) => { html: string; TOCCode: string } /** 用于处理的 markdown 文本的解析器 */
update: (opts: MarkdownResolverOptions) => void /** 更新 markdownIt */
}
12 months ago
1 year ago
1 year ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago