mirror of
https://github.com/vuejs/babel-plugin-jsx.git
synced 2024-11-10 09:39:14 +08:00
feat: add pragma option and support @jsx annotation (#322)
* add pragma option and support @jsx annotation * update syntax and remove useless eslint rule * use BabelCore.BabelFile as type definition of state.file * update chinese doc
This commit is contained in:
parent
57f670711d
commit
ec50fddc8a
@ -22,6 +22,7 @@ module.exports = {
|
||||
'no-nested-ternary': [0],
|
||||
'no-param-reassign': [0],
|
||||
'no-use-before-define': [0],
|
||||
'no-restricted-syntax': [0],
|
||||
'no-plusplus': [0],
|
||||
'import/no-extraneous-dependencies': [0],
|
||||
'consistent-return': [0],
|
||||
|
@ -62,6 +62,14 @@ Default: `true`
|
||||
|
||||
使用 `enableObjectSlots` (文档下面会提到)。虽然在 JSX 中比较好使,但是会增加一些 `_isSlot` 的运行时条件判断,这会增加你的项目体积。即使你关闭了 `enableObjectSlots`,`v-slots` 还是可以使用
|
||||
|
||||
#### pragma
|
||||
|
||||
Type: `string`
|
||||
|
||||
Default: `createVNode`
|
||||
|
||||
替换编译JSX表达式的时候使用的函数
|
||||
|
||||
## 表达式
|
||||
|
||||
### 内容
|
||||
|
@ -66,6 +66,14 @@ Default: `true`
|
||||
|
||||
Whether to enable `object slots` (mentioned below the document) syntax". It might be useful in JSX, but it will add a lot of `_isSlot` condition expressions which increase your bundle size. And `v-slots` is still available even if `enableObjectSlots` is turned off.
|
||||
|
||||
#### pragma
|
||||
|
||||
Type: `string`
|
||||
|
||||
Default: `createVNode`
|
||||
|
||||
Replace the function used when compiling JSX expressions.
|
||||
|
||||
## Syntax
|
||||
|
||||
### Content
|
||||
|
@ -11,6 +11,7 @@ export type State = {
|
||||
get: (name: string) => any;
|
||||
set: (name: string, value: any) => any;
|
||||
opts: VueJSXPluginOptions;
|
||||
file: BabelCore.BabelFile
|
||||
}
|
||||
|
||||
export interface VueJSXPluginOptions {
|
||||
@ -24,6 +25,8 @@ export interface VueJSXPluginOptions {
|
||||
isCustomElement?: (tag: string) => boolean;
|
||||
/** enable object slots syntax */
|
||||
enableObjectSlots?: boolean;
|
||||
/** Replace the function used when compiling JSX expressions */
|
||||
pragma?: string;
|
||||
}
|
||||
|
||||
export type ExcludesBoolean = <T>(x: T | false | true) => x is T;
|
||||
@ -44,6 +47,8 @@ const hasJSX = (parentPath: NodePath<t.Program>) => {
|
||||
return fileHasJSX;
|
||||
};
|
||||
|
||||
const JSX_ANNOTATION_REGEX = /\*?\s*@jsx\s+([^\s]+)/;
|
||||
|
||||
export default ({ types }: typeof BabelCore) => ({
|
||||
name: 'babel-plugin-jsx',
|
||||
inherits: syntaxJsx,
|
||||
@ -129,6 +134,21 @@ export default ({ types }: typeof BabelCore) => ({
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const { opts: { pragma = '' }, file } = state;
|
||||
|
||||
if (pragma) {
|
||||
state.set('createVNode', () => t.identifier(pragma));
|
||||
}
|
||||
|
||||
if (file.ast.comments) {
|
||||
for (const comment of file.ast.comments) {
|
||||
const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
|
||||
if (jsxMatches) {
|
||||
state.set('createVNode', () => t.identifier(jsxMatches[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
exit(path: NodePath<t.Program>) {
|
||||
|
@ -210,6 +210,11 @@ _withDirectives(_createVNode(\\"select\\", {
|
||||
}, [_createTextVNode(\\"c\\")])], 8, [\\"onUpdate:modelValue\\"]), [[_vModelSelect, test]]);"
|
||||
`;
|
||||
|
||||
exports[`set pragma to custom: custom 1`] = `
|
||||
"import { createTextVNode as _createTextVNode } from \\"vue\\";
|
||||
custom(\\"div\\", null, [_createTextVNode(\\"pragma\\")]);"
|
||||
`;
|
||||
|
||||
exports[`should keep \`import * as Vue from "vue"\`: should keep \`import * as Vue from "vue"\` 1`] = `
|
||||
"import { createVNode as _createVNode, createTextVNode as _createTextVNode } from \\"vue\\";
|
||||
import * as Vue from 'vue';
|
||||
@ -239,6 +244,15 @@ _withDirectives(_createVNode(\\"textarea\\", {
|
||||
}, null, 8, [\\"onUpdate:modelValue\\"]), [[_vModelText, test]]);"
|
||||
`;
|
||||
|
||||
exports[`use "@jsx" comment specify pragma: use "@jsx" comment specify pragma 1`] = `
|
||||
"import { createTextVNode as _createTextVNode } from \\"vue\\";
|
||||
|
||||
/* @jsx custom */
|
||||
custom(\\"div\\", {
|
||||
\\"id\\": \\"custom\\"
|
||||
}, [_createTextVNode(\\"Hello\\")]);"
|
||||
`;
|
||||
|
||||
exports[`use "model" as the prop name: use "model" as the prop name 1`] = `
|
||||
"import { createVNode as _createVNode, resolveComponent as _resolveComponent } from \\"vue\\";
|
||||
|
||||
|
@ -163,6 +163,13 @@ const tests: Test[] = [
|
||||
<Vue.KeepAlive>123</Vue.KeepAlive>
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: 'use "@jsx" comment specify pragma',
|
||||
from: `
|
||||
/* @jsx custom */
|
||||
<div id="custom">Hello</div>
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
tests.forEach((
|
||||
@ -244,3 +251,22 @@ objectSlotsTests.forEach(({
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
const pragmaTests = [
|
||||
{
|
||||
name: 'custom',
|
||||
from: '<div>pragma</div>',
|
||||
},
|
||||
];
|
||||
|
||||
pragmaTests.forEach(({
|
||||
name, from,
|
||||
}) => {
|
||||
test(
|
||||
`set pragma to ${name}`,
|
||||
async () => {
|
||||
expect(await transpile(from, { pragma: 'custom' }))
|
||||
.toMatchSnapshot(name);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user