Skip to content

Commit e061913

Browse files
authored
feat: deprecate soft break transform behavior after 2.2.0 (#1686)
* feat: only enabled soft break before 2.2.0 * feat: use custom remark-breaks replace remark-breaks * fix: fix null safe issue * refactor: not reassigning processor * feat: keep soft break exclude dumi * feat: add deprecation warning with soft break * feat: only output warnings once per run * refactor: optimize import * feat: change warning function and add color * feat: ignore text nodes with only one break symbol
1 parent d56fe43 commit e061913

File tree

6 files changed

+78
-18
lines changed

6 files changed

+78
-18
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
"html2sketch": "^1.0.1",
107107
"js-yaml": "^4.1.0",
108108
"lodash.throttle": "^4.1.1",
109+
"mdast-util-find-and-replace": "^2.2.2",
109110
"mdast-util-to-string": "^3.1.0",
110111
"nprogress": "^0.2.0",
111112
"pluralize": "^8.0.0",
@@ -122,7 +123,6 @@
122123
"rehype-autolink-headings": "^6.1.1",
123124
"rehype-remove-comments": "^5.0.0",
124125
"rehype-stringify": "^9.0.3",
125-
"remark-breaks": "^3.0.2",
126126
"remark-directive": "^2.0.1",
127127
"remark-frontmatter": "^4.0.1",
128128
"remark-gfm": "^3.0.1",

pnpm-lock.yaml

Lines changed: 7 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ export const PICKED_PKG_FIELDS = {
2525
export const USELESS_TMP_FILES = ['tsconfig.json', 'typings.d.ts'];
2626

2727
export const VERSION_2_LEVEL_NAV = '^2.2.0';
28+
29+
export const VERSION_2_DEPRECATE_SOFT_BREAKS = '^2.2.0';

src/features/compile/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export default (api: IApi) => {
4343
extraRemarkPlugins: api.config.extraRemarkPlugins,
4444
extraRehypePlugins: api.config.extraRehypePlugins,
4545
routes: api.appData.routes,
46+
pkg: api.pkg,
4647
};
4748

4849
memo.module

src/loaders/markdown/transformer/index.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import type { IParsedBlockAsset } from '@/assetParsers/block';
22
import type { IRouteMeta } from '@/client/theme-api/types';
3-
import type { IDumiConfig, IDumiTechStack } from '@/types';
3+
import { VERSION_2_DEPRECATE_SOFT_BREAKS } from '@/constants';
4+
import type { IApi, IDumiConfig, IDumiTechStack } from '@/types';
45
import enhancedResolve from 'enhanced-resolve';
56
import type { IRoute } from 'umi';
7+
import { semver } from 'umi/plugin-utils';
68
import type { Plugin, Processor } from 'unified';
79
import type { Data } from 'vfile';
810
import rehypeDemo from './rehypeDemo';
@@ -17,6 +19,7 @@ import rehypeRaw from './rehypeRaw';
1719
import rehypeSlug from './rehypeSlug';
1820
import rehypeStrip from './rehypeStrip';
1921
import rehypeText from './rehypeText';
22+
import remarkBreaks from './remarkBreaks';
2023
import remarkContainer from './remarkContainer';
2124
import remarkEmbed from './remarkEmbed';
2225
import remarkMeta from './remarkMeta';
@@ -63,13 +66,25 @@ export interface IMdTransformerOptions {
6366
extraRemarkPlugins?: IDumiConfig['extraRemarkPlugins'];
6467
extraRehypePlugins?: IDumiConfig['extraRehypePlugins'];
6568
routes: Record<string, IRoute>;
69+
pkg: IApi['pkg'];
6670
}
6771

6872
export interface IMdTransformerResult {
6973
content: string;
7074
meta: Data;
7175
}
7276

77+
/**
78+
* keep markdown soft break before 2.2.0
79+
*/
80+
function keepSoftBreak(pkg: IApi['pkg']) {
81+
// for dumi local example project
82+
if (pkg?.name?.startsWith('@examples/') || pkg?.name === 'dumi') return false;
83+
84+
const ver = pkg?.devDependencies?.dumi ?? pkg?.dependencies?.dumi ?? '^2.0.0';
85+
return !semver.subset(ver, VERSION_2_DEPRECATE_SOFT_BREAKS);
86+
}
87+
7388
function applyUnifiedPlugin(opts: {
7489
processor: Processor;
7590
plugin: NonNullable<IMdTransformerOptions['extraRemarkPlugins']>[0];
@@ -92,7 +107,6 @@ export default async (raw: string, opts: IMdTransformerOptions) => {
92107
const { default: remarkParse } = await import('remark-parse');
93108
const { default: remarkFrontmatter } = await import('remark-frontmatter');
94109
const { default: remarkDirective } = await import('remark-directive');
95-
const { default: remarkBreaks } = await import('remark-breaks');
96110
const { default: remarkGfm } = await import('remark-gfm');
97111
const { default: remarkRehype } = await import('remark-rehype');
98112
const { default: rehypeAutolinkHeadings } = await import(
@@ -117,9 +131,12 @@ export default async (raw: string, opts: IMdTransformerOptions) => {
117131
})
118132
.use(remarkDirective)
119133
.use(remarkContainer)
120-
.use(remarkBreaks)
121134
.use(remarkGfm);
122135

136+
if (keepSoftBreak(opts.pkg)) {
137+
processor.use(remarkBreaks, { fileAbsPath: opts.fileAbsPath });
138+
}
139+
123140
// apply extra remark plugins
124141
opts.extraRemarkPlugins?.forEach((plugin) =>
125142
applyUnifiedPlugin({
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import type { IMdTransformerOptions } from '@/loaders/markdown/transformer/index';
2+
import type { Root } from 'mdast';
3+
import type { ReplaceFunction } from 'mdast-util-find-and-replace';
4+
import { chalk, logger } from 'umi/plugin-utils';
5+
6+
let findAndReplace: typeof import('mdast-util-find-and-replace').findAndReplace;
7+
8+
(async () => {
9+
({ findAndReplace } = await import('mdast-util-find-and-replace'));
10+
})();
11+
12+
const warningLock = new Map<string, true>();
13+
14+
function logDeprecationWarning(fileAbsPath: string) {
15+
if (warningLock.get(fileAbsPath)) return;
16+
17+
warningLock.set(fileAbsPath, true);
18+
19+
logger.warn(
20+
'Detected that you are using soft breaks, dumi will transform them into spaces after the declaration',
21+
'version greater than or equal to `2.2.0`, however, they are still being transformed as line breaks now, please',
22+
'migrate them to hard breaks before upgrading the declaration version for dumi.\n',
23+
chalk.grey(` at ${fileAbsPath}\n`),
24+
chalk.grey(' see also: https://github.com/umijs/dumi/issues/1683\n'),
25+
);
26+
}
27+
28+
export default function remarkBreaks(
29+
opts: Pick<IMdTransformerOptions, 'fileAbsPath'>,
30+
) {
31+
const replace: ReplaceFunction = (_, match) => {
32+
if (
33+
match.input === '\n' ||
34+
match.input === '\r' ||
35+
match.input === '\r\n'
36+
) {
37+
return false;
38+
}
39+
40+
logDeprecationWarning(opts.fileAbsPath);
41+
return { type: 'break' };
42+
};
43+
44+
return (tree: Root) => {
45+
findAndReplace(tree, /\r?\n|\r/g, replace);
46+
};
47+
}

0 commit comments

Comments
 (0)