feat(sfc): allow sfcs to recursively self-reference in template via name inferred from filename
e.g. A file named `FooBar.vue` can refer to itself as `<FooBar/>`. This gets rid of the need for the `name` option.
This commit is contained in:
@@ -128,6 +128,12 @@ interface SharedTransformCodegenOptions {
|
||||
* Indicates that transforms and codegen should try to output valid TS code
|
||||
*/
|
||||
isTS?: boolean
|
||||
/**
|
||||
* Filename for source map generation.
|
||||
* Also used for self-recursive reference in templates
|
||||
* @default 'template.vue.html'
|
||||
*/
|
||||
filename?: string
|
||||
}
|
||||
|
||||
export interface TransformOptions extends SharedTransformCodegenOptions {
|
||||
@@ -218,11 +224,6 @@ export interface CodegenOptions extends SharedTransformCodegenOptions {
|
||||
* @default false
|
||||
*/
|
||||
sourceMap?: boolean
|
||||
/**
|
||||
* Filename for source map generation.
|
||||
* @default 'template.vue.html'
|
||||
*/
|
||||
filename?: string
|
||||
/**
|
||||
* SFC scoped styles ID
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,9 @@ import {
|
||||
NOOP,
|
||||
PatchFlags,
|
||||
PatchFlagNames,
|
||||
EMPTY_OBJ
|
||||
EMPTY_OBJ,
|
||||
capitalize,
|
||||
camelize
|
||||
} from '@vue/shared'
|
||||
import { defaultOnError } from './errors'
|
||||
import {
|
||||
@@ -79,7 +81,9 @@ export interface ImportItem {
|
||||
path: string
|
||||
}
|
||||
|
||||
export interface TransformContext extends Required<TransformOptions> {
|
||||
export interface TransformContext
|
||||
extends Required<Omit<TransformOptions, 'filename'>> {
|
||||
selfName: string | null
|
||||
root: RootNode
|
||||
helpers: Set<symbol>
|
||||
components: Set<string>
|
||||
@@ -112,6 +116,7 @@ export interface TransformContext extends Required<TransformOptions> {
|
||||
export function createTransformContext(
|
||||
root: RootNode,
|
||||
{
|
||||
filename = '',
|
||||
prefixIdentifiers = false,
|
||||
hoistStatic = false,
|
||||
cacheHandlers = false,
|
||||
@@ -130,8 +135,10 @@ export function createTransformContext(
|
||||
onError = defaultOnError
|
||||
}: TransformOptions
|
||||
): TransformContext {
|
||||
const nameMatch = filename.replace(/\?.*$/, '').match(/([^/\\]+)\.\w+$/)
|
||||
const context: TransformContext = {
|
||||
// options
|
||||
selfName: nameMatch && capitalize(camelize(nameMatch[1])),
|
||||
prefixIdentifiers,
|
||||
hoistStatic,
|
||||
cacheHandlers,
|
||||
|
||||
@@ -263,7 +263,16 @@ export function resolveComponentType(
|
||||
}
|
||||
}
|
||||
|
||||
// 4. user component (resolve)
|
||||
// 4. Self referencing component (inferred from filename)
|
||||
if (!__BROWSER__ && context.selfName) {
|
||||
if (capitalize(camelize(tag)) === context.selfName) {
|
||||
context.helper(RESOLVE_COMPONENT)
|
||||
context.components.add(`_self`)
|
||||
return toValidAssetId(`_self`, `component`)
|
||||
}
|
||||
}
|
||||
|
||||
// 5. user component (resolve)
|
||||
context.helper(RESOLVE_COMPONENT)
|
||||
context.components.add(tag)
|
||||
return toValidAssetId(tag, `component`)
|
||||
|
||||
Reference in New Issue
Block a user