Skip to content

Commit

Permalink
feat(vue-jsx): add defineComponentName option
Browse files Browse the repository at this point in the history
  • Loading branch information
sxzz committed Aug 14, 2024
1 parent 37c9073 commit 0f71911
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 12 deletions.
10 changes: 9 additions & 1 deletion packages/plugin-vue-jsx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,20 @@ A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patt

> See [@vue/babel-plugin-jsx](https://github.com/vuejs/jsx-next) for other options.
### defineComponentName

Type: `string[]`

Default: `['defineComponent']`

The name of the function to be used for defining components. This is useful when you have a custom `defineComponent` function.

## HMR Detection

This plugin supports HMR of Vue JSX components. The detection requirements are:

- The component must be exported.
- The component must be declared by calling `defineComponent` via a root-level statement, either variable declaration or export declaration.
- The component must be declared by calling `defineComponent` or the name specified in `defineComponentName` via a root-level statement, either variable declaration or export declaration.

### Supported patterns

Expand Down
40 changes: 31 additions & 9 deletions packages/plugin-vue-jsx/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ function vueJsxPlugin(options: Options = {}): Plugin {
let needHmr = false
let needSourceMap = true

const { include, exclude, babelPlugins = [], ...babelPluginOptions } = options
const {
include,
exclude,
babelPlugins = [],
defineComponentName = ['defineComponent'],
...babelPluginOptions
} = options
const filter = createFilter(include || /\.[jt]sx$/, exclude)

return {
Expand Down Expand Up @@ -103,7 +109,9 @@ function vueJsxPlugin(options: Options = {}): Plugin {
visitor: {
CallExpression: {
enter(_path: babel.NodePath<CallExpression>) {
if (isDefineComponentCall(_path.node)) {
if (
isDefineComponentCall(_path.node, defineComponentName)
) {
const callee = _path.node.callee as Identifier
callee.name = `/* @__PURE__ */ ${callee.name}`
}
Expand Down Expand Up @@ -144,7 +152,7 @@ function vueJsxPlugin(options: Options = {}): Plugin {

for (const node of result.ast!.program.body) {
if (node.type === 'VariableDeclaration') {
const names = parseComponentDecls(node)
const names = parseComponentDecls(node, defineComponentName)
if (names.length) {
declaredComponents.push(...names)
}
Expand All @@ -156,7 +164,10 @@ function vueJsxPlugin(options: Options = {}): Plugin {
node.declaration.type === 'VariableDeclaration'
) {
hotComponents.push(
...parseComponentDecls(node.declaration).map((name) => ({
...parseComponentDecls(
node.declaration,
defineComponentName,
).map((name) => ({
local: name,
exported: name,
id: getHash(id + name),
Expand Down Expand Up @@ -194,7 +205,9 @@ function vueJsxPlugin(options: Options = {}): Plugin {
id: getHash(id + 'default'),
})
}
} else if (isDefineComponentCall(node.declaration)) {
} else if (
isDefineComponentCall(node.declaration, defineComponentName)
) {
hasDefault = true
hotComponents.push({
local: '__default__',
Expand Down Expand Up @@ -254,22 +267,31 @@ function vueJsxPlugin(options: Options = {}): Plugin {
}
}

function parseComponentDecls(node: types.VariableDeclaration) {
function parseComponentDecls(
node: types.VariableDeclaration,
fnNames: string[],
) {
const names = []
for (const decl of node.declarations) {
if (decl.id.type === 'Identifier' && isDefineComponentCall(decl.init)) {
if (
decl.id.type === 'Identifier' &&
isDefineComponentCall(decl.init, fnNames)
) {
names.push(decl.id.name)
}
}
return names
}

function isDefineComponentCall(node?: types.Node | null) {
function isDefineComponentCall(
node: types.Node | null | undefined,
names: string[],
) {
return (
node &&
node.type === 'CallExpression' &&
node.callee.type === 'Identifier' &&
node.callee.name === 'defineComponent'
names.includes(node.callee.name)
)
}

Expand Down
7 changes: 5 additions & 2 deletions packages/plugin-vue-jsx/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ export interface FilterOptions {
exclude?: FilterPattern
}

export type Options = VueJSXPluginOptions &
FilterOptions & { babelPlugins?: any[] }
export interface Options extends VueJSXPluginOptions, FilterOptions {
babelPlugins?: any[]
/** @default ['defineComponent'] */
defineComponentName?: string[]
}

0 comments on commit 0f71911

Please sign in to comment.