-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(preset): support to register compiletime component (#933)
* feat: support to register markdown component * test: update markdown component tests * fix: improve module path in windows * feat: support to replace the older component * feat: compiler function supports return values
- Loading branch information
1 parent
cdf1d02
commit ccc5b67
Showing
17 changed files
with
256 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export default { | ||
history: { type: 'memory' }, | ||
mountElementId: '', | ||
plugins: ['./plugin.js'], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<Test /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import React from 'react'; | ||
|
||
export default () => ( | ||
<div>for testing markdown component</div> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import path from "path"; | ||
|
||
export default (api) => { | ||
api.chainWebpack((memo) => { | ||
// babel compile src folder | ||
memo.module.rule("js").include.add(path.join(__dirname, "../../..")); | ||
|
||
return memo; | ||
}); | ||
|
||
api.register({ | ||
key: "dumi.registerMdComponent", | ||
fn: () => ({ | ||
name: "Test", | ||
component: path.join(__dirname, "Test.js"), | ||
compiler(node, i, parent, vFile) {}, | ||
}), | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { IApi } from '@umijs/types'; | ||
import type { IMarkdwonComponent } from '../../transformer/remark/mdComponent'; | ||
import { registerMdComponent } from '../../transformer/remark/mdComponent'; | ||
|
||
export default (api: IApi) => { | ||
api.onPluginReady(async () => { | ||
const mdComponents: IMarkdwonComponent[] = await api.applyPlugins({ | ||
type: api.ApplyPluginsType.add, | ||
key: 'dumi.registerMdComponent', | ||
initialValue: [], | ||
}); | ||
|
||
mdComponents.forEach(comp => { | ||
registerMdComponent(comp); | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
packages/preset-dumi/src/transformer/fixtures/remark-components/Test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import React from 'react'; | ||
|
||
export default () => <div>test</div> |
1 change: 1 addition & 0 deletions
1
packages/preset-dumi/src/transformer/fixtures/remark-components/another.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<Test /> |
1 change: 1 addition & 0 deletions
1
packages/preset-dumi/src/transformer/fixtures/remark-components/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<Test /> |
1 change: 1 addition & 0 deletions
1
packages/preset-dumi/src/transformer/fixtures/remark-components/test.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<Test /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
packages/preset-dumi/src/transformer/remark/mdComponent.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import is from 'hast-util-is-element'; | ||
import visit from 'unist-util-visit'; | ||
import type { IDumiUnifiedTransformer, IDumiElmNode } from '.'; | ||
import type { Transformer } from 'unified'; | ||
import type unified from 'unified'; | ||
|
||
type ICompiler = ( | ||
this: Pick<unified.Processor<unified.Settings>, 'data'>, | ||
node: Parameters<visit.Visitor<IDumiElmNode>>[0], | ||
index: Parameters<visit.Visitor<IDumiElmNode>>[1], | ||
parent: Parameters<visit.Visitor<IDumiElmNode>>[2], | ||
vFile: Parameters<Transformer>[1], | ||
) => ReturnType<visit.Visitor<IDumiElmNode>>; | ||
|
||
export interface IMarkdwonComponent { | ||
/** | ||
* The markdown component name which should always start with a capital letter | ||
*/ | ||
name: string; | ||
/** | ||
* The component path | ||
*/ | ||
component: string; | ||
/** | ||
* The compiler function about how to parse the HTML Abstract Syntax Tree parsed by rehype | ||
* @see https://github.com/syntax-tree/hast for more details about the HTML Abstract Syntax Tree | ||
* @see https://github.com/syntax-tree/unist-util-visit-parents#returns for more details about the return value for this function | ||
*/ | ||
compiler: ICompiler; | ||
} | ||
|
||
const markdownComponents: IMarkdwonComponent[] = []; | ||
export function registerMdComponent(comp: IMarkdwonComponent) { | ||
const target = markdownComponents.find(item => item.name === comp.name); | ||
if (target) { | ||
// replace the existed one | ||
Object.assign(target, comp); | ||
} else { | ||
markdownComponents.push(comp); | ||
} | ||
} | ||
|
||
/** | ||
* remark plugin for parsing the customize markdwon components | ||
*/ | ||
export default function mdComponent(): IDumiUnifiedTransformer { | ||
return (ast, vFile) => { | ||
visit<IDumiElmNode>(ast, 'element', (node, i, parent) => { | ||
const componentNames = markdownComponents.map(a => a.name); | ||
if (is(node, componentNames) && !node._dumi_parsed) { | ||
const target = markdownComponents.find(item => item.name === node.tagName); | ||
// mark this node as a parsed node by dumi | ||
node._dumi_parsed = true; | ||
return target.compiler.call(this, node, i, parent, vFile); | ||
} | ||
}); | ||
}; | ||
} |
87 changes: 87 additions & 0 deletions
87
packages/preset-dumi/src/transformer/test/remark-markdown-component.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import path from 'path'; | ||
import fs from 'fs'; | ||
import transformer from '..'; | ||
import { registerMdComponent } from '../remark/mdComponent'; | ||
|
||
describe('markdown component examples', () => { | ||
const fixtures = path.join(__dirname, '../fixtures/remark-components'); | ||
|
||
it('Should NOT transform unrecognized markdown component', () => { | ||
const filePath = path.join(fixtures, 'index.md'); | ||
const result = transformer.markdown( | ||
fs.readFileSync(filePath, 'utf8').toString(), | ||
filePath, | ||
).content; | ||
|
||
// compare transform content | ||
expect(result).toEqual(`<div className="markdown"><Test /></div>`); | ||
}); | ||
|
||
it('Should transform recognized markdown component', () => { | ||
// register mdComponents | ||
registerMdComponent({ | ||
name: 'Test', | ||
component: path.join(fixtures, 'remark-components', 'Test.js'), | ||
compiler(node, index, parent) { | ||
// insert a h3 title before Test component | ||
parent.children.splice( | ||
index, | ||
0, | ||
...[ | ||
{ | ||
type: 'element', | ||
tagName: 'h3', | ||
properties: { id: `markdown-components` }, | ||
children: [], | ||
}, | ||
], | ||
); | ||
}, | ||
}); | ||
|
||
const filePath = path.join(fixtures, 'test.md'); | ||
const result = transformer.markdown( | ||
fs.readFileSync(filePath, 'utf8').toString(), | ||
filePath, | ||
).content; | ||
|
||
// compare transform content | ||
expect(result).toEqual( | ||
`<div className=\"markdown\"><h3 id=\"markdown-components\"><AnchorLink to=\"#markdown-components\" aria-hidden=\"true\" tabIndex={-1}><span className=\"icon icon-link\" /></AnchorLink></h3><Test /></div>`, | ||
); | ||
}); | ||
|
||
it('Should support to replace the markdown component', () => { | ||
// register another Test component | ||
registerMdComponent({ | ||
name: 'Test', | ||
component: path.join(fixtures, 'remark-components', 'Test.js'), | ||
compiler(node, index, parent) { | ||
// insert a h3 title before Test component | ||
parent.children.splice( | ||
index, | ||
0, | ||
...[ | ||
{ | ||
type: 'element', | ||
tagName: 'h3', | ||
properties: { id: `another-markdown-components` }, | ||
children: [], | ||
}, | ||
], | ||
); | ||
}, | ||
}); | ||
|
||
const filePath = path.join(fixtures, 'another.md'); | ||
const result = transformer.markdown( | ||
fs.readFileSync(filePath, 'utf8').toString(), | ||
filePath, | ||
).content; | ||
|
||
// compare transform content | ||
expect(result).toEqual( | ||
`<div className=\"markdown\"><h3 id=\"another-markdown-components\"><AnchorLink to=\"#another-markdown-components\" aria-hidden=\"true\" tabIndex={-1}><span className=\"icon icon-link\" /></AnchorLink></h3><Test /></div>`, | ||
); | ||
}); | ||
}); |