# webpack **Repository Path**: hjh925678208/webpack ## Basic Information - **Project Name**: webpack - **Description**: webpack 工具库 - **Primary Language**: JavaScript - **License**: ISC - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2022-11-12 - **Last Updated**: 2025-01-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # @imhjh/webpack 文档 [源码](https://gitee.com/hjh925678208/webpack) ## 安装 ```bash # npm npm install @imhjh/webpack --save-dev # yarn yarn add @imhjh/webpack --save ``` ## 使用 以 `MarkdownLoader` 为例 - webpack.config.js ```js const { MarkdownLoader } = require("@imhjh/webpack") module.exports = { module: { rules: [{ test: /\.md/, use: [MarkdownLoader] }] } } ``` - react 配置 `create-react-app` 创建的项目默认 `webpack.config.js` 是隐藏的,需要使用命令显示,但会造成项目臃肿。 可以使用其他配置,以下以 `@craco/craco` 为例。 ```js // 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` 的配置方式 ```js // 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` 中添加以下配置: ```json { "compilerOptions": { "moduleResolution": "node16", // 或 "moduleResolution": "nodenext" } } ``` ## loader ### MarkdownLoader 用于加载 markdown 文件的 loader。代码块高亮默认利用 `prismjs` 进行解析。 插件只会将 markdown 解析为 html 代码,但不会添加样式,需要自行实现。所有样式需要自行实现。 内部使用了以下依赖: [文档解析 - markdown-it](https://github.com/markdown-it/markdown-it) [标题锚点 - markdown-it-anchor](https://github.com/valeriangalliat/markdown-it-anchor) [目录生成 - markdown-it-toc-done-right](https://github.com/nagaozen/markdown-it-toc-done-right) [自定义容器 - markdown-it-container](https://github.com/markdown-it/markdown-it-container) [代码高亮解析 - Prismjs](https://prismjs.com/) - 配置(下面参数显示的是默认配置) ```js // webpack 中配置 { /* markdown-it 的初始化配置 */ preset: "default", // markdown-it 的预设模式 html: undefined, // 在源码中启用 HTML 标签 xhtmlOut: undefined, // 使用 "/" 来闭合单标签 breaks: undefined, // 转换段落里的 '\n' 到
。 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 文件的效果 ```js 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](https://github.com/mAAdhaTTah/babel-plugin-prismjs)。 ```js import { useMarkdownResolver } from "@imhjh/webpack/utils" const { resolver, markdownIt, update, TOCCode } = useMarkdownResolver({ /* 支持除 languages 以外的所有 MarkdownLoader 配置 */ }) const html = resolver("# markdown 文本") ``` ## types ### MarkdownLoader 相关 ```ts // 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' 到
*/ langPrefix?: string /** markdown-it 配置: 代码块的 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 */ } ```