first
This commit is contained in:
64
node_modules/vue/packages/compiler-sfc/api-extractor.json
generated
vendored
Normal file
64
node_modules/vue/packages/compiler-sfc/api-extractor.json
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
|
||||
|
||||
"projectFolder": ".",
|
||||
|
||||
"mainEntryPointFilePath": "../../temp/packages/compiler-sfc/src/index.d.ts",
|
||||
|
||||
"compiler": {
|
||||
"tsconfigFilePath": "../../api-extractor.tsconfig.json"
|
||||
},
|
||||
|
||||
"dtsRollup": {
|
||||
"enabled": true,
|
||||
"untrimmedFilePath": "",
|
||||
"publicTrimmedFilePath": "./dist/compiler-sfc.d.ts"
|
||||
},
|
||||
|
||||
"apiReport": {
|
||||
"enabled": false
|
||||
},
|
||||
|
||||
"docModel": {
|
||||
"enabled": false
|
||||
},
|
||||
|
||||
"tsdocMetadata": {
|
||||
"enabled": false
|
||||
},
|
||||
|
||||
"messages": {
|
||||
"compilerMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
}
|
||||
},
|
||||
|
||||
"extractorMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning",
|
||||
"addToApiReportFile": true
|
||||
},
|
||||
|
||||
"ae-missing-release-tag": {
|
||||
"logLevel": "none"
|
||||
},
|
||||
"ae-internal-missing-underscore": {
|
||||
"logLevel": "none"
|
||||
},
|
||||
"ae-forgotten-export": {
|
||||
"logLevel": "none"
|
||||
}
|
||||
},
|
||||
|
||||
"tsdocMessageReporting": {
|
||||
"default": {
|
||||
"logLevel": "warning"
|
||||
},
|
||||
|
||||
"tsdoc-undefined-tag": {
|
||||
"logLevel": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
454
node_modules/vue/packages/compiler-sfc/dist/compiler-sfc.d.ts
generated
vendored
Normal file
454
node_modules/vue/packages/compiler-sfc/dist/compiler-sfc.d.ts
generated
vendored
Normal file
@ -0,0 +1,454 @@
|
||||
import { LazyResult } from 'postcss';
|
||||
import { ParserPlugin } from '@babel/parser';
|
||||
|
||||
declare interface AssetURLOptions {
|
||||
[name: string]: string | string[];
|
||||
}
|
||||
|
||||
declare type ASTAttr = {
|
||||
name: string;
|
||||
value: any;
|
||||
dynamic?: boolean;
|
||||
start?: number;
|
||||
end?: number;
|
||||
};
|
||||
|
||||
declare type ASTDirective = {
|
||||
name: string;
|
||||
rawName: string;
|
||||
value: string;
|
||||
arg: string | null;
|
||||
isDynamicArg: boolean;
|
||||
modifiers: ASTModifiers | null;
|
||||
start?: number;
|
||||
end?: number;
|
||||
};
|
||||
|
||||
declare type ASTElement = {
|
||||
type: 1;
|
||||
tag: string;
|
||||
attrsList: Array<ASTAttr>;
|
||||
attrsMap: {
|
||||
[key: string]: any;
|
||||
};
|
||||
rawAttrsMap: {
|
||||
[key: string]: ASTAttr;
|
||||
};
|
||||
parent: ASTElement | void;
|
||||
children: Array<ASTNode>;
|
||||
start?: number;
|
||||
end?: number;
|
||||
processed?: true;
|
||||
static?: boolean;
|
||||
staticRoot?: boolean;
|
||||
staticInFor?: boolean;
|
||||
staticProcessed?: boolean;
|
||||
hasBindings?: boolean;
|
||||
text?: string;
|
||||
attrs?: Array<ASTAttr>;
|
||||
dynamicAttrs?: Array<ASTAttr>;
|
||||
props?: Array<ASTAttr>;
|
||||
plain?: boolean;
|
||||
pre?: true;
|
||||
ns?: string;
|
||||
component?: string;
|
||||
inlineTemplate?: true;
|
||||
transitionMode?: string | null;
|
||||
slotName?: string | null;
|
||||
slotTarget?: string | null;
|
||||
slotTargetDynamic?: boolean;
|
||||
slotScope?: string | null;
|
||||
scopedSlots?: {
|
||||
[name: string]: ASTElement;
|
||||
};
|
||||
ref?: string;
|
||||
refInFor?: boolean;
|
||||
if?: string;
|
||||
ifProcessed?: boolean;
|
||||
elseif?: string;
|
||||
else?: true;
|
||||
ifConditions?: ASTIfConditions;
|
||||
for?: string;
|
||||
forProcessed?: boolean;
|
||||
key?: string;
|
||||
alias?: string;
|
||||
iterator1?: string;
|
||||
iterator2?: string;
|
||||
staticClass?: string;
|
||||
classBinding?: string;
|
||||
staticStyle?: string;
|
||||
styleBinding?: string;
|
||||
events?: ASTElementHandlers;
|
||||
nativeEvents?: ASTElementHandlers;
|
||||
transition?: string | true;
|
||||
transitionOnAppear?: boolean;
|
||||
model?: {
|
||||
value: string;
|
||||
callback: string;
|
||||
expression: string;
|
||||
};
|
||||
directives?: Array<ASTDirective>;
|
||||
forbidden?: true;
|
||||
once?: true;
|
||||
onceProcessed?: boolean;
|
||||
wrapData?: (code: string) => string;
|
||||
wrapListeners?: (code: string) => string;
|
||||
ssrOptimizability?: number;
|
||||
};
|
||||
|
||||
declare type ASTElementHandler = {
|
||||
value: string;
|
||||
params?: Array<any>;
|
||||
modifiers: ASTModifiers | null;
|
||||
dynamic?: boolean;
|
||||
start?: number;
|
||||
end?: number;
|
||||
};
|
||||
|
||||
declare type ASTElementHandlers = {
|
||||
[key: string]: ASTElementHandler | Array<ASTElementHandler>;
|
||||
};
|
||||
|
||||
declare type ASTExpression = {
|
||||
type: 2;
|
||||
expression: string;
|
||||
text: string;
|
||||
tokens: Array<string | Object>;
|
||||
static?: boolean;
|
||||
ssrOptimizability?: number;
|
||||
start?: number;
|
||||
end?: number;
|
||||
};
|
||||
|
||||
declare type ASTIfCondition = {
|
||||
exp: string | null;
|
||||
block: ASTElement;
|
||||
};
|
||||
|
||||
declare type ASTIfConditions = Array<ASTIfCondition>;
|
||||
|
||||
declare type ASTModifiers = {
|
||||
[key: string]: boolean;
|
||||
};
|
||||
|
||||
declare type ASTNode = ASTElement | ASTText | ASTExpression;
|
||||
|
||||
declare type ASTText = {
|
||||
type: 3;
|
||||
text: string;
|
||||
static?: boolean;
|
||||
isComment?: boolean;
|
||||
ssrOptimizability?: number;
|
||||
start?: number;
|
||||
end?: number;
|
||||
};
|
||||
|
||||
declare type BindingMetadata = {
|
||||
[key: string]: BindingTypes | undefined;
|
||||
} & {
|
||||
__isScriptSetup?: boolean;
|
||||
};
|
||||
|
||||
declare const enum BindingTypes {
|
||||
/**
|
||||
* returned from data()
|
||||
*/
|
||||
DATA = "data",
|
||||
/**
|
||||
* declared as a prop
|
||||
*/
|
||||
PROPS = "props",
|
||||
/**
|
||||
* a local alias of a `<script setup>` destructured prop.
|
||||
* the original is stored in __propsAliases of the bindingMetadata object.
|
||||
*/
|
||||
PROPS_ALIASED = "props-aliased",
|
||||
/**
|
||||
* a let binding (may or may not be a ref)
|
||||
*/
|
||||
SETUP_LET = "setup-let",
|
||||
/**
|
||||
* a const binding that can never be a ref.
|
||||
* these bindings don't need `unref()` calls when processed in inlined
|
||||
* template expressions.
|
||||
*/
|
||||
SETUP_CONST = "setup-const",
|
||||
/**
|
||||
* a const binding that does not need `unref()`, but may be mutated.
|
||||
*/
|
||||
SETUP_REACTIVE_CONST = "setup-reactive-const",
|
||||
/**
|
||||
* a const binding that may be a ref.
|
||||
*/
|
||||
SETUP_MAYBE_REF = "setup-maybe-ref",
|
||||
/**
|
||||
* bindings that are guaranteed to be refs
|
||||
*/
|
||||
SETUP_REF = "setup-ref",
|
||||
/**
|
||||
* declared by other options, e.g. computed, inject
|
||||
*/
|
||||
OPTIONS = "options"
|
||||
}
|
||||
|
||||
declare type CompiledResult = {
|
||||
ast: ASTElement | null;
|
||||
render: string;
|
||||
staticRenderFns: Array<string>;
|
||||
stringRenderFns?: Array<string>;
|
||||
errors?: Array<string | WarningMessage>;
|
||||
tips?: Array<string | WarningMessage>;
|
||||
};
|
||||
|
||||
export declare type CompilerOptions = {
|
||||
warn?: Function;
|
||||
modules?: Array<ModuleOptions>;
|
||||
directives?: {
|
||||
[key: string]: Function;
|
||||
};
|
||||
staticKeys?: string;
|
||||
isUnaryTag?: (tag: string) => boolean | undefined;
|
||||
canBeLeftOpenTag?: (tag: string) => boolean | undefined;
|
||||
isReservedTag?: (tag: string) => boolean | undefined;
|
||||
preserveWhitespace?: boolean;
|
||||
whitespace?: 'preserve' | 'condense';
|
||||
optimize?: boolean;
|
||||
mustUseProp?: (tag: string, type: string | null, name: string) => boolean;
|
||||
isPreTag?: (attr: string) => boolean | null;
|
||||
getTagNamespace?: (tag: string) => string | undefined;
|
||||
expectHTML?: boolean;
|
||||
isFromDOM?: boolean;
|
||||
shouldDecodeTags?: boolean;
|
||||
shouldDecodeNewlines?: boolean;
|
||||
shouldDecodeNewlinesForHref?: boolean;
|
||||
outputSourceRange?: boolean;
|
||||
shouldKeepComment?: boolean;
|
||||
delimiters?: [string, string];
|
||||
comments?: boolean;
|
||||
scopeId?: string;
|
||||
bindings?: BindingMetadata;
|
||||
};
|
||||
|
||||
/**
|
||||
* Compile `<script setup>`
|
||||
* It requires the whole SFC descriptor because we need to handle and merge
|
||||
* normal `<script>` + `<script setup>` if both are present.
|
||||
*/
|
||||
export declare function compileScript(sfc: SFCDescriptor, options?: SFCScriptCompileOptions): SFCScriptBlock;
|
||||
|
||||
export declare function compileStyle(options: SFCStyleCompileOptions): SFCStyleCompileResults;
|
||||
|
||||
export declare function compileStyleAsync(options: SFCStyleCompileOptions): Promise<SFCStyleCompileResults>;
|
||||
|
||||
export declare function compileTemplate(options: SFCTemplateCompileOptions): SFCTemplateCompileResults;
|
||||
|
||||
export declare function generateCodeFrame(source: string, start?: number, end?: number): string;
|
||||
|
||||
declare interface ImportBinding {
|
||||
isType: boolean;
|
||||
imported: string;
|
||||
source: string;
|
||||
isFromSetup: boolean;
|
||||
isUsedInTemplate: boolean;
|
||||
}
|
||||
|
||||
declare type ModuleOptions = {
|
||||
preTransformNode?: (el: ASTElement) => ASTElement | null | void;
|
||||
transformNode?: (el: ASTElement) => ASTElement | null | void;
|
||||
postTransformNode?: (el: ASTElement) => void;
|
||||
genData?: (el: ASTElement) => string;
|
||||
transformCode?: (el: ASTElement, code: string) => string;
|
||||
staticKeys?: Array<string>;
|
||||
};
|
||||
|
||||
export declare function parse(options: SFCParseOptions): SFCDescriptor;
|
||||
|
||||
/**
|
||||
* Parse a single-file component (*.vue) file into an SFC Descriptor Object.
|
||||
*/
|
||||
export declare function parseComponent(source: string, options?: VueTemplateCompilerParseOptions): SFCDescriptor;
|
||||
|
||||
declare interface RawSourceMap extends StartOfSourceMap {
|
||||
version: string;
|
||||
sources: string[];
|
||||
names: string[];
|
||||
sourcesContent?: string[];
|
||||
mappings: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility for rewriting `export default` in a script block into a variable
|
||||
* declaration so that we can inject things into it
|
||||
*/
|
||||
export declare function rewriteDefault(input: string, as: string, parserPlugins?: ParserPlugin[]): string;
|
||||
|
||||
export declare interface SFCBlock extends SFCCustomBlock {
|
||||
lang?: string;
|
||||
scoped?: boolean;
|
||||
module?: string | boolean;
|
||||
}
|
||||
|
||||
export declare interface SFCCustomBlock {
|
||||
type: string;
|
||||
content: string;
|
||||
attrs: {
|
||||
[key: string]: string | true;
|
||||
};
|
||||
start: number;
|
||||
end: number;
|
||||
src?: string;
|
||||
map?: RawSourceMap;
|
||||
}
|
||||
|
||||
export declare interface SFCDescriptor {
|
||||
source: string;
|
||||
filename: string;
|
||||
template: SFCBlock | null;
|
||||
script: SFCScriptBlock | null;
|
||||
scriptSetup: SFCScriptBlock | null;
|
||||
styles: SFCBlock[];
|
||||
customBlocks: SFCCustomBlock[];
|
||||
cssVars: string[];
|
||||
errors: (string | WarningMessage)[];
|
||||
/**
|
||||
* compare with an existing descriptor to determine whether HMR should perform
|
||||
* a reload vs. re-render.
|
||||
*
|
||||
* Note: this comparison assumes the prev/next script are already identical,
|
||||
* and only checks the special case where `<script setup lang="ts">` unused
|
||||
* import pruning result changes due to template changes.
|
||||
*/
|
||||
shouldForceReload: (prevImports: Record<string, ImportBinding>) => boolean;
|
||||
}
|
||||
|
||||
export declare interface SFCParseOptions {
|
||||
source: string;
|
||||
filename?: string;
|
||||
compiler?: TemplateCompiler;
|
||||
compilerParseOptions?: VueTemplateCompilerParseOptions;
|
||||
sourceRoot?: string;
|
||||
sourceMap?: boolean;
|
||||
/**
|
||||
* @deprecated use `sourceMap` instead.
|
||||
*/
|
||||
needMap?: boolean;
|
||||
}
|
||||
|
||||
export declare interface SFCScriptBlock extends SFCBlock {
|
||||
type: 'script';
|
||||
setup?: string | boolean;
|
||||
bindings?: BindingMetadata;
|
||||
imports?: Record<string, ImportBinding>;
|
||||
/**
|
||||
* import('\@babel/types').Statement
|
||||
*/
|
||||
scriptAst?: any[];
|
||||
/**
|
||||
* import('\@babel/types').Statement
|
||||
*/
|
||||
scriptSetupAst?: any[];
|
||||
}
|
||||
|
||||
export declare interface SFCScriptCompileOptions {
|
||||
/**
|
||||
* Scope ID for prefixing injected CSS variables.
|
||||
* This must be consistent with the `id` passed to `compileStyle`.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Production mode. Used to determine whether to generate hashed CSS variables
|
||||
*/
|
||||
isProd?: boolean;
|
||||
/**
|
||||
* Enable/disable source map. Defaults to true.
|
||||
*/
|
||||
sourceMap?: boolean;
|
||||
/**
|
||||
* https://babeljs.io/docs/en/babel-parser#plugins
|
||||
*/
|
||||
babelParserPlugins?: ParserPlugin[];
|
||||
}
|
||||
|
||||
export declare interface SFCStyleCompileOptions {
|
||||
source: string;
|
||||
filename: string;
|
||||
id: string;
|
||||
map?: any;
|
||||
scoped?: boolean;
|
||||
trim?: boolean;
|
||||
preprocessLang?: string;
|
||||
preprocessOptions?: any;
|
||||
postcssOptions?: any;
|
||||
postcssPlugins?: any[];
|
||||
isProd?: boolean;
|
||||
}
|
||||
|
||||
export declare interface SFCStyleCompileResults {
|
||||
code: string;
|
||||
map: any | void;
|
||||
rawResult: LazyResult | void;
|
||||
errors: string[];
|
||||
}
|
||||
|
||||
export declare interface SFCTemplateCompileOptions {
|
||||
source: string;
|
||||
filename: string;
|
||||
compiler?: TemplateCompiler;
|
||||
compilerOptions?: CompilerOptions;
|
||||
transformAssetUrls?: AssetURLOptions | boolean;
|
||||
transformAssetUrlsOptions?: TransformAssetUrlsOptions;
|
||||
preprocessLang?: string;
|
||||
preprocessOptions?: any;
|
||||
transpileOptions?: any;
|
||||
isProduction?: boolean;
|
||||
isFunctional?: boolean;
|
||||
optimizeSSR?: boolean;
|
||||
prettify?: boolean;
|
||||
isTS?: boolean;
|
||||
bindings?: BindingMetadata;
|
||||
}
|
||||
|
||||
export declare interface SFCTemplateCompileResults {
|
||||
ast: Object | undefined;
|
||||
code: string;
|
||||
source: string;
|
||||
tips: (string | WarningMessage)[];
|
||||
errors: (string | WarningMessage)[];
|
||||
}
|
||||
|
||||
declare interface StartOfSourceMap {
|
||||
file?: string;
|
||||
sourceRoot?: string;
|
||||
}
|
||||
|
||||
export declare interface TemplateCompiler {
|
||||
parseComponent(source: string, options?: any): SFCDescriptor;
|
||||
compile(template: string, options: CompilerOptions): CompiledResult;
|
||||
ssrCompile(template: string, options: CompilerOptions): CompiledResult;
|
||||
}
|
||||
|
||||
declare interface TransformAssetUrlsOptions {
|
||||
/**
|
||||
* If base is provided, instead of transforming relative asset urls into
|
||||
* imports, they will be directly rewritten to absolute urls.
|
||||
*/
|
||||
base?: string;
|
||||
/**
|
||||
* If true, also processes absolute urls.
|
||||
*/
|
||||
includeAbsolute?: boolean;
|
||||
}
|
||||
|
||||
declare interface VueTemplateCompilerParseOptions {
|
||||
pad?: 'line' | 'space' | boolean;
|
||||
deindent?: boolean;
|
||||
outputSourceRange?: boolean;
|
||||
}
|
||||
|
||||
export declare type WarningMessage = {
|
||||
msg: string;
|
||||
start?: number;
|
||||
end?: number;
|
||||
};
|
||||
|
||||
export { }
|
17902
node_modules/vue/packages/compiler-sfc/dist/compiler-sfc.js
generated
vendored
Normal file
17902
node_modules/vue/packages/compiler-sfc/dist/compiler-sfc.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
17
node_modules/vue/packages/compiler-sfc/node_modules/.bin/lessc
generated
vendored
Normal file
17
node_modules/vue/packages/compiler-sfc/node_modules/.bin/lessc
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -z "$NODE_PATH" ]; then
|
||||
export NODE_PATH="/Users/evan/Vue/vue/node_modules/.pnpm/node_modules"
|
||||
else
|
||||
export NODE_PATH="$NODE_PATH:/Users/evan/Vue/vue/node_modules/.pnpm/node_modules"
|
||||
fi
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/less@4.1.3/node_modules/less/bin/lessc" "$@"
|
||||
else
|
||||
exec node "$basedir/../../../../node_modules/.pnpm/less@4.1.3/node_modules/less/bin/lessc" "$@"
|
||||
fi
|
17
node_modules/vue/packages/compiler-sfc/node_modules/.bin/parser
generated
vendored
Normal file
17
node_modules/vue/packages/compiler-sfc/node_modules/.bin/parser
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -z "$NODE_PATH" ]; then
|
||||
export NODE_PATH="/Users/evan/Vue/vue/node_modules/.pnpm/node_modules"
|
||||
else
|
||||
export NODE_PATH="$NODE_PATH:/Users/evan/Vue/vue/node_modules/.pnpm/node_modules"
|
||||
fi
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/@babel+parser@7.19.4/node_modules/@babel/parser/bin/babel-parser.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../../../../node_modules/.pnpm/@babel+parser@7.19.4/node_modules/@babel/parser/bin/babel-parser.js" "$@"
|
||||
fi
|
17
node_modules/vue/packages/compiler-sfc/node_modules/.bin/sass
generated
vendored
Normal file
17
node_modules/vue/packages/compiler-sfc/node_modules/.bin/sass
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -z "$NODE_PATH" ]; then
|
||||
export NODE_PATH="/Users/evan/Vue/vue/node_modules/.pnpm/node_modules"
|
||||
else
|
||||
export NODE_PATH="$NODE_PATH:/Users/evan/Vue/vue/node_modules/.pnpm/node_modules"
|
||||
fi
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/sass@1.55.0/node_modules/sass/sass.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../../../../node_modules/.pnpm/sass@1.55.0/node_modules/sass/sass.js" "$@"
|
||||
fi
|
17
node_modules/vue/packages/compiler-sfc/node_modules/.bin/stylus
generated
vendored
Normal file
17
node_modules/vue/packages/compiler-sfc/node_modules/.bin/stylus
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
||||
esac
|
||||
|
||||
if [ -z "$NODE_PATH" ]; then
|
||||
export NODE_PATH="/Users/evan/Vue/vue/node_modules/.pnpm/node_modules"
|
||||
else
|
||||
export NODE_PATH="$NODE_PATH:/Users/evan/Vue/vue/node_modules/.pnpm/node_modules"
|
||||
fi
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../../../../node_modules/.pnpm/stylus@0.58.1/node_modules/stylus/bin/stylus" "$@"
|
||||
else
|
||||
exec node "$basedir/../../../../node_modules/.pnpm/stylus@0.58.1/node_modules/stylus/bin/stylus" "$@"
|
||||
fi
|
34
node_modules/vue/packages/compiler-sfc/package.json
generated
vendored
Normal file
34
node_modules/vue/packages/compiler-sfc/package.json
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"name": "@vue/compiler-sfc",
|
||||
"version": "2.7.14",
|
||||
"description": "compiler-sfc for Vue 2",
|
||||
"main": "dist/compiler-sfc.js",
|
||||
"types": "dist/compiler-sfc.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.18.4",
|
||||
"postcss": "^8.4.14",
|
||||
"source-map": "^0.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/types": "^7.19.4",
|
||||
"@types/estree": "^0.0.48",
|
||||
"@types/hash-sum": "^1.0.0",
|
||||
"@types/lru-cache": "^5.1.1",
|
||||
"@vue/consolidate": "^0.17.3",
|
||||
"de-indent": "^1.0.2",
|
||||
"estree-walker": "^2.0.2",
|
||||
"hash-sum": "^2.0.0",
|
||||
"less": "^4.1.3",
|
||||
"lru-cache": "^5.1.1",
|
||||
"magic-string": "^0.25.9",
|
||||
"merge-source-map": "^1.1.0",
|
||||
"postcss-modules": "^4.3.1",
|
||||
"postcss-selector-parser": "^6.0.10",
|
||||
"pug": "^3.0.2",
|
||||
"sass": "^1.52.3",
|
||||
"stylus": "^0.58.1"
|
||||
}
|
||||
}
|
423
node_modules/vue/packages/compiler-sfc/src/babelUtils.ts
generated
vendored
Normal file
423
node_modules/vue/packages/compiler-sfc/src/babelUtils.ts
generated
vendored
Normal file
@ -0,0 +1,423 @@
|
||||
// https://github.com/vuejs/core/blob/main/packages/compiler-core/src/babelUtils.ts
|
||||
|
||||
// should only use types from @babel/types
|
||||
// do not import runtime methods
|
||||
import type {
|
||||
Identifier,
|
||||
Node,
|
||||
Function,
|
||||
ObjectProperty,
|
||||
BlockStatement,
|
||||
Program
|
||||
} from '@babel/types'
|
||||
import { walk } from 'estree-walker'
|
||||
|
||||
export function walkIdentifiers(
|
||||
root: Node,
|
||||
onIdentifier: (
|
||||
node: Identifier,
|
||||
parent: Node,
|
||||
parentStack: Node[],
|
||||
isReference: boolean,
|
||||
isLocal: boolean
|
||||
) => void,
|
||||
onNode?: (node: Node) => void
|
||||
) {
|
||||
const includeAll = false
|
||||
const parentStack: Node[] = []
|
||||
const knownIds: Record<string, number> = Object.create(null)
|
||||
|
||||
const rootExp =
|
||||
root.type === 'Program' &&
|
||||
root.body[0].type === 'ExpressionStatement' &&
|
||||
root.body[0].expression
|
||||
|
||||
;(walk as any)(root, {
|
||||
enter(node: Node & { scopeIds?: Set<string> }, parent: Node | undefined) {
|
||||
parent && parentStack.push(parent)
|
||||
if (
|
||||
parent &&
|
||||
parent.type.startsWith('TS') &&
|
||||
parent.type !== 'TSAsExpression' &&
|
||||
parent.type !== 'TSNonNullExpression' &&
|
||||
parent.type !== 'TSTypeAssertion'
|
||||
) {
|
||||
return this.skip()
|
||||
}
|
||||
|
||||
if (onNode) onNode(node)
|
||||
|
||||
if (node.type === 'Identifier') {
|
||||
const isLocal = !!knownIds[node.name]
|
||||
const isRefed = isReferencedIdentifier(node, parent!, parentStack)
|
||||
if (includeAll || (isRefed && !isLocal)) {
|
||||
onIdentifier(node, parent!, parentStack, isRefed, isLocal)
|
||||
}
|
||||
} else if (
|
||||
node.type === 'ObjectProperty' &&
|
||||
parent!.type === 'ObjectPattern'
|
||||
) {
|
||||
// mark property in destructure pattern
|
||||
;(node as any).inPattern = true
|
||||
} else if (isFunctionType(node)) {
|
||||
// walk function expressions and add its arguments to known identifiers
|
||||
// so that we don't prefix them
|
||||
walkFunctionParams(node, id => markScopeIdentifier(node, id, knownIds))
|
||||
} else if (node.type === 'BlockStatement') {
|
||||
// #3445 record block-level local variables
|
||||
walkBlockDeclarations(node, id =>
|
||||
markScopeIdentifier(node, id, knownIds)
|
||||
)
|
||||
}
|
||||
},
|
||||
leave(node: Node & { scopeIds?: Set<string> }, parent: Node | undefined) {
|
||||
parent && parentStack.pop()
|
||||
if (node !== rootExp && node.scopeIds) {
|
||||
for (const id of node.scopeIds) {
|
||||
knownIds[id]--
|
||||
if (knownIds[id] === 0) {
|
||||
delete knownIds[id]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function isReferencedIdentifier(
|
||||
id: Identifier,
|
||||
parent: Node | null,
|
||||
parentStack: Node[]
|
||||
) {
|
||||
if (!parent) {
|
||||
return true
|
||||
}
|
||||
|
||||
// is a special keyword but parsed as identifier
|
||||
if (id.name === 'arguments') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (isReferenced(id, parent)) {
|
||||
return true
|
||||
}
|
||||
|
||||
// babel's isReferenced check returns false for ids being assigned to, so we
|
||||
// need to cover those cases here
|
||||
switch (parent.type) {
|
||||
case 'AssignmentExpression':
|
||||
case 'AssignmentPattern':
|
||||
return true
|
||||
case 'ObjectPattern':
|
||||
case 'ArrayPattern':
|
||||
return isInDestructureAssignment(parent, parentStack)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
export function isInDestructureAssignment(
|
||||
parent: Node,
|
||||
parentStack: Node[]
|
||||
): boolean {
|
||||
if (
|
||||
parent &&
|
||||
(parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')
|
||||
) {
|
||||
let i = parentStack.length
|
||||
while (i--) {
|
||||
const p = parentStack[i]
|
||||
if (p.type === 'AssignmentExpression') {
|
||||
return true
|
||||
} else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export function walkFunctionParams(
|
||||
node: Function,
|
||||
onIdent: (id: Identifier) => void
|
||||
) {
|
||||
for (const p of node.params) {
|
||||
for (const id of extractIdentifiers(p)) {
|
||||
onIdent(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function walkBlockDeclarations(
|
||||
block: BlockStatement | Program,
|
||||
onIdent: (node: Identifier) => void
|
||||
) {
|
||||
for (const stmt of block.body) {
|
||||
if (stmt.type === 'VariableDeclaration') {
|
||||
if (stmt.declare) continue
|
||||
for (const decl of stmt.declarations) {
|
||||
for (const id of extractIdentifiers(decl.id)) {
|
||||
onIdent(id)
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
stmt.type === 'FunctionDeclaration' ||
|
||||
stmt.type === 'ClassDeclaration'
|
||||
) {
|
||||
if (stmt.declare || !stmt.id) continue
|
||||
onIdent(stmt.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function extractIdentifiers(
|
||||
param: Node,
|
||||
nodes: Identifier[] = []
|
||||
): Identifier[] {
|
||||
switch (param.type) {
|
||||
case 'Identifier':
|
||||
nodes.push(param)
|
||||
break
|
||||
|
||||
case 'MemberExpression':
|
||||
let object: any = param
|
||||
while (object.type === 'MemberExpression') {
|
||||
object = object.object
|
||||
}
|
||||
nodes.push(object)
|
||||
break
|
||||
|
||||
case 'ObjectPattern':
|
||||
for (const prop of param.properties) {
|
||||
if (prop.type === 'RestElement') {
|
||||
extractIdentifiers(prop.argument, nodes)
|
||||
} else {
|
||||
extractIdentifiers(prop.value, nodes)
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
case 'ArrayPattern':
|
||||
param.elements.forEach(element => {
|
||||
if (element) extractIdentifiers(element, nodes)
|
||||
})
|
||||
break
|
||||
|
||||
case 'RestElement':
|
||||
extractIdentifiers(param.argument, nodes)
|
||||
break
|
||||
|
||||
case 'AssignmentPattern':
|
||||
extractIdentifiers(param.left, nodes)
|
||||
break
|
||||
}
|
||||
|
||||
return nodes
|
||||
}
|
||||
|
||||
function markScopeIdentifier(
|
||||
node: Node & { scopeIds?: Set<string> },
|
||||
child: Identifier,
|
||||
knownIds: Record<string, number>
|
||||
) {
|
||||
const { name } = child
|
||||
if (node.scopeIds && node.scopeIds.has(name)) {
|
||||
return
|
||||
}
|
||||
if (name in knownIds) {
|
||||
knownIds[name]++
|
||||
} else {
|
||||
knownIds[name] = 1
|
||||
}
|
||||
;(node.scopeIds || (node.scopeIds = new Set())).add(name)
|
||||
}
|
||||
|
||||
export const isFunctionType = (node: Node): node is Function => {
|
||||
return /Function(?:Expression|Declaration)$|Method$/.test(node.type)
|
||||
}
|
||||
|
||||
export const isStaticProperty = (node: Node): node is ObjectProperty =>
|
||||
node &&
|
||||
(node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
|
||||
!node.computed
|
||||
|
||||
export const isStaticPropertyKey = (node: Node, parent: Node) =>
|
||||
isStaticProperty(parent) && parent.key === node
|
||||
|
||||
/**
|
||||
* Copied from https://github.com/babel/babel/blob/main/packages/babel-types/src/validators/isReferenced.ts
|
||||
* To avoid runtime dependency on @babel/types (which includes process references)
|
||||
* This file should not change very often in babel but we may need to keep it
|
||||
* up-to-date from time to time.
|
||||
*
|
||||
* https://github.com/babel/babel/blob/main/LICENSE
|
||||
*
|
||||
*/
|
||||
function isReferenced(node: Node, parent: Node, grandparent?: Node): boolean {
|
||||
switch (parent.type) {
|
||||
// yes: PARENT[NODE]
|
||||
// yes: NODE.child
|
||||
// no: parent.NODE
|
||||
case 'MemberExpression':
|
||||
case 'OptionalMemberExpression':
|
||||
if (parent.property === node) {
|
||||
return !!parent.computed
|
||||
}
|
||||
return parent.object === node
|
||||
|
||||
case 'JSXMemberExpression':
|
||||
return parent.object === node
|
||||
// no: let NODE = init;
|
||||
// yes: let id = NODE;
|
||||
case 'VariableDeclarator':
|
||||
return parent.init === node
|
||||
|
||||
// yes: () => NODE
|
||||
// no: (NODE) => {}
|
||||
case 'ArrowFunctionExpression':
|
||||
return parent.body === node
|
||||
|
||||
// no: class { #NODE; }
|
||||
// no: class { get #NODE() {} }
|
||||
// no: class { #NODE() {} }
|
||||
// no: class { fn() { return this.#NODE; } }
|
||||
case 'PrivateName':
|
||||
return false
|
||||
|
||||
// no: class { NODE() {} }
|
||||
// yes: class { [NODE]() {} }
|
||||
// no: class { foo(NODE) {} }
|
||||
case 'ClassMethod':
|
||||
case 'ClassPrivateMethod':
|
||||
case 'ObjectMethod':
|
||||
if (parent.key === node) {
|
||||
return !!parent.computed
|
||||
}
|
||||
return false
|
||||
|
||||
// yes: { [NODE]: "" }
|
||||
// no: { NODE: "" }
|
||||
// depends: { NODE }
|
||||
// depends: { key: NODE }
|
||||
case 'ObjectProperty':
|
||||
if (parent.key === node) {
|
||||
return !!parent.computed
|
||||
}
|
||||
// parent.value === node
|
||||
return !grandparent || grandparent.type !== 'ObjectPattern'
|
||||
// no: class { NODE = value; }
|
||||
// yes: class { [NODE] = value; }
|
||||
// yes: class { key = NODE; }
|
||||
case 'ClassProperty':
|
||||
if (parent.key === node) {
|
||||
return !!parent.computed
|
||||
}
|
||||
return true
|
||||
case 'ClassPrivateProperty':
|
||||
return parent.key !== node
|
||||
|
||||
// no: class NODE {}
|
||||
// yes: class Foo extends NODE {}
|
||||
case 'ClassDeclaration':
|
||||
case 'ClassExpression':
|
||||
return parent.superClass === node
|
||||
|
||||
// yes: left = NODE;
|
||||
// no: NODE = right;
|
||||
case 'AssignmentExpression':
|
||||
return parent.right === node
|
||||
|
||||
// no: [NODE = foo] = [];
|
||||
// yes: [foo = NODE] = [];
|
||||
case 'AssignmentPattern':
|
||||
return parent.right === node
|
||||
|
||||
// no: NODE: for (;;) {}
|
||||
case 'LabeledStatement':
|
||||
return false
|
||||
|
||||
// no: try {} catch (NODE) {}
|
||||
case 'CatchClause':
|
||||
return false
|
||||
|
||||
// no: function foo(...NODE) {}
|
||||
case 'RestElement':
|
||||
return false
|
||||
|
||||
case 'BreakStatement':
|
||||
case 'ContinueStatement':
|
||||
return false
|
||||
|
||||
// no: function NODE() {}
|
||||
// no: function foo(NODE) {}
|
||||
case 'FunctionDeclaration':
|
||||
case 'FunctionExpression':
|
||||
return false
|
||||
|
||||
// no: export NODE from "foo";
|
||||
// no: export * as NODE from "foo";
|
||||
case 'ExportNamespaceSpecifier':
|
||||
case 'ExportDefaultSpecifier':
|
||||
return false
|
||||
|
||||
// no: export { foo as NODE };
|
||||
// yes: export { NODE as foo };
|
||||
// no: export { NODE as foo } from "foo";
|
||||
case 'ExportSpecifier':
|
||||
// @ts-expect-error
|
||||
if (grandparent?.source) {
|
||||
return false
|
||||
}
|
||||
return parent.local === node
|
||||
|
||||
// no: import NODE from "foo";
|
||||
// no: import * as NODE from "foo";
|
||||
// no: import { NODE as foo } from "foo";
|
||||
// no: import { foo as NODE } from "foo";
|
||||
// no: import NODE from "bar";
|
||||
case 'ImportDefaultSpecifier':
|
||||
case 'ImportNamespaceSpecifier':
|
||||
case 'ImportSpecifier':
|
||||
return false
|
||||
|
||||
// no: import "foo" assert { NODE: "json" }
|
||||
case 'ImportAttribute':
|
||||
return false
|
||||
|
||||
// no: <div NODE="foo" />
|
||||
case 'JSXAttribute':
|
||||
return false
|
||||
|
||||
// no: [NODE] = [];
|
||||
// no: ({ NODE }) = [];
|
||||
case 'ObjectPattern':
|
||||
case 'ArrayPattern':
|
||||
return false
|
||||
|
||||
// no: new.NODE
|
||||
// no: NODE.target
|
||||
case 'MetaProperty':
|
||||
return false
|
||||
|
||||
// yes: type X = { someProperty: NODE }
|
||||
// no: type X = { NODE: OtherType }
|
||||
case 'ObjectTypeProperty':
|
||||
return parent.key !== node
|
||||
|
||||
// yes: enum X { Foo = NODE }
|
||||
// no: enum X { NODE }
|
||||
case 'TSEnumMember':
|
||||
return parent.id !== node
|
||||
|
||||
// yes: { [NODE]: value }
|
||||
// no: { NODE: value }
|
||||
case 'TSPropertySignature':
|
||||
if (parent.key === node) {
|
||||
return !!parent.computed
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
1911
node_modules/vue/packages/compiler-sfc/src/compileScript.ts
generated
vendored
Normal file
1911
node_modules/vue/packages/compiler-sfc/src/compileScript.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
147
node_modules/vue/packages/compiler-sfc/src/compileStyle.ts
generated
vendored
Normal file
147
node_modules/vue/packages/compiler-sfc/src/compileStyle.ts
generated
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
const postcss = require('postcss')
|
||||
import { ProcessOptions, LazyResult } from 'postcss'
|
||||
import trimPlugin from './stylePlugins/trim'
|
||||
import scopedPlugin from './stylePlugins/scoped'
|
||||
import {
|
||||
processors,
|
||||
StylePreprocessor,
|
||||
StylePreprocessorResults
|
||||
} from './stylePreprocessors'
|
||||
import { cssVarsPlugin } from './cssVars'
|
||||
|
||||
export interface SFCStyleCompileOptions {
|
||||
source: string
|
||||
filename: string
|
||||
id: string
|
||||
map?: any
|
||||
scoped?: boolean
|
||||
trim?: boolean
|
||||
preprocessLang?: string
|
||||
preprocessOptions?: any
|
||||
postcssOptions?: any
|
||||
postcssPlugins?: any[]
|
||||
isProd?: boolean
|
||||
}
|
||||
|
||||
export interface SFCAsyncStyleCompileOptions extends SFCStyleCompileOptions {
|
||||
isAsync?: boolean
|
||||
}
|
||||
|
||||
export interface SFCStyleCompileResults {
|
||||
code: string
|
||||
map: any | void
|
||||
rawResult: LazyResult | void
|
||||
errors: string[]
|
||||
}
|
||||
|
||||
export function compileStyle(
|
||||
options: SFCStyleCompileOptions
|
||||
): SFCStyleCompileResults {
|
||||
return doCompileStyle({ ...options, isAsync: false })
|
||||
}
|
||||
|
||||
export function compileStyleAsync(
|
||||
options: SFCStyleCompileOptions
|
||||
): Promise<SFCStyleCompileResults> {
|
||||
return Promise.resolve(doCompileStyle({ ...options, isAsync: true }))
|
||||
}
|
||||
|
||||
export function doCompileStyle(
|
||||
options: SFCAsyncStyleCompileOptions
|
||||
): SFCStyleCompileResults {
|
||||
const {
|
||||
filename,
|
||||
id,
|
||||
scoped = true,
|
||||
trim = true,
|
||||
isProd = false,
|
||||
preprocessLang,
|
||||
postcssOptions,
|
||||
postcssPlugins
|
||||
} = options
|
||||
const preprocessor = preprocessLang && processors[preprocessLang]
|
||||
const preProcessedSource = preprocessor && preprocess(options, preprocessor)
|
||||
const map = preProcessedSource ? preProcessedSource.map : options.map
|
||||
const source = preProcessedSource ? preProcessedSource.code : options.source
|
||||
|
||||
const plugins = (postcssPlugins || []).slice()
|
||||
plugins.unshift(cssVarsPlugin({ id: id.replace(/^data-v-/, ''), isProd }))
|
||||
if (trim) {
|
||||
plugins.push(trimPlugin())
|
||||
}
|
||||
if (scoped) {
|
||||
plugins.push(scopedPlugin(id))
|
||||
}
|
||||
|
||||
const postCSSOptions: ProcessOptions = {
|
||||
...postcssOptions,
|
||||
to: filename,
|
||||
from: filename
|
||||
}
|
||||
if (map) {
|
||||
postCSSOptions.map = {
|
||||
inline: false,
|
||||
annotation: false,
|
||||
prev: map
|
||||
}
|
||||
}
|
||||
|
||||
let result, code, outMap
|
||||
const errors: any[] = []
|
||||
if (preProcessedSource && preProcessedSource.errors.length) {
|
||||
errors.push(...preProcessedSource.errors)
|
||||
}
|
||||
try {
|
||||
result = postcss(plugins).process(source, postCSSOptions)
|
||||
|
||||
// In async mode, return a promise.
|
||||
if (options.isAsync) {
|
||||
return result
|
||||
.then(
|
||||
(result: LazyResult): SFCStyleCompileResults => ({
|
||||
code: result.css || '',
|
||||
map: result.map && result.map.toJSON(),
|
||||
errors,
|
||||
rawResult: result
|
||||
})
|
||||
)
|
||||
.catch(
|
||||
(error: Error): SFCStyleCompileResults => ({
|
||||
code: '',
|
||||
map: undefined,
|
||||
errors: [...errors, error.message],
|
||||
rawResult: undefined
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
// force synchronous transform (we know we only have sync plugins)
|
||||
code = result.css
|
||||
outMap = result.map
|
||||
} catch (e) {
|
||||
errors.push(e)
|
||||
}
|
||||
|
||||
return {
|
||||
code: code || ``,
|
||||
map: outMap && outMap.toJSON(),
|
||||
errors,
|
||||
rawResult: result
|
||||
}
|
||||
}
|
||||
|
||||
function preprocess(
|
||||
options: SFCStyleCompileOptions,
|
||||
preprocessor: StylePreprocessor
|
||||
): StylePreprocessorResults {
|
||||
return preprocessor(
|
||||
options.source,
|
||||
options.map,
|
||||
Object.assign(
|
||||
{
|
||||
filename: options.filename
|
||||
},
|
||||
options.preprocessOptions
|
||||
)
|
||||
)
|
||||
}
|
205
node_modules/vue/packages/compiler-sfc/src/compileTemplate.ts
generated
vendored
Normal file
205
node_modules/vue/packages/compiler-sfc/src/compileTemplate.ts
generated
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
import { BindingMetadata, TemplateCompiler } from './types'
|
||||
import assetUrlsModule, {
|
||||
AssetURLOptions,
|
||||
TransformAssetUrlsOptions
|
||||
} from './templateCompilerModules/assetUrl'
|
||||
import srcsetModule from './templateCompilerModules/srcset'
|
||||
import consolidate from '@vue/consolidate'
|
||||
import * as _compiler from 'web/entry-compiler'
|
||||
import { prefixIdentifiers } from './prefixIdentifiers'
|
||||
import { CompilerOptions, WarningMessage } from 'types/compiler'
|
||||
|
||||
export interface SFCTemplateCompileOptions {
|
||||
source: string
|
||||
filename: string
|
||||
compiler?: TemplateCompiler
|
||||
compilerOptions?: CompilerOptions
|
||||
transformAssetUrls?: AssetURLOptions | boolean
|
||||
transformAssetUrlsOptions?: TransformAssetUrlsOptions
|
||||
preprocessLang?: string
|
||||
preprocessOptions?: any
|
||||
transpileOptions?: any
|
||||
isProduction?: boolean
|
||||
isFunctional?: boolean
|
||||
optimizeSSR?: boolean
|
||||
prettify?: boolean
|
||||
isTS?: boolean
|
||||
bindings?: BindingMetadata
|
||||
}
|
||||
|
||||
export interface SFCTemplateCompileResults {
|
||||
ast: Object | undefined
|
||||
code: string
|
||||
source: string
|
||||
tips: (string | WarningMessage)[]
|
||||
errors: (string | WarningMessage)[]
|
||||
}
|
||||
|
||||
export function compileTemplate(
|
||||
options: SFCTemplateCompileOptions
|
||||
): SFCTemplateCompileResults {
|
||||
const { preprocessLang } = options
|
||||
const preprocessor = preprocessLang && consolidate[preprocessLang]
|
||||
if (preprocessor) {
|
||||
return actuallyCompile(
|
||||
Object.assign({}, options, {
|
||||
source: preprocess(options, preprocessor)
|
||||
})
|
||||
)
|
||||
} else if (preprocessLang) {
|
||||
return {
|
||||
ast: {},
|
||||
code: `var render = function () {}\n` + `var staticRenderFns = []\n`,
|
||||
source: options.source,
|
||||
tips: [
|
||||
`Component ${options.filename} uses lang ${preprocessLang} for template. Please install the language preprocessor.`
|
||||
],
|
||||
errors: [
|
||||
`Component ${options.filename} uses lang ${preprocessLang} for template, however it is not installed.`
|
||||
]
|
||||
}
|
||||
} else {
|
||||
return actuallyCompile(options)
|
||||
}
|
||||
}
|
||||
|
||||
function preprocess(
|
||||
options: SFCTemplateCompileOptions,
|
||||
preprocessor: any
|
||||
): string {
|
||||
const { source, filename, preprocessOptions } = options
|
||||
|
||||
const finalPreprocessOptions = Object.assign(
|
||||
{
|
||||
filename
|
||||
},
|
||||
preprocessOptions
|
||||
)
|
||||
|
||||
// Consolidate exposes a callback based API, but the callback is in fact
|
||||
// called synchronously for most templating engines. In our case, we have to
|
||||
// expose a synchronous API so that it is usable in Jest transforms (which
|
||||
// have to be sync because they are applied via Node.js require hooks)
|
||||
let res: any, err
|
||||
preprocessor.render(
|
||||
source,
|
||||
finalPreprocessOptions,
|
||||
(_err: Error | null, _res: string) => {
|
||||
if (_err) err = _err
|
||||
res = _res
|
||||
}
|
||||
)
|
||||
|
||||
if (err) throw err
|
||||
return res
|
||||
}
|
||||
|
||||
function actuallyCompile(
|
||||
options: SFCTemplateCompileOptions
|
||||
): SFCTemplateCompileResults {
|
||||
const {
|
||||
source,
|
||||
compiler = _compiler,
|
||||
compilerOptions = {},
|
||||
transpileOptions = {},
|
||||
transformAssetUrls,
|
||||
transformAssetUrlsOptions,
|
||||
isProduction = process.env.NODE_ENV === 'production',
|
||||
isFunctional = false,
|
||||
optimizeSSR = false,
|
||||
prettify = true,
|
||||
isTS = false,
|
||||
bindings
|
||||
} = options
|
||||
|
||||
const compile =
|
||||
optimizeSSR && compiler.ssrCompile ? compiler.ssrCompile : compiler.compile
|
||||
|
||||
let finalCompilerOptions = compilerOptions
|
||||
if (transformAssetUrls) {
|
||||
const builtInModules = [
|
||||
transformAssetUrls === true
|
||||
? assetUrlsModule(undefined, transformAssetUrlsOptions)
|
||||
: assetUrlsModule(transformAssetUrls, transformAssetUrlsOptions),
|
||||
srcsetModule(transformAssetUrlsOptions)
|
||||
]
|
||||
finalCompilerOptions = Object.assign({}, compilerOptions, {
|
||||
modules: [...builtInModules, ...(compilerOptions.modules || [])],
|
||||
filename: options.filename
|
||||
})
|
||||
}
|
||||
finalCompilerOptions.bindings = bindings
|
||||
|
||||
const { ast, render, staticRenderFns, tips, errors } = compile(
|
||||
source,
|
||||
finalCompilerOptions
|
||||
)
|
||||
|
||||
if (errors && errors.length) {
|
||||
return {
|
||||
ast,
|
||||
code: `var render = function () {}\n` + `var staticRenderFns = []\n`,
|
||||
source,
|
||||
tips,
|
||||
errors
|
||||
}
|
||||
} else {
|
||||
// stripping `with` usage
|
||||
let code =
|
||||
`var __render__ = ${prefixIdentifiers(
|
||||
`function render(${isFunctional ? `_c,_vm` : ``}){${render}\n}`,
|
||||
isFunctional,
|
||||
isTS,
|
||||
transpileOptions,
|
||||
bindings
|
||||
)}\n` +
|
||||
`var __staticRenderFns__ = [${staticRenderFns.map(code =>
|
||||
prefixIdentifiers(
|
||||
`function (${isFunctional ? `_c,_vm` : ``}){${code}\n}`,
|
||||
isFunctional,
|
||||
isTS,
|
||||
transpileOptions,
|
||||
bindings
|
||||
)
|
||||
)}]` +
|
||||
`\n`
|
||||
|
||||
// #23 we use __render__ to avoid `render` not being prefixed by the
|
||||
// transpiler when stripping with, but revert it back to `render` to
|
||||
// maintain backwards compat
|
||||
code = code.replace(/\s__(render|staticRenderFns)__\s/g, ' $1 ')
|
||||
|
||||
if (!isProduction) {
|
||||
// mark with stripped (this enables Vue to use correct runtime proxy
|
||||
// detection)
|
||||
code += `render._withStripped = true`
|
||||
|
||||
if (prettify) {
|
||||
try {
|
||||
code = require('prettier').format(code, {
|
||||
semi: false,
|
||||
parser: 'babel'
|
||||
})
|
||||
} catch (e: any) {
|
||||
if (e.code === 'MODULE_NOT_FOUND') {
|
||||
tips.push(
|
||||
'The `prettify` option is on, but the dependency `prettier` is not found.\n' +
|
||||
'Please either turn off `prettify` or manually install `prettier`.'
|
||||
)
|
||||
}
|
||||
tips.push(
|
||||
`Failed to prettify component ${options.filename} template source after compilation.`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ast,
|
||||
code,
|
||||
source,
|
||||
tips,
|
||||
errors
|
||||
}
|
||||
}
|
||||
}
|
179
node_modules/vue/packages/compiler-sfc/src/cssVars.ts
generated
vendored
Normal file
179
node_modules/vue/packages/compiler-sfc/src/cssVars.ts
generated
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
import { BindingMetadata } from './types'
|
||||
import { SFCDescriptor } from './parseComponent'
|
||||
import { PluginCreator } from 'postcss'
|
||||
import hash from 'hash-sum'
|
||||
import { prefixIdentifiers } from './prefixIdentifiers'
|
||||
|
||||
export const CSS_VARS_HELPER = `useCssVars`
|
||||
|
||||
export function genCssVarsFromList(
|
||||
vars: string[],
|
||||
id: string,
|
||||
isProd: boolean,
|
||||
isSSR = false
|
||||
): string {
|
||||
return `{\n ${vars
|
||||
.map(
|
||||
key => `"${isSSR ? `--` : ``}${genVarName(id, key, isProd)}": (${key})`
|
||||
)
|
||||
.join(',\n ')}\n}`
|
||||
}
|
||||
|
||||
function genVarName(id: string, raw: string, isProd: boolean): string {
|
||||
if (isProd) {
|
||||
return hash(id + raw)
|
||||
} else {
|
||||
return `${id}-${raw.replace(/([^\w-])/g, '_')}`
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeExpression(exp: string) {
|
||||
exp = exp.trim()
|
||||
if (
|
||||
(exp[0] === `'` && exp[exp.length - 1] === `'`) ||
|
||||
(exp[0] === `"` && exp[exp.length - 1] === `"`)
|
||||
) {
|
||||
return exp.slice(1, -1)
|
||||
}
|
||||
return exp
|
||||
}
|
||||
|
||||
const vBindRE = /v-bind\s*\(/g
|
||||
|
||||
export function parseCssVars(sfc: SFCDescriptor): string[] {
|
||||
const vars: string[] = []
|
||||
sfc.styles.forEach(style => {
|
||||
let match
|
||||
// ignore v-bind() in comments /* ... */
|
||||
const content = style.content.replace(/\/\*([\s\S]*?)\*\//g, '')
|
||||
while ((match = vBindRE.exec(content))) {
|
||||
const start = match.index + match[0].length
|
||||
const end = lexBinding(content, start)
|
||||
if (end !== null) {
|
||||
const variable = normalizeExpression(content.slice(start, end))
|
||||
if (!vars.includes(variable)) {
|
||||
vars.push(variable)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return vars
|
||||
}
|
||||
|
||||
const enum LexerState {
|
||||
inParens,
|
||||
inSingleQuoteString,
|
||||
inDoubleQuoteString
|
||||
}
|
||||
|
||||
function lexBinding(content: string, start: number): number | null {
|
||||
let state: LexerState = LexerState.inParens
|
||||
let parenDepth = 0
|
||||
|
||||
for (let i = start; i < content.length; i++) {
|
||||
const char = content.charAt(i)
|
||||
switch (state) {
|
||||
case LexerState.inParens:
|
||||
if (char === `'`) {
|
||||
state = LexerState.inSingleQuoteString
|
||||
} else if (char === `"`) {
|
||||
state = LexerState.inDoubleQuoteString
|
||||
} else if (char === `(`) {
|
||||
parenDepth++
|
||||
} else if (char === `)`) {
|
||||
if (parenDepth > 0) {
|
||||
parenDepth--
|
||||
} else {
|
||||
return i
|
||||
}
|
||||
}
|
||||
break
|
||||
case LexerState.inSingleQuoteString:
|
||||
if (char === `'`) {
|
||||
state = LexerState.inParens
|
||||
}
|
||||
break
|
||||
case LexerState.inDoubleQuoteString:
|
||||
if (char === `"`) {
|
||||
state = LexerState.inParens
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// for compileStyle
|
||||
export interface CssVarsPluginOptions {
|
||||
id: string
|
||||
isProd: boolean
|
||||
}
|
||||
|
||||
export const cssVarsPlugin: PluginCreator<CssVarsPluginOptions> = opts => {
|
||||
const { id, isProd } = opts!
|
||||
return {
|
||||
postcssPlugin: 'vue-sfc-vars',
|
||||
Declaration(decl) {
|
||||
// rewrite CSS variables
|
||||
const value = decl.value
|
||||
if (vBindRE.test(value)) {
|
||||
vBindRE.lastIndex = 0
|
||||
let transformed = ''
|
||||
let lastIndex = 0
|
||||
let match
|
||||
while ((match = vBindRE.exec(value))) {
|
||||
const start = match.index + match[0].length
|
||||
const end = lexBinding(value, start)
|
||||
if (end !== null) {
|
||||
const variable = normalizeExpression(value.slice(start, end))
|
||||
transformed +=
|
||||
value.slice(lastIndex, match.index) +
|
||||
`var(--${genVarName(id, variable, isProd)})`
|
||||
lastIndex = end + 1
|
||||
}
|
||||
}
|
||||
decl.value = transformed + value.slice(lastIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cssVarsPlugin.postcss = true
|
||||
|
||||
export function genCssVarsCode(
|
||||
vars: string[],
|
||||
bindings: BindingMetadata,
|
||||
id: string,
|
||||
isProd: boolean
|
||||
) {
|
||||
const varsExp = genCssVarsFromList(vars, id, isProd)
|
||||
return `_${CSS_VARS_HELPER}((_vm, _setup) => ${prefixIdentifiers(
|
||||
`(${varsExp})`,
|
||||
false,
|
||||
false,
|
||||
undefined,
|
||||
bindings
|
||||
)})`
|
||||
}
|
||||
|
||||
// <script setup> already gets the calls injected as part of the transform
|
||||
// this is only for single normal <script>
|
||||
export function genNormalScriptCssVarsCode(
|
||||
cssVars: string[],
|
||||
bindings: BindingMetadata,
|
||||
id: string,
|
||||
isProd: boolean
|
||||
): string {
|
||||
return (
|
||||
`\nimport { ${CSS_VARS_HELPER} as _${CSS_VARS_HELPER} } from 'vue'\n` +
|
||||
`const __injectCSSVars__ = () => {\n${genCssVarsCode(
|
||||
cssVars,
|
||||
bindings,
|
||||
id,
|
||||
isProd
|
||||
)}}\n` +
|
||||
`const __setup__ = __default__.setup\n` +
|
||||
`__default__.setup = __setup__\n` +
|
||||
` ? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }\n` +
|
||||
` : __injectCSSVars__\n`
|
||||
)
|
||||
}
|
31
node_modules/vue/packages/compiler-sfc/src/index.ts
generated
vendored
Normal file
31
node_modules/vue/packages/compiler-sfc/src/index.ts
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
// API
|
||||
export { parse } from './parse'
|
||||
export { compileTemplate } from './compileTemplate'
|
||||
export { compileStyle, compileStyleAsync } from './compileStyle'
|
||||
export { compileScript } from './compileScript'
|
||||
export { generateCodeFrame } from 'compiler/codeframe'
|
||||
export { rewriteDefault } from './rewriteDefault'
|
||||
|
||||
// For backwards compat only. Some existing tools like
|
||||
// fork-ts-checker-webpack-plugin relies on its presence for differentiating
|
||||
// between Vue 2 and Vue 3.
|
||||
// ref #12719
|
||||
// ref https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/issues/765
|
||||
export { parseComponent } from './parseComponent'
|
||||
|
||||
// types
|
||||
export { SFCParseOptions } from './parse'
|
||||
export { CompilerOptions, WarningMessage } from 'types/compiler'
|
||||
export { TemplateCompiler } from './types'
|
||||
export {
|
||||
SFCBlock,
|
||||
SFCCustomBlock,
|
||||
SFCScriptBlock,
|
||||
SFCDescriptor
|
||||
} from './parseComponent'
|
||||
export {
|
||||
SFCTemplateCompileOptions,
|
||||
SFCTemplateCompileResults
|
||||
} from './compileTemplate'
|
||||
export { SFCStyleCompileOptions, SFCStyleCompileResults } from './compileStyle'
|
||||
export { SFCScriptCompileOptions } from './compileScript'
|
129
node_modules/vue/packages/compiler-sfc/src/parse.ts
generated
vendored
Normal file
129
node_modules/vue/packages/compiler-sfc/src/parse.ts
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
import { SourceMapGenerator } from 'source-map'
|
||||
import { RawSourceMap, TemplateCompiler } from './types'
|
||||
import {
|
||||
parseComponent,
|
||||
VueTemplateCompilerParseOptions,
|
||||
SFCDescriptor,
|
||||
DEFAULT_FILENAME
|
||||
} from './parseComponent'
|
||||
|
||||
import hash from 'hash-sum'
|
||||
import LRU from 'lru-cache'
|
||||
import { hmrShouldReload } from './compileScript'
|
||||
import { parseCssVars } from './cssVars'
|
||||
|
||||
const cache = new LRU<string, SFCDescriptor>(100)
|
||||
|
||||
const splitRE = /\r?\n/g
|
||||
const emptyRE = /^(?:\/\/)?\s*$/
|
||||
|
||||
export interface SFCParseOptions {
|
||||
source: string
|
||||
filename?: string
|
||||
compiler?: TemplateCompiler
|
||||
compilerParseOptions?: VueTemplateCompilerParseOptions
|
||||
sourceRoot?: string
|
||||
sourceMap?: boolean
|
||||
/**
|
||||
* @deprecated use `sourceMap` instead.
|
||||
*/
|
||||
needMap?: boolean
|
||||
}
|
||||
|
||||
export function parse(options: SFCParseOptions): SFCDescriptor {
|
||||
const {
|
||||
source,
|
||||
filename = DEFAULT_FILENAME,
|
||||
compiler,
|
||||
compilerParseOptions = { pad: false } as VueTemplateCompilerParseOptions,
|
||||
sourceRoot = '',
|
||||
needMap = true,
|
||||
sourceMap = needMap
|
||||
} = options
|
||||
const cacheKey = hash(
|
||||
filename + source + JSON.stringify(compilerParseOptions)
|
||||
)
|
||||
|
||||
let output = cache.get(cacheKey)
|
||||
if (output) {
|
||||
return output
|
||||
}
|
||||
|
||||
if (compiler) {
|
||||
// user-provided compiler
|
||||
output = compiler.parseComponent(source, compilerParseOptions)
|
||||
} else {
|
||||
// use built-in compiler
|
||||
output = parseComponent(source, compilerParseOptions)
|
||||
}
|
||||
|
||||
output.filename = filename
|
||||
|
||||
// parse CSS vars
|
||||
output.cssVars = parseCssVars(output)
|
||||
|
||||
output.shouldForceReload = prevImports =>
|
||||
hmrShouldReload(prevImports, output!)
|
||||
|
||||
if (sourceMap) {
|
||||
if (output.script && !output.script.src) {
|
||||
output.script.map = generateSourceMap(
|
||||
filename,
|
||||
source,
|
||||
output.script.content,
|
||||
sourceRoot,
|
||||
compilerParseOptions.pad
|
||||
)
|
||||
}
|
||||
if (output.styles) {
|
||||
output.styles.forEach(style => {
|
||||
if (!style.src) {
|
||||
style.map = generateSourceMap(
|
||||
filename,
|
||||
source,
|
||||
style.content,
|
||||
sourceRoot,
|
||||
compilerParseOptions.pad
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
cache.set(cacheKey, output)
|
||||
return output
|
||||
}
|
||||
|
||||
function generateSourceMap(
|
||||
filename: string,
|
||||
source: string,
|
||||
generated: string,
|
||||
sourceRoot: string,
|
||||
pad?: 'line' | 'space' | boolean
|
||||
): RawSourceMap {
|
||||
const map = new SourceMapGenerator({
|
||||
file: filename.replace(/\\/g, '/'),
|
||||
sourceRoot: sourceRoot.replace(/\\/g, '/')
|
||||
})
|
||||
let offset = 0
|
||||
if (!pad) {
|
||||
offset = source.split(generated).shift()!.split(splitRE).length - 1
|
||||
}
|
||||
map.setSourceContent(filename, source)
|
||||
generated.split(splitRE).forEach((line, index) => {
|
||||
if (!emptyRE.test(line)) {
|
||||
map.addMapping({
|
||||
source: filename,
|
||||
original: {
|
||||
line: index + 1 + offset,
|
||||
column: 0
|
||||
},
|
||||
generated: {
|
||||
line: index + 1,
|
||||
column: 0
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
return JSON.parse(map.toString())
|
||||
}
|
220
node_modules/vue/packages/compiler-sfc/src/parseComponent.ts
generated
vendored
Normal file
220
node_modules/vue/packages/compiler-sfc/src/parseComponent.ts
generated
vendored
Normal file
@ -0,0 +1,220 @@
|
||||
import deindent from 'de-indent'
|
||||
import { parseHTML } from 'compiler/parser/html-parser'
|
||||
import { makeMap } from 'shared/util'
|
||||
import { ASTAttr, WarningMessage } from 'types/compiler'
|
||||
import { BindingMetadata, RawSourceMap } from './types'
|
||||
import type { ImportBinding } from './compileScript'
|
||||
|
||||
export const DEFAULT_FILENAME = 'anonymous.vue'
|
||||
|
||||
const splitRE = /\r?\n/g
|
||||
const replaceRE = /./g
|
||||
const isSpecialTag = makeMap('script,style,template', true)
|
||||
|
||||
export interface SFCCustomBlock {
|
||||
type: string
|
||||
content: string
|
||||
attrs: { [key: string]: string | true }
|
||||
start: number
|
||||
end: number
|
||||
src?: string
|
||||
map?: RawSourceMap
|
||||
}
|
||||
|
||||
export interface SFCBlock extends SFCCustomBlock {
|
||||
lang?: string
|
||||
scoped?: boolean
|
||||
module?: string | boolean
|
||||
}
|
||||
|
||||
export interface SFCScriptBlock extends SFCBlock {
|
||||
type: 'script'
|
||||
setup?: string | boolean
|
||||
bindings?: BindingMetadata
|
||||
imports?: Record<string, ImportBinding>
|
||||
/**
|
||||
* import('\@babel/types').Statement
|
||||
*/
|
||||
scriptAst?: any[]
|
||||
/**
|
||||
* import('\@babel/types').Statement
|
||||
*/
|
||||
scriptSetupAst?: any[]
|
||||
}
|
||||
|
||||
export interface SFCDescriptor {
|
||||
source: string
|
||||
filename: string
|
||||
template: SFCBlock | null
|
||||
script: SFCScriptBlock | null
|
||||
scriptSetup: SFCScriptBlock | null
|
||||
styles: SFCBlock[]
|
||||
customBlocks: SFCCustomBlock[]
|
||||
cssVars: string[]
|
||||
|
||||
errors: (string | WarningMessage)[]
|
||||
|
||||
/**
|
||||
* compare with an existing descriptor to determine whether HMR should perform
|
||||
* a reload vs. re-render.
|
||||
*
|
||||
* Note: this comparison assumes the prev/next script are already identical,
|
||||
* and only checks the special case where `<script setup lang="ts">` unused
|
||||
* import pruning result changes due to template changes.
|
||||
*/
|
||||
shouldForceReload: (prevImports: Record<string, ImportBinding>) => boolean
|
||||
}
|
||||
|
||||
export interface VueTemplateCompilerParseOptions {
|
||||
pad?: 'line' | 'space' | boolean
|
||||
deindent?: boolean
|
||||
outputSourceRange?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a single-file component (*.vue) file into an SFC Descriptor Object.
|
||||
*/
|
||||
export function parseComponent(
|
||||
source: string,
|
||||
options: VueTemplateCompilerParseOptions = {}
|
||||
): SFCDescriptor {
|
||||
const sfc: SFCDescriptor = {
|
||||
source,
|
||||
filename: DEFAULT_FILENAME,
|
||||
template: null,
|
||||
script: null,
|
||||
scriptSetup: null, // TODO
|
||||
styles: [],
|
||||
customBlocks: [],
|
||||
cssVars: [],
|
||||
errors: [],
|
||||
shouldForceReload: null as any // attached in parse() by compiler-sfc
|
||||
}
|
||||
let depth = 0
|
||||
let currentBlock: SFCBlock | null = null
|
||||
|
||||
let warn: any = msg => {
|
||||
sfc.errors.push(msg)
|
||||
}
|
||||
|
||||
if (__DEV__ && options.outputSourceRange) {
|
||||
warn = (msg, range) => {
|
||||
const data: WarningMessage = { msg }
|
||||
if (range.start != null) {
|
||||
data.start = range.start
|
||||
}
|
||||
if (range.end != null) {
|
||||
data.end = range.end
|
||||
}
|
||||
sfc.errors.push(data)
|
||||
}
|
||||
}
|
||||
|
||||
function start(
|
||||
tag: string,
|
||||
attrs: ASTAttr[],
|
||||
unary: boolean,
|
||||
start: number,
|
||||
end: number
|
||||
) {
|
||||
if (depth === 0) {
|
||||
currentBlock = {
|
||||
type: tag,
|
||||
content: '',
|
||||
start: end,
|
||||
end: 0, // will be set on tag close
|
||||
attrs: attrs.reduce((cumulated, { name, value }) => {
|
||||
cumulated[name] = value || true
|
||||
return cumulated
|
||||
}, {})
|
||||
}
|
||||
|
||||
if (typeof currentBlock.attrs.src === 'string') {
|
||||
currentBlock.src = currentBlock.attrs.src
|
||||
}
|
||||
|
||||
if (isSpecialTag(tag)) {
|
||||
checkAttrs(currentBlock, attrs)
|
||||
if (tag === 'script') {
|
||||
const block = currentBlock as SFCScriptBlock
|
||||
if (block.attrs.setup) {
|
||||
block.setup = currentBlock.attrs.setup
|
||||
sfc.scriptSetup = block
|
||||
} else {
|
||||
sfc.script = block
|
||||
}
|
||||
} else if (tag === 'style') {
|
||||
sfc.styles.push(currentBlock)
|
||||
} else {
|
||||
sfc[tag] = currentBlock
|
||||
}
|
||||
} else {
|
||||
// custom blocks
|
||||
sfc.customBlocks.push(currentBlock)
|
||||
}
|
||||
}
|
||||
if (!unary) {
|
||||
depth++
|
||||
}
|
||||
}
|
||||
|
||||
function checkAttrs(block: SFCBlock, attrs: ASTAttr[]) {
|
||||
for (let i = 0; i < attrs.length; i++) {
|
||||
const attr = attrs[i]
|
||||
if (attr.name === 'lang') {
|
||||
block.lang = attr.value
|
||||
}
|
||||
if (attr.name === 'scoped') {
|
||||
block.scoped = true
|
||||
}
|
||||
if (attr.name === 'module') {
|
||||
block.module = attr.value || true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function end(tag: string, start: number) {
|
||||
if (depth === 1 && currentBlock) {
|
||||
currentBlock.end = start
|
||||
let text = source.slice(currentBlock.start, currentBlock.end)
|
||||
if (
|
||||
options.deindent === true ||
|
||||
// by default, deindent unless it's script with default lang or (j/t)sx?
|
||||
(options.deindent !== false &&
|
||||
!(
|
||||
currentBlock.type === 'script' &&
|
||||
(!currentBlock.lang || /^(j|t)sx?$/.test(currentBlock.lang))
|
||||
))
|
||||
) {
|
||||
text = deindent(text)
|
||||
}
|
||||
// pad content so that linters and pre-processors can output correct
|
||||
// line numbers in errors and warnings
|
||||
if (currentBlock.type !== 'template' && options.pad) {
|
||||
text = padContent(currentBlock, options.pad) + text
|
||||
}
|
||||
currentBlock.content = text
|
||||
currentBlock = null
|
||||
}
|
||||
depth--
|
||||
}
|
||||
|
||||
function padContent(block: SFCBlock, pad: true | 'line' | 'space') {
|
||||
if (pad === 'space') {
|
||||
return source.slice(0, block.start).replace(replaceRE, ' ')
|
||||
} else {
|
||||
const offset = source.slice(0, block.start).split(splitRE).length
|
||||
const padChar = block.type === 'script' && !block.lang ? '//\n' : '\n'
|
||||
return Array(offset).join(padChar)
|
||||
}
|
||||
}
|
||||
|
||||
parseHTML(source, {
|
||||
warn,
|
||||
start,
|
||||
end,
|
||||
outputSourceRange: options.outputSourceRange
|
||||
})
|
||||
|
||||
return sfc
|
||||
}
|
82
node_modules/vue/packages/compiler-sfc/src/prefixIdentifiers.ts
generated
vendored
Normal file
82
node_modules/vue/packages/compiler-sfc/src/prefixIdentifiers.ts
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
import MagicString from 'magic-string'
|
||||
import { parseExpression, ParserOptions, ParserPlugin } from '@babel/parser'
|
||||
import { makeMap } from 'shared/util'
|
||||
import { isStaticProperty, walkIdentifiers } from './babelUtils'
|
||||
import { BindingMetadata } from './types'
|
||||
|
||||
const doNotPrefix = makeMap(
|
||||
'Infinity,undefined,NaN,isFinite,isNaN,' +
|
||||
'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
|
||||
'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
|
||||
'require,' + // for webpack
|
||||
'arguments,' + // parsed as identifier but is a special keyword...
|
||||
'_c' // cached to save property access
|
||||
)
|
||||
|
||||
/**
|
||||
* The input is expected to be a valid expression.
|
||||
*/
|
||||
export function prefixIdentifiers(
|
||||
source: string,
|
||||
isFunctional = false,
|
||||
isTS = false,
|
||||
babelOptions: ParserOptions = {},
|
||||
bindings?: BindingMetadata
|
||||
) {
|
||||
const s = new MagicString(source)
|
||||
|
||||
const plugins: ParserPlugin[] = [
|
||||
...(isTS ? (['typescript'] as const) : []),
|
||||
...(babelOptions?.plugins || [])
|
||||
]
|
||||
|
||||
const ast = parseExpression(source, {
|
||||
...babelOptions,
|
||||
plugins
|
||||
})
|
||||
|
||||
const isScriptSetup = bindings && bindings.__isScriptSetup !== false
|
||||
|
||||
walkIdentifiers(
|
||||
ast,
|
||||
(ident, parent) => {
|
||||
const { name } = ident
|
||||
if (doNotPrefix(name)) {
|
||||
return
|
||||
}
|
||||
|
||||
let prefix = `_vm.`
|
||||
if (isScriptSetup) {
|
||||
const type = bindings[name]
|
||||
if (type && type.startsWith('setup')) {
|
||||
prefix = `_setup.`
|
||||
}
|
||||
}
|
||||
|
||||
if (isStaticProperty(parent) && parent.shorthand) {
|
||||
// property shorthand like { foo }, we need to add the key since
|
||||
// we rewrite the value
|
||||
// { foo } -> { foo: _vm.foo }
|
||||
s.appendLeft(ident.end!, `: ${prefix}${name}`)
|
||||
} else {
|
||||
s.prependRight(ident.start!, prefix)
|
||||
}
|
||||
},
|
||||
node => {
|
||||
if (node.type === 'WithStatement') {
|
||||
s.remove(node.start!, node.body.start! + 1)
|
||||
s.remove(node.end! - 1, node.end!)
|
||||
if (!isFunctional) {
|
||||
s.prependRight(
|
||||
node.start!,
|
||||
`var _vm=this,_c=_vm._self._c${
|
||||
isScriptSetup ? `,_setup=_vm._self._setupProxy;` : `;`
|
||||
}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return s.toString()
|
||||
}
|
115
node_modules/vue/packages/compiler-sfc/src/rewriteDefault.ts
generated
vendored
Normal file
115
node_modules/vue/packages/compiler-sfc/src/rewriteDefault.ts
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
import { parse, ParserPlugin } from '@babel/parser'
|
||||
import MagicString from 'magic-string'
|
||||
|
||||
const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/
|
||||
const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)(?:as)?(\s*)default/s
|
||||
const exportDefaultClassRE =
|
||||
/((?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/
|
||||
|
||||
/**
|
||||
* Utility for rewriting `export default` in a script block into a variable
|
||||
* declaration so that we can inject things into it
|
||||
*/
|
||||
export function rewriteDefault(
|
||||
input: string,
|
||||
as: string,
|
||||
parserPlugins?: ParserPlugin[]
|
||||
): string {
|
||||
if (!hasDefaultExport(input)) {
|
||||
return input + `\nconst ${as} = {}`
|
||||
}
|
||||
|
||||
let replaced: string | undefined
|
||||
|
||||
const classMatch = input.match(exportDefaultClassRE)
|
||||
if (classMatch) {
|
||||
replaced =
|
||||
input.replace(exportDefaultClassRE, '$1class $2') +
|
||||
`\nconst ${as} = ${classMatch[2]}`
|
||||
} else {
|
||||
replaced = input.replace(defaultExportRE, `$1const ${as} =`)
|
||||
}
|
||||
if (!hasDefaultExport(replaced)) {
|
||||
return replaced
|
||||
}
|
||||
|
||||
// if the script somehow still contains `default export`, it probably has
|
||||
// multi-line comments or template strings. fallback to a full parse.
|
||||
const s = new MagicString(input)
|
||||
const ast = parse(input, {
|
||||
sourceType: 'module',
|
||||
plugins: parserPlugins
|
||||
}).program.body
|
||||
ast.forEach(node => {
|
||||
if (node.type === 'ExportDefaultDeclaration') {
|
||||
if (node.declaration.type === 'ClassDeclaration') {
|
||||
s.overwrite(node.start!, node.declaration.id.start!, `class `)
|
||||
s.append(`\nconst ${as} = ${node.declaration.id.name}`)
|
||||
} else {
|
||||
s.overwrite(node.start!, node.declaration.start!, `const ${as} = `)
|
||||
}
|
||||
}
|
||||
if (node.type === 'ExportNamedDeclaration') {
|
||||
for (const specifier of node.specifiers) {
|
||||
if (
|
||||
specifier.type === 'ExportSpecifier' &&
|
||||
specifier.exported.type === 'Identifier' &&
|
||||
specifier.exported.name === 'default'
|
||||
) {
|
||||
if (node.source) {
|
||||
if (specifier.local.name === 'default') {
|
||||
const end = specifierEnd(input, specifier.local.end!, node.end)
|
||||
s.prepend(
|
||||
`import { default as __VUE_DEFAULT__ } from '${node.source.value}'\n`
|
||||
)
|
||||
s.overwrite(specifier.start!, end, ``)
|
||||
s.append(`\nconst ${as} = __VUE_DEFAULT__`)
|
||||
continue
|
||||
} else {
|
||||
const end = specifierEnd(input, specifier.exported.end!, node.end)
|
||||
s.prepend(
|
||||
`import { ${input.slice(
|
||||
specifier.local.start!,
|
||||
specifier.local.end!
|
||||
)} } from '${node.source.value}'\n`
|
||||
)
|
||||
s.overwrite(specifier.start!, end, ``)
|
||||
s.append(`\nconst ${as} = ${specifier.local.name}`)
|
||||
continue
|
||||
}
|
||||
}
|
||||
const end = specifierEnd(input, specifier.end!, node.end)
|
||||
s.overwrite(specifier.start!, end, ``)
|
||||
s.append(`\nconst ${as} = ${specifier.local.name}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return s.toString()
|
||||
}
|
||||
|
||||
export function hasDefaultExport(input: string): boolean {
|
||||
return defaultExportRE.test(input) || namedDefaultExportRE.test(input)
|
||||
}
|
||||
|
||||
function specifierEnd(
|
||||
input: string,
|
||||
end: number,
|
||||
nodeEnd: number | undefined | null
|
||||
) {
|
||||
// export { default , foo } ...
|
||||
let hasCommas = false
|
||||
let oldEnd = end
|
||||
while (end < nodeEnd!) {
|
||||
if (/\s/.test(input.charAt(end))) {
|
||||
end++
|
||||
} else if (input.charAt(end) === ',') {
|
||||
end++
|
||||
hasCommas = true
|
||||
break
|
||||
} else if (input.charAt(end) === '}') {
|
||||
break
|
||||
}
|
||||
}
|
||||
return hasCommas ? end : oldEnd
|
||||
}
|
203
node_modules/vue/packages/compiler-sfc/src/stylePlugins/scoped.ts
generated
vendored
Normal file
203
node_modules/vue/packages/compiler-sfc/src/stylePlugins/scoped.ts
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
import { PluginCreator, Rule, AtRule } from 'postcss'
|
||||
import selectorParser from 'postcss-selector-parser'
|
||||
|
||||
const animationNameRE = /^(-\w+-)?animation-name$/
|
||||
const animationRE = /^(-\w+-)?animation$/
|
||||
|
||||
const scopedPlugin: PluginCreator<string> = (id = '') => {
|
||||
const keyframes = Object.create(null)
|
||||
const shortId = id.replace(/^data-v-/, '')
|
||||
|
||||
return {
|
||||
postcssPlugin: 'vue-sfc-scoped',
|
||||
Rule(rule) {
|
||||
processRule(id, rule)
|
||||
},
|
||||
AtRule(node) {
|
||||
if (
|
||||
/-?keyframes$/.test(node.name) &&
|
||||
!node.params.endsWith(`-${shortId}`)
|
||||
) {
|
||||
// register keyframes
|
||||
keyframes[node.params] = node.params = node.params + '-' + shortId
|
||||
}
|
||||
},
|
||||
OnceExit(root) {
|
||||
if (Object.keys(keyframes).length) {
|
||||
// If keyframes are found in this <style>, find and rewrite animation names
|
||||
// in declarations.
|
||||
// Caveat: this only works for keyframes and animation rules in the same
|
||||
// <style> element.
|
||||
// individual animation-name declaration
|
||||
root.walkDecls(decl => {
|
||||
if (animationNameRE.test(decl.prop)) {
|
||||
decl.value = decl.value
|
||||
.split(',')
|
||||
.map(v => keyframes[v.trim()] || v.trim())
|
||||
.join(',')
|
||||
}
|
||||
// shorthand
|
||||
if (animationRE.test(decl.prop)) {
|
||||
decl.value = decl.value
|
||||
.split(',')
|
||||
.map(v => {
|
||||
const vals = v.trim().split(/\s+/)
|
||||
const i = vals.findIndex(val => keyframes[val])
|
||||
if (i !== -1) {
|
||||
vals.splice(i, 1, keyframes[vals[i]])
|
||||
return vals.join(' ')
|
||||
} else {
|
||||
return v
|
||||
}
|
||||
})
|
||||
.join(',')
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const processedRules = new WeakSet<Rule>()
|
||||
|
||||
function processRule(id: string, rule: Rule) {
|
||||
if (
|
||||
processedRules.has(rule) ||
|
||||
(rule.parent &&
|
||||
rule.parent.type === 'atrule' &&
|
||||
/-?keyframes$/.test((rule.parent as AtRule).name))
|
||||
) {
|
||||
return
|
||||
}
|
||||
processedRules.add(rule)
|
||||
rule.selector = selectorParser(selectorRoot => {
|
||||
selectorRoot.each(selector => {
|
||||
rewriteSelector(id, selector, selectorRoot)
|
||||
})
|
||||
}).processSync(rule.selector)
|
||||
}
|
||||
|
||||
function rewriteSelector(
|
||||
id: string,
|
||||
selector: selectorParser.Selector,
|
||||
selectorRoot: selectorParser.Root
|
||||
) {
|
||||
let node: selectorParser.Node | null = null
|
||||
let shouldInject = true
|
||||
// find the last child node to insert attribute selector
|
||||
selector.each(n => {
|
||||
// DEPRECATED ">>>" and "/deep/" combinator
|
||||
if (
|
||||
n.type === 'combinator' &&
|
||||
(n.value === '>>>' || n.value === '/deep/')
|
||||
) {
|
||||
n.value = ' '
|
||||
n.spaces.before = n.spaces.after = ''
|
||||
// warn(
|
||||
// `the >>> and /deep/ combinators have been deprecated. ` +
|
||||
// `Use :deep() instead.`
|
||||
// )
|
||||
return false
|
||||
}
|
||||
|
||||
if (n.type === 'pseudo') {
|
||||
const { value } = n
|
||||
// deep: inject [id] attribute at the node before the ::v-deep
|
||||
// combinator.
|
||||
if (value === ':deep' || value === '::v-deep') {
|
||||
if (n.nodes.length) {
|
||||
// .foo ::v-deep(.bar) -> .foo[xxxxxxx] .bar
|
||||
// replace the current node with ::v-deep's inner selector
|
||||
let last: selectorParser.Selector['nodes'][0] = n
|
||||
n.nodes[0].each(ss => {
|
||||
selector.insertAfter(last, ss)
|
||||
last = ss
|
||||
})
|
||||
// insert a space combinator before if it doesn't already have one
|
||||
const prev = selector.at(selector.index(n) - 1)
|
||||
if (!prev || !isSpaceCombinator(prev)) {
|
||||
selector.insertAfter(
|
||||
n,
|
||||
selectorParser.combinator({
|
||||
value: ' '
|
||||
})
|
||||
)
|
||||
}
|
||||
selector.removeChild(n)
|
||||
} else {
|
||||
// DEPRECATED usage in v3
|
||||
// .foo ::v-deep .bar -> .foo[xxxxxxx] .bar
|
||||
// warn(
|
||||
// `::v-deep usage as a combinator has ` +
|
||||
// `been deprecated. Use :deep(<inner-selector>) instead.`
|
||||
// )
|
||||
const prev = selector.at(selector.index(n) - 1)
|
||||
if (prev && isSpaceCombinator(prev)) {
|
||||
selector.removeChild(prev)
|
||||
}
|
||||
selector.removeChild(n)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// !!! Vue 2 does not have :slotted support
|
||||
// ::v-slotted(.foo) -> .foo[xxxxxxx-s]
|
||||
// if (value === ':slotted' || value === '::v-slotted') {
|
||||
// rewriteSelector(id, n.nodes[0], selectorRoot, true /* slotted */)
|
||||
// let last: selectorParser.Selector['nodes'][0] = n
|
||||
// n.nodes[0].each(ss => {
|
||||
// selector.insertAfter(last, ss)
|
||||
// last = ss
|
||||
// })
|
||||
// // selector.insertAfter(n, n.nodes[0])
|
||||
// selector.removeChild(n)
|
||||
// // since slotted attribute already scopes the selector there's no
|
||||
// // need for the non-slot attribute.
|
||||
// shouldInject = false
|
||||
// return false
|
||||
// }
|
||||
|
||||
// global: replace with inner selector and do not inject [id].
|
||||
// ::v-global(.foo) -> .foo
|
||||
if (value === ':global' || value === '::v-global') {
|
||||
selectorRoot.insertAfter(selector, n.nodes[0])
|
||||
selectorRoot.removeChild(selector)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (n.type !== 'pseudo' && n.type !== 'combinator') {
|
||||
node = n
|
||||
}
|
||||
})
|
||||
|
||||
if (node) {
|
||||
;(node as selectorParser.Node).spaces.after = ''
|
||||
} else {
|
||||
// For deep selectors & standalone pseudo selectors,
|
||||
// the attribute selectors are prepended rather than appended.
|
||||
// So all leading spaces must be eliminated to avoid problems.
|
||||
selector.first.spaces.before = ''
|
||||
}
|
||||
|
||||
if (shouldInject) {
|
||||
selector.insertAfter(
|
||||
// If node is null it means we need to inject [id] at the start
|
||||
// insertAfter can handle `null` here
|
||||
node as any,
|
||||
selectorParser.attribute({
|
||||
attribute: id,
|
||||
value: id,
|
||||
raws: {},
|
||||
quoteMark: `"`
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function isSpaceCombinator(node: selectorParser.Node) {
|
||||
return node.type === 'combinator' && /^\s+$/.test(node.value)
|
||||
}
|
||||
|
||||
scopedPlugin.postcss = true
|
||||
export default scopedPlugin
|
18
node_modules/vue/packages/compiler-sfc/src/stylePlugins/trim.ts
generated
vendored
Normal file
18
node_modules/vue/packages/compiler-sfc/src/stylePlugins/trim.ts
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
import { PluginCreator } from 'postcss'
|
||||
|
||||
const trimPlugin: PluginCreator<{}> = () => {
|
||||
return {
|
||||
postcssPlugin: 'vue-sfc-trim',
|
||||
Once(root) {
|
||||
root.walk(({ type, raws }) => {
|
||||
if (type === 'rule' || type === 'atrule') {
|
||||
if (raws.before) raws.before = '\n'
|
||||
if ('after' in raws && raws.after) raws.after = '\n'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trimPlugin.postcss = true
|
||||
export default trimPlugin
|
135
node_modules/vue/packages/compiler-sfc/src/stylePreprocessors.ts
generated
vendored
Normal file
135
node_modules/vue/packages/compiler-sfc/src/stylePreprocessors.ts
generated
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
import merge from 'merge-source-map'
|
||||
import { RawSourceMap } from 'source-map'
|
||||
import { isFunction } from 'shared/util'
|
||||
|
||||
export type StylePreprocessor = (
|
||||
source: string,
|
||||
map: RawSourceMap | undefined,
|
||||
options: {
|
||||
[key: string]: any
|
||||
additionalData?: string | ((source: string, filename: string) => string)
|
||||
filename: string
|
||||
}
|
||||
) => StylePreprocessorResults
|
||||
|
||||
export interface StylePreprocessorResults {
|
||||
code: string
|
||||
map?: object
|
||||
errors: Error[]
|
||||
dependencies: string[]
|
||||
}
|
||||
|
||||
// .scss/.sass processor
|
||||
const scss: StylePreprocessor = (source, map, options) => {
|
||||
const nodeSass = require('sass')
|
||||
const finalOptions = {
|
||||
...options,
|
||||
data: getSource(source, options.filename, options.additionalData),
|
||||
file: options.filename,
|
||||
outFile: options.filename,
|
||||
sourceMap: !!map
|
||||
}
|
||||
|
||||
try {
|
||||
const result = nodeSass.renderSync(finalOptions)
|
||||
const dependencies = result.stats.includedFiles
|
||||
if (map) {
|
||||
return {
|
||||
code: result.css.toString(),
|
||||
map: merge(map, JSON.parse(result.map.toString())),
|
||||
errors: [],
|
||||
dependencies
|
||||
}
|
||||
}
|
||||
|
||||
return { code: result.css.toString(), errors: [], dependencies }
|
||||
} catch (e: any) {
|
||||
return { code: '', errors: [e], dependencies: [] }
|
||||
}
|
||||
}
|
||||
|
||||
const sass: StylePreprocessor = (source, map, options) =>
|
||||
scss(source, map, {
|
||||
...options,
|
||||
indentedSyntax: true
|
||||
})
|
||||
|
||||
// .less
|
||||
const less: StylePreprocessor = (source, map, options) => {
|
||||
const nodeLess = require('less')
|
||||
|
||||
let result: any
|
||||
let error: Error | null = null
|
||||
nodeLess.render(
|
||||
getSource(source, options.filename, options.additionalData),
|
||||
{ ...options, syncImport: true },
|
||||
(err: Error | null, output: any) => {
|
||||
error = err
|
||||
result = output
|
||||
}
|
||||
)
|
||||
|
||||
if (error) return { code: '', errors: [error], dependencies: [] }
|
||||
const dependencies = result.imports
|
||||
if (map) {
|
||||
return {
|
||||
code: result.css.toString(),
|
||||
map: merge(map, result.map),
|
||||
errors: [],
|
||||
dependencies: dependencies
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
code: result.css.toString(),
|
||||
errors: [],
|
||||
dependencies: dependencies
|
||||
}
|
||||
}
|
||||
|
||||
// .styl
|
||||
const styl: StylePreprocessor = (source, map, options) => {
|
||||
const nodeStylus = require('stylus')
|
||||
try {
|
||||
const ref = nodeStylus(source)
|
||||
Object.keys(options).forEach(key => ref.set(key, options[key]))
|
||||
if (map) ref.set('sourcemap', { inline: false, comment: false })
|
||||
|
||||
const result = ref.render()
|
||||
const dependencies = ref.deps()
|
||||
if (map) {
|
||||
return {
|
||||
code: result,
|
||||
map: merge(map, ref.sourcemap),
|
||||
errors: [],
|
||||
dependencies
|
||||
}
|
||||
}
|
||||
|
||||
return { code: result, errors: [], dependencies }
|
||||
} catch (e: any) {
|
||||
return { code: '', errors: [e], dependencies: [] }
|
||||
}
|
||||
}
|
||||
|
||||
function getSource(
|
||||
source: string,
|
||||
filename: string,
|
||||
additionalData?: string | ((source: string, filename: string) => string)
|
||||
) {
|
||||
if (!additionalData) return source
|
||||
if (isFunction(additionalData)) {
|
||||
return additionalData(source, filename)
|
||||
}
|
||||
return additionalData + source
|
||||
}
|
||||
|
||||
export type PreprocessLang = 'less' | 'sass' | 'scss' | 'styl' | 'stylus'
|
||||
|
||||
export const processors: Record<PreprocessLang, StylePreprocessor> = {
|
||||
less,
|
||||
sass,
|
||||
scss,
|
||||
styl,
|
||||
stylus: styl
|
||||
}
|
84
node_modules/vue/packages/compiler-sfc/src/templateCompilerModules/assetUrl.ts
generated
vendored
Normal file
84
node_modules/vue/packages/compiler-sfc/src/templateCompilerModules/assetUrl.ts
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
// vue compiler module for transforming `<tag>:<attribute>` to `require`
|
||||
|
||||
import { urlToRequire } from './utils'
|
||||
import { ASTNode, ASTAttr } from 'types/compiler'
|
||||
|
||||
export interface AssetURLOptions {
|
||||
[name: string]: string | string[]
|
||||
}
|
||||
|
||||
export interface TransformAssetUrlsOptions {
|
||||
/**
|
||||
* If base is provided, instead of transforming relative asset urls into
|
||||
* imports, they will be directly rewritten to absolute urls.
|
||||
*/
|
||||
base?: string
|
||||
/**
|
||||
* If true, also processes absolute urls.
|
||||
*/
|
||||
includeAbsolute?: boolean
|
||||
}
|
||||
|
||||
const defaultOptions: AssetURLOptions = {
|
||||
audio: 'src',
|
||||
video: ['src', 'poster'],
|
||||
source: 'src',
|
||||
img: 'src',
|
||||
image: ['xlink:href', 'href'],
|
||||
use: ['xlink:href', 'href']
|
||||
}
|
||||
|
||||
export default (
|
||||
userOptions?: AssetURLOptions,
|
||||
transformAssetUrlsOption?: TransformAssetUrlsOptions
|
||||
) => {
|
||||
const options = userOptions
|
||||
? Object.assign({}, defaultOptions, userOptions)
|
||||
: defaultOptions
|
||||
|
||||
return {
|
||||
postTransformNode: (node: ASTNode) => {
|
||||
transform(node, options, transformAssetUrlsOption)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function transform(
|
||||
node: ASTNode,
|
||||
options: AssetURLOptions,
|
||||
transformAssetUrlsOption?: TransformAssetUrlsOptions
|
||||
) {
|
||||
if (node.type !== 1 || !node.attrs) return
|
||||
for (const tag in options) {
|
||||
if (tag === '*' || node.tag === tag) {
|
||||
const attributes = options[tag]
|
||||
if (typeof attributes === 'string') {
|
||||
node.attrs!.some(attr =>
|
||||
rewrite(attr, attributes, transformAssetUrlsOption)
|
||||
)
|
||||
} else if (Array.isArray(attributes)) {
|
||||
attributes.forEach(item =>
|
||||
node.attrs!.some(attr =>
|
||||
rewrite(attr, item, transformAssetUrlsOption)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function rewrite(
|
||||
attr: ASTAttr,
|
||||
name: string,
|
||||
transformAssetUrlsOption?: TransformAssetUrlsOptions
|
||||
) {
|
||||
if (attr.name === name) {
|
||||
const value = attr.value
|
||||
// only transform static URLs
|
||||
if (value.charAt(0) === '"' && value.charAt(value.length - 1) === '"') {
|
||||
attr.value = urlToRequire(value.slice(1, -1), transformAssetUrlsOption)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
76
node_modules/vue/packages/compiler-sfc/src/templateCompilerModules/srcset.ts
generated
vendored
Normal file
76
node_modules/vue/packages/compiler-sfc/src/templateCompilerModules/srcset.ts
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
// vue compiler module for transforming `img:srcset` to a number of `require`s
|
||||
|
||||
import { urlToRequire } from './utils'
|
||||
import { TransformAssetUrlsOptions } from './assetUrl'
|
||||
import { ASTNode } from 'types/compiler'
|
||||
|
||||
interface ImageCandidate {
|
||||
require: string
|
||||
descriptor: string
|
||||
}
|
||||
|
||||
export default (transformAssetUrlsOptions?: TransformAssetUrlsOptions) => ({
|
||||
postTransformNode: (node: ASTNode) => {
|
||||
transform(node, transformAssetUrlsOptions)
|
||||
}
|
||||
})
|
||||
|
||||
// http://w3c.github.io/html/semantics-embedded-content.html#ref-for-image-candidate-string-5
|
||||
const escapedSpaceCharacters = /( |\\t|\\n|\\f|\\r)+/g
|
||||
|
||||
function transform(
|
||||
node: ASTNode,
|
||||
transformAssetUrlsOptions?: TransformAssetUrlsOptions
|
||||
) {
|
||||
if (node.type !== 1 || !node.attrs) {
|
||||
return
|
||||
}
|
||||
|
||||
if (node.tag === 'img' || node.tag === 'source') {
|
||||
node.attrs.forEach(attr => {
|
||||
if (attr.name === 'srcset') {
|
||||
// same logic as in transform-require.js
|
||||
const value = attr.value
|
||||
const isStatic =
|
||||
value.charAt(0) === '"' && value.charAt(value.length - 1) === '"'
|
||||
if (!isStatic) {
|
||||
return
|
||||
}
|
||||
|
||||
const imageCandidates: ImageCandidate[] = value
|
||||
.slice(1, -1)
|
||||
.split(',')
|
||||
.map(s => {
|
||||
// The attribute value arrives here with all whitespace, except
|
||||
// normal spaces, represented by escape sequences
|
||||
const [url, descriptor] = s
|
||||
.replace(escapedSpaceCharacters, ' ')
|
||||
.trim()
|
||||
.split(' ', 2)
|
||||
return {
|
||||
require: urlToRequire(url, transformAssetUrlsOptions),
|
||||
descriptor
|
||||
}
|
||||
})
|
||||
|
||||
// "require(url1)"
|
||||
// "require(url1) 1x"
|
||||
// "require(url1), require(url2)"
|
||||
// "require(url1), require(url2) 2x"
|
||||
// "require(url1) 1x, require(url2)"
|
||||
// "require(url1) 1x, require(url2) 2x"
|
||||
const code = imageCandidates
|
||||
.map(
|
||||
({ require, descriptor }) =>
|
||||
`${require} + "${descriptor ? ' ' + descriptor : ''}, " + `
|
||||
)
|
||||
.join('')
|
||||
.slice(0, -6)
|
||||
.concat('"')
|
||||
.replace(/ \+ ""$/, '')
|
||||
|
||||
attr.value = code
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
86
node_modules/vue/packages/compiler-sfc/src/templateCompilerModules/utils.ts
generated
vendored
Normal file
86
node_modules/vue/packages/compiler-sfc/src/templateCompilerModules/utils.ts
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
import { TransformAssetUrlsOptions } from './assetUrl'
|
||||
import { UrlWithStringQuery, parse as uriParse } from 'url'
|
||||
import path from 'path'
|
||||
|
||||
export function urlToRequire(
|
||||
url: string,
|
||||
transformAssetUrlsOption: TransformAssetUrlsOptions = {}
|
||||
): string {
|
||||
const returnValue = `"${url}"`
|
||||
// same logic as in transform-require.js
|
||||
const firstChar = url.charAt(0)
|
||||
if (firstChar === '~') {
|
||||
const secondChar = url.charAt(1)
|
||||
url = url.slice(secondChar === '/' ? 2 : 1)
|
||||
}
|
||||
|
||||
if (isExternalUrl(url) || isDataUrl(url) || firstChar === '#') {
|
||||
return returnValue
|
||||
}
|
||||
|
||||
const uriParts = parseUriParts(url)
|
||||
if (transformAssetUrlsOption.base) {
|
||||
// explicit base - directly rewrite the url into absolute url
|
||||
// does not apply to absolute urls or urls that start with `@`
|
||||
// since they are aliases
|
||||
if (firstChar === '.' || firstChar === '~') {
|
||||
// Allow for full hostnames provided in options.base
|
||||
const base = parseUriParts(transformAssetUrlsOption.base)
|
||||
const protocol = base.protocol || ''
|
||||
const host = base.host ? protocol + '//' + base.host : ''
|
||||
const basePath = base.path || '/'
|
||||
// when packaged in the browser, path will be using the posix-
|
||||
// only version provided by rollup-plugin-node-builtins.
|
||||
return `"${host}${(path.posix || path).join(
|
||||
basePath,
|
||||
uriParts.path + (uriParts.hash || '')
|
||||
)}"`
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
transformAssetUrlsOption.includeAbsolute ||
|
||||
firstChar === '.' ||
|
||||
firstChar === '~' ||
|
||||
firstChar === '@'
|
||||
) {
|
||||
if (!uriParts.hash) {
|
||||
return `require("${url}")`
|
||||
} else {
|
||||
// support uri fragment case by excluding it from
|
||||
// the require and instead appending it as string;
|
||||
// assuming that the path part is sufficient according to
|
||||
// the above caseing(t.i. no protocol-auth-host parts expected)
|
||||
return `require("${uriParts.path}") + "${uriParts.hash}"`
|
||||
}
|
||||
}
|
||||
return returnValue
|
||||
}
|
||||
|
||||
/**
|
||||
* vuejs/component-compiler-utils#22 Support uri fragment in transformed require
|
||||
* @param urlString an url as a string
|
||||
*/
|
||||
function parseUriParts(urlString: string): UrlWithStringQuery {
|
||||
// initialize return value
|
||||
const returnValue: UrlWithStringQuery = uriParse('')
|
||||
if (urlString) {
|
||||
// A TypeError is thrown if urlString is not a string
|
||||
// @see https://nodejs.org/api/url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost
|
||||
if ('string' === typeof urlString) {
|
||||
// check is an uri
|
||||
return uriParse(urlString, false, true) // take apart the uri
|
||||
}
|
||||
}
|
||||
return returnValue
|
||||
}
|
||||
|
||||
const externalRE = /^(https?:)?\/\//
|
||||
function isExternalUrl(url: string): boolean {
|
||||
return externalRE.test(url)
|
||||
}
|
||||
|
||||
const dataUrlRE = /^\s*data:/i
|
||||
function isDataUrl(url: string): boolean {
|
||||
return dataUrlRE.test(url)
|
||||
}
|
69
node_modules/vue/packages/compiler-sfc/src/types.ts
generated
vendored
Normal file
69
node_modules/vue/packages/compiler-sfc/src/types.ts
generated
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
import { CompilerOptions, CompiledResult } from 'types/compiler'
|
||||
import { SFCDescriptor } from './parseComponent'
|
||||
|
||||
export interface StartOfSourceMap {
|
||||
file?: string
|
||||
sourceRoot?: string
|
||||
}
|
||||
|
||||
export interface RawSourceMap extends StartOfSourceMap {
|
||||
version: string
|
||||
sources: string[]
|
||||
names: string[]
|
||||
sourcesContent?: string[]
|
||||
mappings: string
|
||||
}
|
||||
|
||||
export interface TemplateCompiler {
|
||||
parseComponent(source: string, options?: any): SFCDescriptor
|
||||
compile(template: string, options: CompilerOptions): CompiledResult
|
||||
ssrCompile(template: string, options: CompilerOptions): CompiledResult
|
||||
}
|
||||
|
||||
export const enum BindingTypes {
|
||||
/**
|
||||
* returned from data()
|
||||
*/
|
||||
DATA = 'data',
|
||||
/**
|
||||
* declared as a prop
|
||||
*/
|
||||
PROPS = 'props',
|
||||
/**
|
||||
* a local alias of a `<script setup>` destructured prop.
|
||||
* the original is stored in __propsAliases of the bindingMetadata object.
|
||||
*/
|
||||
PROPS_ALIASED = 'props-aliased',
|
||||
/**
|
||||
* a let binding (may or may not be a ref)
|
||||
*/
|
||||
SETUP_LET = 'setup-let',
|
||||
/**
|
||||
* a const binding that can never be a ref.
|
||||
* these bindings don't need `unref()` calls when processed in inlined
|
||||
* template expressions.
|
||||
*/
|
||||
SETUP_CONST = 'setup-const',
|
||||
/**
|
||||
* a const binding that does not need `unref()`, but may be mutated.
|
||||
*/
|
||||
SETUP_REACTIVE_CONST = 'setup-reactive-const',
|
||||
/**
|
||||
* a const binding that may be a ref.
|
||||
*/
|
||||
SETUP_MAYBE_REF = 'setup-maybe-ref',
|
||||
/**
|
||||
* bindings that are guaranteed to be refs
|
||||
*/
|
||||
SETUP_REF = 'setup-ref',
|
||||
/**
|
||||
* declared by other options, e.g. computed, inject
|
||||
*/
|
||||
OPTIONS = 'options'
|
||||
}
|
||||
|
||||
export type BindingMetadata = {
|
||||
[key: string]: BindingTypes | undefined
|
||||
} & {
|
||||
__isScriptSetup?: boolean
|
||||
}
|
16
node_modules/vue/packages/compiler-sfc/src/warn.ts
generated
vendored
Normal file
16
node_modules/vue/packages/compiler-sfc/src/warn.ts
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
const hasWarned: Record<string, boolean> = {}
|
||||
|
||||
export function warnOnce(msg: string) {
|
||||
const isNodeProd =
|
||||
typeof process !== 'undefined' && process.env.NODE_ENV === 'production'
|
||||
if (!isNodeProd && !hasWarned[msg]) {
|
||||
hasWarned[msg] = true
|
||||
warn(msg)
|
||||
}
|
||||
}
|
||||
|
||||
export function warn(msg: string) {
|
||||
console.warn(
|
||||
`\x1b[1m\x1b[33m[@vue/compiler-sfc]\x1b[0m\x1b[33m ${msg}\x1b[0m\n`
|
||||
)
|
||||
}
|
925
node_modules/vue/packages/compiler-sfc/test/__snapshots__/compileScript.spec.ts.snap
generated
vendored
Normal file
925
node_modules/vue/packages/compiler-sfc/test/__snapshots__/compileScript.spec.ts.snap
generated
vendored
Normal file
@ -0,0 +1,925 @@
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`SFC analyze <script> bindings > auto name inference > basic 1`] = `
|
||||
"export default {
|
||||
__name: 'FooBar',
|
||||
setup(__props) {
|
||||
const a = 1
|
||||
return { a }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC analyze <script> bindings > auto name inference > do not overwrite manual name (call) 1`] = `
|
||||
"import { defineComponent } from 'vue'
|
||||
const __default__ = defineComponent({
|
||||
name: 'Baz'
|
||||
})
|
||||
|
||||
export default /*#__PURE__*/Object.assign(__default__, {
|
||||
setup(__props) {
|
||||
const a = 1
|
||||
return { a }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC analyze <script> bindings > auto name inference > do not overwrite manual name (object) 1`] = `
|
||||
"const __default__ = {
|
||||
name: 'Baz'
|
||||
}
|
||||
|
||||
export default /*#__PURE__*/Object.assign(__default__, {
|
||||
setup(__props) {
|
||||
const a = 1
|
||||
return { a }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > <script> after <script setup> the script content not end with \`\\n\` 1`] = `
|
||||
"const n = 1
|
||||
import { x } from './x'
|
||||
|
||||
export default {
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { n, x }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > <script> and <script setup> co-usage > script first 1`] = `
|
||||
"import { x } from './x'
|
||||
|
||||
export const n = 1
|
||||
|
||||
const __default__ = {}
|
||||
|
||||
export default /*#__PURE__*/Object.assign(__default__, {
|
||||
setup(__props) {
|
||||
|
||||
x()
|
||||
|
||||
return { n, x }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > <script> and <script setup> co-usage > script setup first 1`] = `
|
||||
"export const n = 1
|
||||
const __default__ = {}
|
||||
|
||||
import { x } from './x'
|
||||
|
||||
export default /*#__PURE__*/Object.assign(__default__, {
|
||||
setup(__props) {
|
||||
|
||||
x()
|
||||
|
||||
return { n, x }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > <script> and <script setup> co-usage > script setup first, lang="ts", script block content export default 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
|
||||
const __default__ = {
|
||||
name: \\"test\\"
|
||||
}
|
||||
|
||||
import { x } from './x'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
...__default__,
|
||||
setup(__props) {
|
||||
|
||||
x()
|
||||
|
||||
return { x }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > <script> and <script setup> co-usage > script setup first, named default export 1`] = `
|
||||
"export const n = 1
|
||||
const def = {}
|
||||
|
||||
|
||||
const __default__ = def
|
||||
|
||||
import { x } from './x'
|
||||
|
||||
export default /*#__PURE__*/Object.assign(__default__, {
|
||||
setup(__props) {
|
||||
|
||||
x()
|
||||
|
||||
return { n, def, x }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > <script> and <script setup> co-usage > spaces in ExportDefaultDeclaration node > with many spaces and newline 1`] = `
|
||||
"import { x } from './x'
|
||||
|
||||
export const n = 1
|
||||
const __default__ = {
|
||||
some:'option'
|
||||
}
|
||||
|
||||
export default /*#__PURE__*/Object.assign(__default__, {
|
||||
setup(__props) {
|
||||
|
||||
x()
|
||||
|
||||
return { n, x }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > <script> and <script setup> co-usage > spaces in ExportDefaultDeclaration node > with minimal spaces 1`] = `
|
||||
"import { x } from './x'
|
||||
|
||||
export const n = 1
|
||||
const __default__ = {
|
||||
some:'option'
|
||||
}
|
||||
|
||||
export default /*#__PURE__*/Object.assign(__default__, {
|
||||
setup(__props) {
|
||||
|
||||
x()
|
||||
|
||||
return { n, x }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > binding analysis for destructure 1`] = `
|
||||
"export default {
|
||||
setup(__props) {
|
||||
|
||||
const { foo, b: bar, ['x' + 'y']: baz, x: { y, zz: { z }}} = {}
|
||||
|
||||
return { foo, bar, baz, y, z }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > defineEmits() 1`] = `
|
||||
"export default {
|
||||
emits: ['foo', 'bar'],
|
||||
setup(__props, { emit: myEmit }) {
|
||||
|
||||
|
||||
|
||||
return { myEmit }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > defineExpose() 1`] = `
|
||||
"export default {
|
||||
setup(__props, { expose }) {
|
||||
|
||||
expose({ foo: 123 })
|
||||
|
||||
return { }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > defineProps w/ external definition 1`] = `
|
||||
"import { propsModel } from './props'
|
||||
|
||||
export default {
|
||||
props: propsModel,
|
||||
setup(__props) {
|
||||
|
||||
const props = __props
|
||||
|
||||
|
||||
|
||||
return { props, propsModel }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > defineProps w/ leading code 1`] = `
|
||||
"import { x } from './x'
|
||||
|
||||
export default {
|
||||
props: {},
|
||||
setup(__props) {
|
||||
|
||||
const props = __props
|
||||
|
||||
|
||||
return { props, x }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > defineProps() 1`] = `
|
||||
"export default {
|
||||
props: {
|
||||
foo: String
|
||||
},
|
||||
setup(__props) {
|
||||
|
||||
const props = __props
|
||||
|
||||
|
||||
const bar = 1
|
||||
|
||||
return { props, bar }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > defineProps/defineEmits in multi-variable declaration (full removal) 1`] = `
|
||||
"export default {
|
||||
props: ['item'],
|
||||
emits: ['a'],
|
||||
setup(__props, { emit }) {
|
||||
|
||||
const props = __props
|
||||
|
||||
|
||||
|
||||
return { props, emit }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > defineProps/defineEmits in multi-variable declaration 1`] = `
|
||||
"export default {
|
||||
props: ['item'],
|
||||
emits: ['a'],
|
||||
setup(__props, { emit }) {
|
||||
|
||||
const props = __props
|
||||
|
||||
const a = 1;
|
||||
|
||||
return { props, a, emit }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > dev mode import usage check > TS annotations 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import { Foo, Baz, Qux, Fred } from './x'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
const a = 1
|
||||
function b() {}
|
||||
|
||||
return { a, b, Baz }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > dev mode import usage check > attribute expressions 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import { bar, baz } from './x'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
const cond = true
|
||||
|
||||
return { cond, bar, baz }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > dev mode import usage check > components 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import { FooBar, FooBaz, FooQux, foo } from './x'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
const fooBar: FooBar = 1
|
||||
|
||||
return { fooBar, FooBaz, FooQux, foo }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > dev mode import usage check > directive 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import { vMyDir } from './x'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { vMyDir }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > dev mode import usage check > js template string interpolations 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import { VAR, VAR2, VAR3 } from './x'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { VAR, VAR3 }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > dev mode import usage check > last tag 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import { FooBaz, Last } from './x'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { FooBaz, Last }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > dev mode import usage check > vue interpolations 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import { x, y, z, x$y } from './x'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { x, z, x$y }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > errors > should allow defineProps/Emit() referencing imported binding 1`] = `
|
||||
"import { bar } from './bar'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
foo: {
|
||||
default: () => bar
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
foo: () => bar > 1
|
||||
},
|
||||
setup(__props) {
|
||||
|
||||
|
||||
|
||||
|
||||
return { bar }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > errors > should allow defineProps/Emit() referencing scope var 1`] = `
|
||||
"export default {
|
||||
props: {
|
||||
foo: {
|
||||
default: bar => bar + 1
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
foo: bar => bar > 1
|
||||
},
|
||||
setup(__props) {
|
||||
|
||||
const bar = 1
|
||||
|
||||
|
||||
|
||||
return { bar }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > imports > import dedupe between <script> and <script setup> 1`] = `
|
||||
"import { x } from './x'
|
||||
|
||||
export default {
|
||||
setup(__props) {
|
||||
|
||||
x()
|
||||
|
||||
return { x }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > imports > should allow defineProps/Emit at the start of imports 1`] = `
|
||||
"import { ref } from 'vue'
|
||||
|
||||
export default {
|
||||
props: ['foo'],
|
||||
emits: ['bar'],
|
||||
setup(__props) {
|
||||
|
||||
|
||||
|
||||
const r = ref(0)
|
||||
|
||||
return { r, ref }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > imports > should extract comment for import or type declarations 1`] = `
|
||||
"import a from 'a' // comment
|
||||
import b from 'b'
|
||||
|
||||
export default {
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { a, b }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > imports > should hoist and expose imports 1`] = `
|
||||
"import { ref } from 'vue'
|
||||
import 'foo/css'
|
||||
|
||||
export default {
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { ref }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > should expose top level declarations 1`] = `
|
||||
"import { xx } from './x'
|
||||
let aa = 1
|
||||
const bb = 2
|
||||
function cc() {}
|
||||
class dd {}
|
||||
|
||||
import { x } from './x'
|
||||
|
||||
export default {
|
||||
setup(__props) {
|
||||
|
||||
let a = 1
|
||||
const b = 2
|
||||
function c() {}
|
||||
class d {}
|
||||
|
||||
return { aa, bb, cc, dd, a, b, c, d, xx, x }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > const Enum 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
const enum Foo { A = 123 }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { Foo }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (exported interface) 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
export interface Emits { (e: 'foo' | 'bar'): void }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
emits: [\\"foo\\", \\"bar\\"],
|
||||
setup(__props, { emit }: { emit: ({ (e: 'foo' | 'bar'): void }), expose: any, slots: any, attrs: any }) {
|
||||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (exported type alias) 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
export type Emits = { (e: 'foo' | 'bar'): void }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
emits: [\\"foo\\", \\"bar\\"],
|
||||
setup(__props, { emit }: { emit: ({ (e: 'foo' | 'bar'): void }), expose: any, slots: any, attrs: any }) {
|
||||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (interface) 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
interface Emits { (e: 'foo' | 'bar'): void }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
emits: [\\"foo\\", \\"bar\\"],
|
||||
setup(__props, { emit }: { emit: ({ (e: 'foo' | 'bar'): void }), expose: any, slots: any, attrs: any }) {
|
||||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (referenced exported function type) 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
export type Emits = (e: 'foo' | 'bar') => void
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
emits: [\\"foo\\", \\"bar\\"],
|
||||
setup(__props, { emit }: { emit: ((e: 'foo' | 'bar') => void), expose: any, slots: any, attrs: any }) {
|
||||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (referenced function type) 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
type Emits = (e: 'foo' | 'bar') => void
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
emits: [\\"foo\\", \\"bar\\"],
|
||||
setup(__props, { emit }: { emit: ((e: 'foo' | 'bar') => void), expose: any, slots: any, attrs: any }) {
|
||||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (type alias) 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
type Emits = { (e: 'foo' | 'bar'): void }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
emits: [\\"foo\\", \\"bar\\"],
|
||||
setup(__props, { emit }: { emit: ({ (e: 'foo' | 'bar'): void }), expose: any, slots: any, attrs: any }) {
|
||||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type (type literal w/ call signatures) 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
emits: [\\"foo\\", \\"bar\\", \\"baz\\"],
|
||||
setup(__props, { emit }: { emit: ({(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;}), expose: any, slots: any, attrs: any }) {
|
||||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineEmits w/ type 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
emits: [\\"foo\\", \\"bar\\"],
|
||||
setup(__props, { emit }: { emit: ((e: 'foo' | 'bar') => void), expose: any, slots: any, attrs: any }) {
|
||||
|
||||
|
||||
|
||||
return { emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineProps w/ exported interface 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
export interface Props { x?: number }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: {
|
||||
x: { type: Number, required: false }
|
||||
},
|
||||
setup(__props: any) {
|
||||
|
||||
|
||||
|
||||
return { }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineProps w/ exported interface in normal script 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
|
||||
export interface Props { x?: number }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: {
|
||||
x: { type: Number, required: false }
|
||||
},
|
||||
setup(__props: any) {
|
||||
|
||||
|
||||
|
||||
return { }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineProps w/ exported type alias 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
export type Props = { x?: number }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: {
|
||||
x: { type: Number, required: false }
|
||||
},
|
||||
setup(__props: any) {
|
||||
|
||||
|
||||
|
||||
return { }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineProps w/ interface 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
interface Props { x?: number }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: {
|
||||
x: { type: Number, required: false }
|
||||
},
|
||||
setup(__props: any) {
|
||||
|
||||
|
||||
|
||||
return { }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineProps w/ type 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
interface Test {}
|
||||
|
||||
type Alias = number[]
|
||||
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: {
|
||||
string: { type: String, required: true },
|
||||
number: { type: Number, required: true },
|
||||
boolean: { type: Boolean, required: true },
|
||||
object: { type: Object, required: true },
|
||||
objectLiteral: { type: Object, required: true },
|
||||
fn: { type: Function, required: true },
|
||||
functionRef: { type: Function, required: true },
|
||||
objectRef: { type: Object, required: true },
|
||||
dateTime: { type: Date, required: true },
|
||||
array: { type: Array, required: true },
|
||||
arrayRef: { type: Array, required: true },
|
||||
tuple: { type: Array, required: true },
|
||||
set: { type: Set, required: true },
|
||||
literal: { type: String, required: true },
|
||||
optional: { type: null, required: false },
|
||||
recordRef: { type: Object, required: true },
|
||||
interface: { type: Object, required: true },
|
||||
alias: { type: Array, required: true },
|
||||
method: { type: Function, required: true },
|
||||
symbol: { type: Symbol, required: true },
|
||||
union: { type: [String, Number], required: true },
|
||||
literalUnion: { type: String, required: true },
|
||||
literalUnionNumber: { type: Number, required: true },
|
||||
literalUnionMixed: { type: [String, Number, Boolean], required: true },
|
||||
intersection: { type: Object, required: true },
|
||||
foo: { type: [Function, null], required: true }
|
||||
},
|
||||
setup(__props: any) {
|
||||
|
||||
|
||||
|
||||
return { }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineProps w/ type alias 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
type Props = { x?: number }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: {
|
||||
x: { type: Number, required: false }
|
||||
},
|
||||
setup(__props: any) {
|
||||
|
||||
|
||||
|
||||
return { }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > defineProps/Emit w/ runtime options 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: { foo: String },
|
||||
emits: ['a', 'b'],
|
||||
setup(__props, { emit }) {
|
||||
|
||||
const props = __props
|
||||
|
||||
|
||||
|
||||
|
||||
return { props, emit }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > hoist type declarations 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
export interface Foo {}
|
||||
type Bar = {}
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > import type 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
import type { Foo } from './main.ts'
|
||||
import { type Bar, Baz } from './main.ts'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { Baz }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > runtime Enum 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
enum Foo { A = 123 }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { Foo }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > runtime Enum in normal script 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
enum Foo { A = 123 }
|
||||
|
||||
export enum D { D = \\"D\\" }
|
||||
const enum C { C = \\"C\\" }
|
||||
enum B { B = \\"B\\" }
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
setup(__props) {
|
||||
|
||||
|
||||
return { D, C, B, Foo }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > withDefaults (dynamic) 1`] = `
|
||||
"import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from 'vue'
|
||||
import { defaults } from './foo'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: _mergeDefaults({
|
||||
foo: { type: String, required: false },
|
||||
bar: { type: Number, required: false },
|
||||
baz: { type: Boolean, required: true }
|
||||
}, { ...defaults }),
|
||||
setup(__props: any) {
|
||||
|
||||
const props = __props as {
|
||||
foo?: string
|
||||
bar?: number
|
||||
baz: boolean
|
||||
}
|
||||
|
||||
|
||||
|
||||
return { props, defaults }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
||||
|
||||
exports[`SFC compile <script setup> > with TypeScript > withDefaults (static) 1`] = `
|
||||
"import { defineComponent as _defineComponent } from 'vue'
|
||||
|
||||
export default /*#__PURE__*/_defineComponent({
|
||||
props: {
|
||||
foo: { type: String, required: false, default: 'hi' },
|
||||
bar: { type: Number, required: false },
|
||||
baz: { type: Boolean, required: true },
|
||||
qux: { type: Function, required: false, default() { return 1 } }
|
||||
},
|
||||
setup(__props: any) {
|
||||
|
||||
const props = __props as { foo: string, bar?: number, baz: boolean, qux(): number }
|
||||
|
||||
|
||||
|
||||
return { props }
|
||||
}
|
||||
|
||||
})"
|
||||
`;
|
189
node_modules/vue/packages/compiler-sfc/test/__snapshots__/cssVars.spec.ts.snap
generated
vendored
Normal file
189
node_modules/vue/packages/compiler-sfc/test/__snapshots__/cssVars.spec.ts.snap
generated
vendored
Normal file
@ -0,0 +1,189 @@
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`CSS vars injection > codegen > <script> w/ default export 1`] = `
|
||||
"const __default__ = { setup() {} }
|
||||
import { useCssVars as _useCssVars } from 'vue'
|
||||
const __injectCSSVars__ = () => {
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-color\\": (_vm.color)
|
||||
}))}
|
||||
const __setup__ = __default__.setup
|
||||
__default__.setup = __setup__
|
||||
? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }
|
||||
: __injectCSSVars__
|
||||
|
||||
export default __default__"
|
||||
`;
|
||||
|
||||
exports[`CSS vars injection > codegen > <script> w/ default export in strings/comments 1`] = `
|
||||
"
|
||||
// export default {}
|
||||
const __default__ = {}
|
||||
|
||||
import { useCssVars as _useCssVars } from 'vue'
|
||||
const __injectCSSVars__ = () => {
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-color\\": (_vm.color)
|
||||
}))}
|
||||
const __setup__ = __default__.setup
|
||||
__default__.setup = __setup__
|
||||
? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }
|
||||
: __injectCSSVars__
|
||||
|
||||
export default __default__"
|
||||
`;
|
||||
|
||||
exports[`CSS vars injection > codegen > <script> w/ no default export 1`] = `
|
||||
"const a = 1
|
||||
const __default__ = {}
|
||||
import { useCssVars as _useCssVars } from 'vue'
|
||||
const __injectCSSVars__ = () => {
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-color\\": (_vm.color)
|
||||
}))}
|
||||
const __setup__ = __default__.setup
|
||||
__default__.setup = __setup__
|
||||
? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }
|
||||
: __injectCSSVars__
|
||||
|
||||
export default __default__"
|
||||
`;
|
||||
|
||||
exports[`CSS vars injection > codegen > should ignore comments 1`] = `
|
||||
"import { useCssVars as _useCssVars } from 'vue'
|
||||
|
||||
export default {
|
||||
setup(__props) {
|
||||
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-width\\": (_setup.width)
|
||||
}))
|
||||
const color = 'red';const width = 100
|
||||
return { color, width }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`CSS vars injection > codegen > should work with w/ complex expression 1`] = `
|
||||
"import { useCssVars as _useCssVars } from 'vue'
|
||||
|
||||
export default {
|
||||
setup(__props) {
|
||||
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-foo\\": (_setup.foo),
|
||||
\\"xxxxxxxx-foo____px_\\": (_setup.foo + 'px'),
|
||||
\\"xxxxxxxx-_a___b____2____px_\\": ((_setup.a + _setup.b) / 2 + 'px'),
|
||||
\\"xxxxxxxx-__a___b______2___a_\\": (((_setup.a + _setup.b)) / (2 * _setup.a))
|
||||
}))
|
||||
|
||||
let a = 100
|
||||
let b = 200
|
||||
let foo = 300
|
||||
|
||||
return { a, b, foo }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`CSS vars injection > codegen > w/ <script setup> 1`] = `
|
||||
"import { useCssVars as _useCssVars } from 'vue'
|
||||
|
||||
export default {
|
||||
setup(__props) {
|
||||
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-color\\": (_setup.color)
|
||||
}))
|
||||
const color = 'red'
|
||||
return { color }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`CSS vars injection > codegen > w/ <script setup> using the same var multiple times 1`] = `
|
||||
"import { useCssVars as _useCssVars } from 'vue'
|
||||
|
||||
export default {
|
||||
setup(__props) {
|
||||
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-color\\": (_setup.color)
|
||||
}))
|
||||
|
||||
const color = 'red'
|
||||
|
||||
return { color }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`CSS vars injection > generating correct code for nested paths 1`] = `
|
||||
"const a = 1
|
||||
const __default__ = {}
|
||||
import { useCssVars as _useCssVars } from 'vue'
|
||||
const __injectCSSVars__ = () => {
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-color\\": (_vm.color),
|
||||
\\"xxxxxxxx-font_size\\": (_vm.font.size)
|
||||
}))}
|
||||
const __setup__ = __default__.setup
|
||||
__default__.setup = __setup__
|
||||
? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }
|
||||
: __injectCSSVars__
|
||||
|
||||
export default __default__"
|
||||
`;
|
||||
|
||||
exports[`CSS vars injection > w/ <script setup> binding analysis 1`] = `
|
||||
"import { useCssVars as _useCssVars } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
foo: String
|
||||
},
|
||||
setup(__props) {
|
||||
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-color\\": (_setup.color),
|
||||
\\"xxxxxxxx-size\\": (_setup.size),
|
||||
\\"xxxxxxxx-foo\\": (_vm.foo)
|
||||
}))
|
||||
|
||||
const color = 'red'
|
||||
const size = ref('10px')
|
||||
|
||||
|
||||
return { color, size, ref }
|
||||
}
|
||||
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`CSS vars injection > w/ normal <script> binding analysis 1`] = `
|
||||
"
|
||||
const __default__ = {
|
||||
setup() {
|
||||
return {
|
||||
size: ref('100px')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import { useCssVars as _useCssVars } from 'vue'
|
||||
const __injectCSSVars__ = () => {
|
||||
_useCssVars((_vm, _setup) => ({
|
||||
\\"xxxxxxxx-size\\": (_vm.size)
|
||||
}))}
|
||||
const __setup__ = __default__.setup
|
||||
__default__.setup = __setup__
|
||||
? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }
|
||||
: __injectCSSVars__
|
||||
|
||||
export default __default__"
|
||||
`;
|
1594
node_modules/vue/packages/compiler-sfc/test/compileScript.spec.ts
generated
vendored
Normal file
1594
node_modules/vue/packages/compiler-sfc/test/compileScript.spec.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
203
node_modules/vue/packages/compiler-sfc/test/compileStyle.spec.ts
generated
vendored
Normal file
203
node_modules/vue/packages/compiler-sfc/test/compileStyle.spec.ts
generated
vendored
Normal file
@ -0,0 +1,203 @@
|
||||
import { parse } from '../src/parse'
|
||||
import { compileStyle, compileStyleAsync } from '../src/compileStyle'
|
||||
|
||||
test('preprocess less', () => {
|
||||
const style = parse({
|
||||
source:
|
||||
'<style lang="less">\n' +
|
||||
'@red: rgb(255, 0, 0);\n' +
|
||||
'.color { color: @red; }\n' +
|
||||
'</style>\n',
|
||||
filename: 'example.vue',
|
||||
sourceMap: true
|
||||
}).styles[0]
|
||||
|
||||
const result = compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
filename: 'example.vue',
|
||||
source: style.content,
|
||||
map: style.map,
|
||||
scoped: false,
|
||||
preprocessLang: style.lang
|
||||
})
|
||||
|
||||
expect(result.errors.length).toBe(0)
|
||||
expect(result.code).toEqual(expect.stringContaining('color: #ff0000;'))
|
||||
expect(result.map).toBeTruthy()
|
||||
})
|
||||
|
||||
test('preprocess scss', () => {
|
||||
const style = parse({
|
||||
source:
|
||||
'<style lang="scss">\n' +
|
||||
'$red: red;\n' +
|
||||
'.color { color: $red; }\n' +
|
||||
'</style>\n',
|
||||
filename: 'example.vue',
|
||||
sourceMap: true
|
||||
}).styles[0]
|
||||
const result = compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
filename: 'example.vue',
|
||||
source: style.content,
|
||||
map: style.map,
|
||||
scoped: false,
|
||||
preprocessLang: style.lang
|
||||
})
|
||||
|
||||
expect(result.errors.length).toBe(0)
|
||||
expect(result.code).toMatch('color: red;')
|
||||
expect(result.map).toBeTruthy()
|
||||
})
|
||||
|
||||
test('preprocess sass', () => {
|
||||
const style = parse({
|
||||
source:
|
||||
'<style lang="sass">\n' +
|
||||
'$red: red\n' +
|
||||
'.color\n' +
|
||||
' color: $red\n' +
|
||||
'</style>\n',
|
||||
filename: 'example.vue',
|
||||
sourceMap: true
|
||||
}).styles[0]
|
||||
const result = compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
filename: 'example.vue',
|
||||
source: style.content,
|
||||
map: style.map,
|
||||
scoped: false,
|
||||
preprocessLang: style.lang
|
||||
})
|
||||
|
||||
expect(result.errors.length).toBe(0)
|
||||
expect(result.code).toMatch('color: red;')
|
||||
expect(result.map).toBeTruthy()
|
||||
})
|
||||
|
||||
test('preprocess stylus', () => {
|
||||
const style = parse({
|
||||
source:
|
||||
'<style lang="styl">\n' +
|
||||
'red-color = rgb(255, 0, 0);\n' +
|
||||
'.color\n' +
|
||||
' color: red-color\n' +
|
||||
'</style>\n',
|
||||
filename: 'example.vue',
|
||||
sourceMap: true
|
||||
}).styles[0]
|
||||
const result = compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
filename: 'example.vue',
|
||||
source: style.content,
|
||||
map: style.map,
|
||||
scoped: false,
|
||||
preprocessLang: style.lang
|
||||
})
|
||||
|
||||
expect(result.errors.length).toBe(0)
|
||||
expect(result.code).toEqual(expect.stringContaining('color: #f00;'))
|
||||
expect(result.map).toBeTruthy()
|
||||
})
|
||||
|
||||
test('custom postcss plugin', () => {
|
||||
const spy = vi.fn()
|
||||
|
||||
compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
filename: 'example.vue',
|
||||
source: '.foo { color: red }',
|
||||
scoped: false,
|
||||
postcssPlugins: [require('postcss').plugin('test-plugin', () => spy)()]
|
||||
})
|
||||
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test('custom postcss options', () => {
|
||||
const result = compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
filename: 'example.vue',
|
||||
source: '.foo { color: red }',
|
||||
scoped: false,
|
||||
postcssOptions: { random: 'foo' }
|
||||
})
|
||||
|
||||
expect((result.rawResult as any).opts.random).toBe('foo')
|
||||
})
|
||||
|
||||
test('async postcss plugin in sync mode', () => {
|
||||
const result = compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
filename: 'example.vue',
|
||||
source: '.foo { color: red }',
|
||||
scoped: false,
|
||||
postcssPlugins: [
|
||||
require('postcss').plugin(
|
||||
'test-plugin',
|
||||
() => async (result: any) => result
|
||||
)
|
||||
]
|
||||
})
|
||||
|
||||
expect(result.errors).toHaveLength(1)
|
||||
})
|
||||
|
||||
test('async postcss plugin', async () => {
|
||||
const promise = compileStyleAsync({
|
||||
id: 'v-scope-xxx',
|
||||
filename: 'example.vue',
|
||||
source: '.foo { color: red }',
|
||||
scoped: false,
|
||||
postcssPlugins: [
|
||||
require('postcss').plugin(
|
||||
'test-plugin',
|
||||
() => async (result: any) => result
|
||||
)
|
||||
]
|
||||
})
|
||||
|
||||
expect(promise instanceof Promise).toBe(true)
|
||||
|
||||
const result = await promise
|
||||
expect(result.errors).toHaveLength(0)
|
||||
expect(result.code).toEqual(expect.stringContaining('color: red'))
|
||||
})
|
||||
|
||||
test('media query', () => {
|
||||
const result = compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
scoped: true,
|
||||
filename: 'example.vue',
|
||||
source: `
|
||||
@media print {
|
||||
.foo {
|
||||
color: #000;
|
||||
}
|
||||
}`
|
||||
})
|
||||
|
||||
expect(result.errors).toHaveLength(0)
|
||||
expect(result.code).toContain(
|
||||
'@media print {\n.foo[v-scope-xxx] {\n color: #000;\n}\n}'
|
||||
)
|
||||
})
|
||||
|
||||
test('supports query', () => {
|
||||
const result = compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
scoped: true,
|
||||
filename: 'example.vue',
|
||||
source: `
|
||||
@supports ( color: #000 ) {
|
||||
.foo {
|
||||
color: #000;
|
||||
}
|
||||
}`
|
||||
})
|
||||
|
||||
expect(result.errors).toHaveLength(0)
|
||||
expect(result.code).toContain(
|
||||
'@supports ( color: #000 ) {\n.foo[v-scope-xxx] {\n color: #000;\n}\n}'
|
||||
)
|
||||
})
|
258
node_modules/vue/packages/compiler-sfc/test/compileTemplate.spec.ts
generated
vendored
Normal file
258
node_modules/vue/packages/compiler-sfc/test/compileTemplate.spec.ts
generated
vendored
Normal file
@ -0,0 +1,258 @@
|
||||
import { parse } from '../src/parse'
|
||||
import { SFCBlock } from '../src/parseComponent'
|
||||
import { compileTemplate } from '../src/compileTemplate'
|
||||
import Vue from 'vue'
|
||||
|
||||
function mockRender(code: string, mocks: Record<string, any> = {}) {
|
||||
const fn = new Function(
|
||||
`require`,
|
||||
`${code}; return { render, staticRenderFns }`
|
||||
)
|
||||
const vm = new Vue(
|
||||
Object.assign(
|
||||
{},
|
||||
fn((id: string) => mocks[id])
|
||||
)
|
||||
)
|
||||
vm.$mount()
|
||||
return (vm as any)._vnode
|
||||
}
|
||||
|
||||
test('should work', () => {
|
||||
const source = `<div><p>{{ render }}</p></div>`
|
||||
|
||||
const result = compileTemplate({
|
||||
filename: 'example.vue',
|
||||
source
|
||||
})
|
||||
|
||||
expect(result.errors.length).toBe(0)
|
||||
expect(result.source).toBe(source)
|
||||
// should expose render fns
|
||||
expect(result.code).toMatch(`var render = function`)
|
||||
expect(result.code).toMatch(`var staticRenderFns = []`)
|
||||
// should mark with stripped
|
||||
expect(result.code).toMatch(`render._withStripped = true`)
|
||||
// should prefix bindings
|
||||
expect(result.code).toMatch(`_vm.render`)
|
||||
expect(result.ast).not.toBeUndefined()
|
||||
})
|
||||
|
||||
test('preprocess pug', () => {
|
||||
const template = parse({
|
||||
source:
|
||||
'<template lang="pug">\n' +
|
||||
'body\n' +
|
||||
' h1 Pug Examples\n' +
|
||||
' div.container\n' +
|
||||
' p Cool Pug example!\n' +
|
||||
'</template>\n',
|
||||
filename: 'example.vue',
|
||||
sourceMap: true
|
||||
}).template as SFCBlock
|
||||
|
||||
const result = compileTemplate({
|
||||
filename: 'example.vue',
|
||||
source: template.content,
|
||||
preprocessLang: template.lang
|
||||
})
|
||||
|
||||
expect(result.errors.length).toBe(0)
|
||||
})
|
||||
|
||||
/**
|
||||
* vuejs/component-compiler-utils#22 Support uri fragment in transformed require
|
||||
*/
|
||||
test('supports uri fragment in transformed require', () => {
|
||||
const source = '<svg>\
|
||||
<use href="~@svg/file.svg#fragment"></use>\
|
||||
</svg>' //
|
||||
const result = compileTemplate({
|
||||
filename: 'svgparticle.html',
|
||||
source: source,
|
||||
transformAssetUrls: {
|
||||
use: 'href'
|
||||
}
|
||||
})
|
||||
expect(result.errors.length).toBe(0)
|
||||
expect(result.code).toMatch(
|
||||
/href: require\("@svg\/file.svg"\) \+ "#fragment"/
|
||||
)
|
||||
})
|
||||
|
||||
/**
|
||||
* vuejs/component-compiler-utils#22 Support uri fragment in transformed require
|
||||
*/
|
||||
test('when too short uri then empty require', () => {
|
||||
const source = '<svg>\
|
||||
<use href="~"></use>\
|
||||
</svg>' //
|
||||
const result = compileTemplate({
|
||||
filename: 'svgparticle.html',
|
||||
source: source,
|
||||
transformAssetUrls: {
|
||||
use: 'href'
|
||||
}
|
||||
})
|
||||
expect(result.errors.length).toBe(0)
|
||||
expect(result.code).toMatch(/href: require\(""\)/)
|
||||
})
|
||||
|
||||
test('warn missing preprocessor', () => {
|
||||
const template = parse({
|
||||
source: '<template lang="unknownLang">\n' + '</template>\n',
|
||||
|
||||
filename: 'example.vue',
|
||||
sourceMap: true
|
||||
}).template as SFCBlock
|
||||
|
||||
const result = compileTemplate({
|
||||
filename: 'example.vue',
|
||||
source: template.content,
|
||||
preprocessLang: template.lang
|
||||
})
|
||||
|
||||
expect(result.errors.length).toBe(1)
|
||||
})
|
||||
|
||||
test('transform assetUrls', () => {
|
||||
const source = `
|
||||
<div>
|
||||
<img src="./logo.png">
|
||||
<img src="~fixtures/logo.png">
|
||||
<img src="~/fixtures/logo.png">
|
||||
</div>
|
||||
`
|
||||
const result = compileTemplate({
|
||||
filename: 'example.vue',
|
||||
source,
|
||||
transformAssetUrls: true
|
||||
})
|
||||
expect(result.errors.length).toBe(0)
|
||||
|
||||
const vnode = mockRender(result.code, {
|
||||
'./logo.png': 'a',
|
||||
'fixtures/logo.png': 'b'
|
||||
})
|
||||
|
||||
expect(vnode.children[0].data.attrs.src).toBe('a')
|
||||
expect(vnode.children[2].data.attrs.src).toBe('b')
|
||||
expect(vnode.children[4].data.attrs.src).toBe('b')
|
||||
})
|
||||
|
||||
test('transform srcset', () => {
|
||||
const source = `
|
||||
<div>
|
||||
<img src="./logo.png">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
|
||||
<image xlink:href="./logo.png" />
|
||||
</svg>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
|
||||
<use xlink:href="./logo.png"/>
|
||||
</svg>
|
||||
</svg>
|
||||
<img src="./logo.png" srcset="./logo.png">
|
||||
<img src="./logo.png" srcset="./logo.png 2x">
|
||||
<img src="./logo.png" srcset="./logo.png, ./logo.png 2x">
|
||||
<img src="./logo.png" srcset="./logo.png 2x, ./logo.png">
|
||||
<img src="./logo.png" srcset="./logo.png 2x, ./logo.png 3x">
|
||||
<img src="./logo.png" srcset="./logo.png, ./logo.png 2x, ./logo.png 3x">
|
||||
<img
|
||||
src="./logo.png"
|
||||
srcset="
|
||||
./logo.png 2x,
|
||||
./logo.png 3x
|
||||
">
|
||||
</div>
|
||||
`
|
||||
const result = compileTemplate({
|
||||
filename: 'example.vue',
|
||||
source,
|
||||
transformAssetUrls: true
|
||||
})
|
||||
expect(result.errors.length).toBe(0)
|
||||
|
||||
const vnode = mockRender(result.code, {
|
||||
'./logo.png': 'test-url'
|
||||
})
|
||||
|
||||
// img tag
|
||||
expect(vnode.children[0].data.attrs.src).toBe('test-url')
|
||||
// image tag (SVG)
|
||||
expect(vnode.children[2].children[0].data.attrs['xlink:href']).toBe(
|
||||
'test-url'
|
||||
)
|
||||
// use tag (SVG)
|
||||
expect(vnode.children[4].children[0].data.attrs['xlink:href']).toBe(
|
||||
'test-url'
|
||||
)
|
||||
|
||||
// image tag with srcset
|
||||
expect(vnode.children[6].data.attrs.srcset).toBe('test-url')
|
||||
expect(vnode.children[8].data.attrs.srcset).toBe('test-url 2x')
|
||||
// image tag with multiline srcset
|
||||
expect(vnode.children[10].data.attrs.srcset).toBe('test-url, test-url 2x')
|
||||
expect(vnode.children[12].data.attrs.srcset).toBe('test-url 2x, test-url')
|
||||
expect(vnode.children[14].data.attrs.srcset).toBe('test-url 2x, test-url 3x')
|
||||
expect(vnode.children[16].data.attrs.srcset).toBe(
|
||||
'test-url, test-url 2x, test-url 3x'
|
||||
)
|
||||
expect(vnode.children[18].data.attrs.srcset).toBe('test-url 2x, test-url 3x')
|
||||
})
|
||||
|
||||
test('transform assetUrls and srcset with base option', () => {
|
||||
const source = `
|
||||
<div>
|
||||
<img src="./logo.png">
|
||||
<img src="~fixtures/logo.png">
|
||||
<img src="~/fixtures/logo.png">
|
||||
<img src="./logo.png" srcset="./logo.png 2x, ./logo.png 3x">
|
||||
<img src="@/fixtures/logo.png">
|
||||
</div>
|
||||
`
|
||||
const result = compileTemplate({
|
||||
filename: 'example.vue',
|
||||
source,
|
||||
transformAssetUrls: true,
|
||||
transformAssetUrlsOptions: { base: '/base/' }
|
||||
})
|
||||
|
||||
expect(result.errors.length).toBe(0)
|
||||
|
||||
const vnode = mockRender(result.code, {
|
||||
'@/fixtures/logo.png': 'aliased'
|
||||
})
|
||||
expect(vnode.children[0].data.attrs.src).toBe('/base/logo.png')
|
||||
expect(vnode.children[2].data.attrs.src).toBe('/base/fixtures/logo.png')
|
||||
expect(vnode.children[4].data.attrs.src).toBe('/base/fixtures/logo.png')
|
||||
expect(vnode.children[6].data.attrs.srcset).toBe(
|
||||
'/base/logo.png 2x, /base/logo.png 3x'
|
||||
)
|
||||
expect(vnode.children[8].data.attrs.src).toBe('aliased')
|
||||
})
|
||||
|
||||
test('transform with includeAbsolute', () => {
|
||||
const source = `
|
||||
<div>
|
||||
<img src="./logo.png">
|
||||
<img src="/logo.png">
|
||||
<img src="https://foo.com/logo.png">
|
||||
</div>
|
||||
`
|
||||
const result = compileTemplate({
|
||||
filename: 'example.vue',
|
||||
source,
|
||||
transformAssetUrls: true,
|
||||
transformAssetUrlsOptions: { includeAbsolute: true }
|
||||
})
|
||||
|
||||
expect(result.errors.length).toBe(0)
|
||||
|
||||
const vnode = mockRender(result.code, {
|
||||
'./logo.png': 'relative',
|
||||
'/logo.png': 'absolute'
|
||||
})
|
||||
expect(vnode.children[0].data.attrs.src).toBe('relative')
|
||||
expect(vnode.children[2].data.attrs.src).toBe('absolute')
|
||||
expect(vnode.children[4].data.attrs.src).toBe('https://foo.com/logo.png')
|
||||
})
|
247
node_modules/vue/packages/compiler-sfc/test/cssVars.spec.ts
generated
vendored
Normal file
247
node_modules/vue/packages/compiler-sfc/test/cssVars.spec.ts
generated
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
import { compileStyle, parse } from '../src'
|
||||
import { mockId, compile, assertCode } from './util'
|
||||
|
||||
describe('CSS vars injection', () => {
|
||||
test('generating correct code for nested paths', () => {
|
||||
const { content } = compile(
|
||||
`<script>const a = 1</script>\n` +
|
||||
`<style>div{
|
||||
color: v-bind(color);
|
||||
font-size: v-bind('font.size');
|
||||
}</style>`
|
||||
)
|
||||
expect(content).toMatch(`_useCssVars((_vm, _setup) => ({
|
||||
"${mockId}-color": (_vm.color),
|
||||
"${mockId}-font_size": (_vm.font.size)
|
||||
})`)
|
||||
assertCode(content)
|
||||
})
|
||||
|
||||
test('w/ normal <script> binding analysis', () => {
|
||||
const { content } = compile(
|
||||
`<script>
|
||||
export default {
|
||||
setup() {
|
||||
return {
|
||||
size: ref('100px')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>\n` +
|
||||
`<style>
|
||||
div {
|
||||
font-size: v-bind(size);
|
||||
}
|
||||
</style>`
|
||||
)
|
||||
expect(content).toMatch(`_useCssVars((_vm, _setup) => ({
|
||||
"${mockId}-size": (_vm.size)
|
||||
})`)
|
||||
expect(content).toMatch(`import { useCssVars as _useCssVars } from 'vue'`)
|
||||
assertCode(content)
|
||||
})
|
||||
|
||||
test('w/ <script setup> binding analysis', () => {
|
||||
const { content } = compile(
|
||||
`<script setup>
|
||||
import { defineProps, ref } from 'vue'
|
||||
const color = 'red'
|
||||
const size = ref('10px')
|
||||
defineProps({
|
||||
foo: String
|
||||
})
|
||||
</script>\n` +
|
||||
`<style>
|
||||
div {
|
||||
color: v-bind(color);
|
||||
font-size: v-bind(size);
|
||||
border: v-bind(foo);
|
||||
}
|
||||
</style>`
|
||||
)
|
||||
// should handle:
|
||||
// 1. local const bindings
|
||||
// 2. local potential ref bindings
|
||||
// 3. props bindings (analyzed)
|
||||
expect(content).toMatch(`_useCssVars((_vm, _setup) => ({
|
||||
"${mockId}-color": (_setup.color),
|
||||
"${mockId}-size": (_setup.size),
|
||||
"${mockId}-foo": (_vm.foo)
|
||||
})`)
|
||||
expect(content).toMatch(`import { useCssVars as _useCssVars } from 'vue'`)
|
||||
assertCode(content)
|
||||
})
|
||||
|
||||
test('should rewrite CSS vars in compileStyle', () => {
|
||||
const { code } = compileStyle({
|
||||
source: `.foo {
|
||||
color: v-bind(color);
|
||||
font-size: v-bind('font.size');
|
||||
}`,
|
||||
filename: 'test.css',
|
||||
id: 'data-v-test'
|
||||
})
|
||||
expect(code).toMatchInlineSnapshot(`
|
||||
".foo[data-v-test] {
|
||||
color: var(--test-color);
|
||||
font-size: var(--test-font_size);
|
||||
}"
|
||||
`)
|
||||
})
|
||||
|
||||
test('prod mode', () => {
|
||||
const { content } = compile(
|
||||
`<script>const a = 1</script>\n` +
|
||||
`<style>div{
|
||||
color: v-bind(color);
|
||||
font-size: v-bind('font.size');
|
||||
}</style>`,
|
||||
{ isProd: true }
|
||||
)
|
||||
expect(content).toMatch(`_useCssVars((_vm, _setup) => ({
|
||||
"4003f1a6": (_vm.color),
|
||||
"41b6490a": (_vm.font.size)
|
||||
}))}`)
|
||||
|
||||
const { code } = compileStyle({
|
||||
source: `.foo {
|
||||
color: v-bind(color);
|
||||
font-size: v-bind('font.size');
|
||||
}`,
|
||||
filename: 'test.css',
|
||||
id: mockId,
|
||||
isProd: true
|
||||
})
|
||||
expect(code).toMatchInlineSnapshot(`
|
||||
".foo[xxxxxxxx] {
|
||||
color: var(--4003f1a6);
|
||||
font-size: var(--41b6490a);
|
||||
}"
|
||||
`)
|
||||
})
|
||||
|
||||
describe('codegen', () => {
|
||||
test('<script> w/ no default export', () => {
|
||||
assertCode(
|
||||
compile(
|
||||
`<script>const a = 1</script>\n` +
|
||||
`<style>div{ color: v-bind(color); }</style>`
|
||||
).content
|
||||
)
|
||||
})
|
||||
|
||||
test('<script> w/ default export', () => {
|
||||
assertCode(
|
||||
compile(
|
||||
`<script>export default { setup() {} }</script>\n` +
|
||||
`<style>div{ color: v-bind(color); }</style>`
|
||||
).content
|
||||
)
|
||||
})
|
||||
|
||||
test('<script> w/ default export in strings/comments', () => {
|
||||
assertCode(
|
||||
compile(
|
||||
`<script>
|
||||
// export default {}
|
||||
export default {}
|
||||
</script>\n` + `<style>div{ color: v-bind(color); }</style>`
|
||||
).content
|
||||
)
|
||||
})
|
||||
|
||||
test('w/ <script setup>', () => {
|
||||
assertCode(
|
||||
compile(
|
||||
`<script setup>const color = 'red'</script>\n` +
|
||||
`<style>div{ color: v-bind(color); }</style>`
|
||||
).content
|
||||
)
|
||||
})
|
||||
|
||||
//#4185
|
||||
test('should ignore comments', () => {
|
||||
const { content } = compile(
|
||||
`<script setup>const color = 'red';const width = 100</script>\n` +
|
||||
`<style>
|
||||
/* comment **/
|
||||
div{ /* color: v-bind(color); */ width:20; }
|
||||
div{ width: v-bind(width); }
|
||||
/* comment */
|
||||
</style>`
|
||||
)
|
||||
|
||||
expect(content).not.toMatch(`"${mockId}-color": (_setup.color)`)
|
||||
expect(content).toMatch(`"${mockId}-width": (_setup.width)`)
|
||||
assertCode(content)
|
||||
})
|
||||
|
||||
test('w/ <script setup> using the same var multiple times', () => {
|
||||
const { content } = compile(
|
||||
`<script setup>
|
||||
const color = 'red'
|
||||
</script>\n` +
|
||||
`<style>
|
||||
div {
|
||||
color: v-bind(color);
|
||||
}
|
||||
p {
|
||||
color: v-bind(color);
|
||||
}
|
||||
</style>`
|
||||
)
|
||||
// color should only be injected once, even if it is twice in style
|
||||
expect(content).toMatch(`_useCssVars((_vm, _setup) => ({
|
||||
"${mockId}-color": (_setup.color)
|
||||
})`)
|
||||
assertCode(content)
|
||||
})
|
||||
|
||||
test('should work with w/ complex expression', () => {
|
||||
const { content } = compile(
|
||||
`<script setup>
|
||||
let a = 100
|
||||
let b = 200
|
||||
let foo = 300
|
||||
</script>\n` +
|
||||
`<style>
|
||||
p{
|
||||
width: calc(v-bind(foo) - 3px);
|
||||
height: calc(v-bind('foo') - 3px);
|
||||
top: calc(v-bind(foo + 'px') - 3px);
|
||||
}
|
||||
div {
|
||||
color: v-bind((a + b) / 2 + 'px' );
|
||||
}
|
||||
div {
|
||||
color: v-bind ((a + b) / 2 + 'px' );
|
||||
}
|
||||
p {
|
||||
color: v-bind(((a + b)) / (2 * a));
|
||||
}
|
||||
</style>`
|
||||
)
|
||||
expect(content).toMatch(`_useCssVars((_vm, _setup) => ({
|
||||
"${mockId}-foo": (_setup.foo),
|
||||
"${mockId}-foo____px_": (_setup.foo + 'px'),
|
||||
"${mockId}-_a___b____2____px_": ((_setup.a + _setup.b) / 2 + 'px'),
|
||||
"${mockId}-__a___b______2___a_": (((_setup.a + _setup.b)) / (2 * _setup.a))
|
||||
})`)
|
||||
assertCode(content)
|
||||
})
|
||||
|
||||
// #6022
|
||||
test('should be able to parse incomplete expressions', () => {
|
||||
const { cssVars } = parse({
|
||||
source: `<script setup>let xxx = 1</script>
|
||||
<style scoped>
|
||||
label {
|
||||
font-weight: v-bind("count.toString(");
|
||||
font-weight: v-bind(xxx);
|
||||
}
|
||||
</style>`
|
||||
})
|
||||
expect(cssVars).toMatchObject([`count.toString(`, `xxx`])
|
||||
})
|
||||
})
|
||||
})
|
269
node_modules/vue/packages/compiler-sfc/test/parseComponent.spec.ts
generated
vendored
Normal file
269
node_modules/vue/packages/compiler-sfc/test/parseComponent.spec.ts
generated
vendored
Normal file
@ -0,0 +1,269 @@
|
||||
import { WarningMessage } from 'types/compiler'
|
||||
import { parseComponent } from '../src/parseComponent'
|
||||
|
||||
describe('Single File Component parser', () => {
|
||||
it('should parse', () => {
|
||||
const res = parseComponent(
|
||||
`
|
||||
<template>
|
||||
<div>hi</div>
|
||||
</template>
|
||||
<style src="./test.css"></style>
|
||||
<style lang="stylus" scoped>
|
||||
h1
|
||||
color red
|
||||
h2
|
||||
color green
|
||||
</style>
|
||||
<style module>
|
||||
h1 { font-weight: bold }
|
||||
</style>
|
||||
<style bool-attr val-attr="test"></style>
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
||||
<div>
|
||||
<style>nested should be ignored</style>
|
||||
</div>
|
||||
`
|
||||
)
|
||||
expect(res.template!.content.trim()).toBe('<div>hi</div>')
|
||||
expect(res.styles.length).toBe(4)
|
||||
expect(res.styles[0].src).toBe('./test.css')
|
||||
expect(res.styles[1].lang).toBe('stylus')
|
||||
expect(res.styles[1].scoped).toBe(true)
|
||||
expect(res.styles[1].content.trim()).toBe(
|
||||
'h1\n color red\nh2\n color green'
|
||||
)
|
||||
expect(res.styles[2].module).toBe(true)
|
||||
expect(res.styles[3].attrs['bool-attr']).toBe(true)
|
||||
expect(res.styles[3].attrs['val-attr']).toBe('test')
|
||||
expect(res.script!.content.trim()).toBe('export default {}')
|
||||
})
|
||||
|
||||
it('should parse template with closed input', () => {
|
||||
const res = parseComponent(`
|
||||
<template>
|
||||
<input type="text"/>
|
||||
</template>
|
||||
`)
|
||||
|
||||
expect(res.template!.content.trim()).toBe('<input type="text"/>')
|
||||
})
|
||||
|
||||
it('should handle nested template', () => {
|
||||
const res = parseComponent(`
|
||||
<template>
|
||||
<div><template v-if="ok">hi</template></div>
|
||||
</template>
|
||||
`)
|
||||
expect(res.template!.content.trim()).toBe(
|
||||
'<div><template v-if="ok">hi</template></div>'
|
||||
)
|
||||
})
|
||||
|
||||
it('deindent content', () => {
|
||||
const content = `
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
||||
<style>
|
||||
h1 { color: red }
|
||||
</style>
|
||||
`
|
||||
const deindentDefault = parseComponent(content.trim(), {
|
||||
pad: false
|
||||
})
|
||||
const deindentEnabled = parseComponent(content.trim(), {
|
||||
pad: false,
|
||||
deindent: true
|
||||
})
|
||||
const deindentDisabled = parseComponent(content.trim(), {
|
||||
pad: false,
|
||||
deindent: false
|
||||
})
|
||||
|
||||
expect(deindentDefault.template!.content).toBe('\n<div></div>\n')
|
||||
expect(deindentDefault.script!.content).toBe(
|
||||
'\n export default {}\n '
|
||||
)
|
||||
expect(deindentDefault.styles[0].content).toBe('\nh1 { color: red }\n')
|
||||
expect(deindentEnabled.template!.content).toBe('\n<div></div>\n')
|
||||
expect(deindentEnabled.script!.content).toBe('\nexport default {}\n')
|
||||
expect(deindentEnabled.styles[0].content).toBe('\nh1 { color: red }\n')
|
||||
expect(deindentDisabled.template!.content).toBe(
|
||||
'\n <div></div>\n '
|
||||
)
|
||||
expect(deindentDisabled.script!.content).toBe(
|
||||
'\n export default {}\n '
|
||||
)
|
||||
expect(deindentDisabled.styles[0].content).toBe(
|
||||
'\n h1 { color: red }\n '
|
||||
)
|
||||
})
|
||||
|
||||
it('pad content', () => {
|
||||
const content = `
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
||||
<style>
|
||||
h1 { color: red }
|
||||
</style>
|
||||
`
|
||||
const padDefault = parseComponent(content.trim(), {
|
||||
pad: true,
|
||||
deindent: true
|
||||
})
|
||||
const padLine = parseComponent(content.trim(), {
|
||||
pad: 'line',
|
||||
deindent: true
|
||||
})
|
||||
const padSpace = parseComponent(content.trim(), {
|
||||
pad: 'space',
|
||||
deindent: true
|
||||
})
|
||||
|
||||
expect(padDefault.script!.content).toBe(
|
||||
Array(3 + 1).join('//\n') + '\nexport default {}\n'
|
||||
)
|
||||
expect(padDefault.styles[0].content).toBe(
|
||||
Array(6 + 1).join('\n') + '\nh1 { color: red }\n'
|
||||
)
|
||||
expect(padLine.script!.content).toBe(
|
||||
Array(3 + 1).join('//\n') + '\nexport default {}\n'
|
||||
)
|
||||
expect(padLine.styles[0].content).toBe(
|
||||
Array(6 + 1).join('\n') + '\nh1 { color: red }\n'
|
||||
)
|
||||
expect(padSpace.script!.content).toBe(
|
||||
`<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script>`.replace(/./g, ' ') + '\nexport default {}\n'
|
||||
)
|
||||
expect(padSpace.styles[0].content).toBe(
|
||||
`<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
||||
<style>`.replace(/./g, ' ') + '\nh1 { color: red }\n'
|
||||
)
|
||||
})
|
||||
|
||||
it('should handle template blocks with lang as special text', () => {
|
||||
const res = parseComponent(
|
||||
`
|
||||
<template lang="pug">
|
||||
div
|
||||
h1(v-if='1 < 2') hello
|
||||
</template>
|
||||
`,
|
||||
{ deindent: true }
|
||||
)
|
||||
expect(res.template!.content.trim()).toBe(`div\n h1(v-if='1 < 2') hello`)
|
||||
})
|
||||
|
||||
it('should handle component contains "<" only', () => {
|
||||
const res = parseComponent(`
|
||||
<template>
|
||||
<span><</span>
|
||||
</template>
|
||||
`)
|
||||
expect(res.template!.content.trim()).toBe(`<span><</span>`)
|
||||
})
|
||||
|
||||
it('should handle custom blocks without parsing them', () => {
|
||||
const res = parseComponent(
|
||||
`
|
||||
<template>
|
||||
<div></div>
|
||||
</template>
|
||||
<example name="simple">
|
||||
<my-button ref="button">Hello</my-button>
|
||||
</example>
|
||||
<example name="with props">
|
||||
<my-button color="red">Hello</my-button>
|
||||
</example>
|
||||
<test name="simple" foo="bar">
|
||||
export default function simple (vm) {
|
||||
describe('Hello', () => {
|
||||
it('should display Hello', () => {
|
||||
this.vm.$refs.button.$el.innerText.should.equal('Hello')
|
||||
}))
|
||||
}))
|
||||
}
|
||||
</test>
|
||||
<custom src="./x.json"></custom>
|
||||
`
|
||||
)
|
||||
expect(res.customBlocks.length).toBe(4)
|
||||
|
||||
const simpleExample = res.customBlocks[0]
|
||||
expect(simpleExample.type).toBe('example')
|
||||
expect(simpleExample.content.trim()).toBe(
|
||||
'<my-button ref="button">Hello</my-button>'
|
||||
)
|
||||
expect(simpleExample.attrs.name).toBe('simple')
|
||||
|
||||
const withProps = res.customBlocks[1]
|
||||
expect(withProps.type).toBe('example')
|
||||
expect(withProps.content.trim()).toBe(
|
||||
'<my-button color="red">Hello</my-button>'
|
||||
)
|
||||
expect(withProps.attrs.name).toBe('with props')
|
||||
|
||||
const simpleTest = res.customBlocks[2]
|
||||
expect(simpleTest.type).toBe('test')
|
||||
expect(simpleTest.content.trim())
|
||||
.toBe(`export default function simple (vm) {
|
||||
describe('Hello', () => {
|
||||
it('should display Hello', () => {
|
||||
this.vm.$refs.button.$el.innerText.should.equal('Hello')
|
||||
}))
|
||||
}))
|
||||
}`)
|
||||
expect(simpleTest.attrs.name).toBe('simple')
|
||||
expect(simpleTest.attrs.foo).toBe('bar')
|
||||
|
||||
const customWithSrc = res.customBlocks[3]
|
||||
expect(customWithSrc.src).toBe('./x.json')
|
||||
})
|
||||
|
||||
// Regression #4289
|
||||
it('accepts nested template tag', () => {
|
||||
const raw = `<div>
|
||||
<template v-if="true === true">
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
Should be shown
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<template v-else>
|
||||
<p>Should not be shown</p>
|
||||
</template>
|
||||
</div>`
|
||||
const res = parseComponent(`<template>${raw}</template>`)
|
||||
expect(res.template!.content.trim()).toBe(raw)
|
||||
})
|
||||
|
||||
it('should not hang on trailing text', () => {
|
||||
const res = parseComponent(`<template>hi</`)
|
||||
expect(res.template!.content).toBe('hi')
|
||||
})
|
||||
|
||||
it('should collect errors with source range', () => {
|
||||
const res = parseComponent(`<template>hi</`, { outputSourceRange: true })
|
||||
expect(res.errors.length).toBe(1)
|
||||
expect((res.errors[0] as WarningMessage).start).toBe(0)
|
||||
})
|
||||
})
|
97
node_modules/vue/packages/compiler-sfc/test/prefixIdentifiers.spec.ts
generated
vendored
Normal file
97
node_modules/vue/packages/compiler-sfc/test/prefixIdentifiers.spec.ts
generated
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
import { prefixIdentifiers } from '../src/prefixIdentifiers'
|
||||
import { compile } from 'web/entry-compiler'
|
||||
import { format } from 'prettier'
|
||||
import { BindingTypes } from '../src/types'
|
||||
|
||||
const toFn = (source: string) => `function render(){${source}\n}`
|
||||
|
||||
it('should work', () => {
|
||||
const { render } = compile(`<div id="app">
|
||||
<div :style="{ color }">{{ foo }}</div>
|
||||
<p v-for="i in list">{{ i }}</p>
|
||||
<foo inline-template>
|
||||
<div>{{ bar }}</div>
|
||||
</foo>
|
||||
</div>`)
|
||||
|
||||
const result = format(prefixIdentifiers(toFn(render)), {
|
||||
semi: false,
|
||||
parser: 'babel'
|
||||
})
|
||||
|
||||
expect(result).not.toMatch(`_vm._c`)
|
||||
expect(result).toMatch(`_vm.foo`)
|
||||
expect(result).toMatch(`_vm.list`)
|
||||
expect(result).toMatch(`{ color: _vm.color }`)
|
||||
expect(result).not.toMatch(`_vm.i`)
|
||||
expect(result).not.toMatch(`with (this)`)
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"function render() {
|
||||
var _vm = this,
|
||||
_c = _vm._self._c
|
||||
return _c(
|
||||
\\"div\\",
|
||||
{ attrs: { id: \\"app\\" } },
|
||||
[
|
||||
_c(\\"div\\", { style: { color: _vm.color } }, [_vm._v(_vm._s(_vm.foo))]),
|
||||
_vm._v(\\" \\"),
|
||||
_vm._l(_vm.list, function (i) {
|
||||
return _c(\\"p\\", [_vm._v(_vm._s(i))])
|
||||
}),
|
||||
_vm._v(\\" \\"),
|
||||
_c(\\"foo\\", {
|
||||
inlineTemplate: {
|
||||
render: function () {
|
||||
var _vm = this,
|
||||
_c = _vm._self._c
|
||||
return _c(\\"div\\", [_vm._v(_vm._s(_vm.bar))])
|
||||
},
|
||||
staticRenderFns: [],
|
||||
},
|
||||
}),
|
||||
],
|
||||
2
|
||||
)
|
||||
}
|
||||
"
|
||||
`)
|
||||
})
|
||||
|
||||
it('setup bindings', () => {
|
||||
const { render } = compile(`<div @click="count++">{{ count }}</div>`)
|
||||
|
||||
const result = format(
|
||||
prefixIdentifiers(toFn(render), false, false, undefined, {
|
||||
count: BindingTypes.SETUP_REF
|
||||
}),
|
||||
{
|
||||
semi: false,
|
||||
parser: 'babel'
|
||||
}
|
||||
)
|
||||
|
||||
expect(result).toMatch(`_setup = _vm._self._setupProxy`)
|
||||
expect(result).toMatch(`_setup.count++`)
|
||||
expect(result).toMatch(`_vm._s(_setup.count)`)
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"function render() {
|
||||
var _vm = this,
|
||||
_c = _vm._self._c,
|
||||
_setup = _vm._self._setupProxy
|
||||
return _c(
|
||||
\\"div\\",
|
||||
{
|
||||
on: {
|
||||
click: function (\$event) {
|
||||
_setup.count++
|
||||
},
|
||||
},
|
||||
},
|
||||
[_vm._v(_vm._s(_setup.count))]
|
||||
)
|
||||
}
|
||||
"
|
||||
`)
|
||||
})
|
245
node_modules/vue/packages/compiler-sfc/test/rewriteDefault.spec.ts
generated
vendored
Normal file
245
node_modules/vue/packages/compiler-sfc/test/rewriteDefault.spec.ts
generated
vendored
Normal file
@ -0,0 +1,245 @@
|
||||
import { rewriteDefault } from '../src'
|
||||
|
||||
describe('compiler sfc: rewriteDefault', () => {
|
||||
test('without export default', () => {
|
||||
expect(rewriteDefault(`export a = {}`, 'script')).toMatchInlineSnapshot(`
|
||||
"export a = {}
|
||||
const script = {}"
|
||||
`)
|
||||
})
|
||||
|
||||
test('rewrite export default', () => {
|
||||
expect(
|
||||
rewriteDefault(`export default {}`, 'script')
|
||||
).toMatchInlineSnapshot(`"const script = {}"`)
|
||||
})
|
||||
|
||||
test('rewrite export named default', () => {
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`const a = 1 \n export { a as b, a as default, a as c}`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"const a = 1
|
||||
export { a as b, a as c}
|
||||
const script = a"
|
||||
`)
|
||||
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`const a = 1 \n export { a as b, a as default , a as c}`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"const a = 1
|
||||
export { a as b, a as c}
|
||||
const script = a"
|
||||
`)
|
||||
})
|
||||
|
||||
test('w/ comments', async () => {
|
||||
expect(rewriteDefault(`// export default\nexport default {}`, 'script'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"// export default
|
||||
const script = {}"
|
||||
`)
|
||||
})
|
||||
|
||||
test('export named default multiline', () => {
|
||||
expect(
|
||||
rewriteDefault(`let App = {}\n export {\nApp as default\n}`, '_sfc_main')
|
||||
).toMatchInlineSnapshot(`
|
||||
"let App = {}
|
||||
export {
|
||||
|
||||
}
|
||||
const _sfc_main = App"
|
||||
`)
|
||||
})
|
||||
|
||||
test('export named default multiline /w comments', () => {
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`const a = 1 \n export {\n a as b,\n a as default,\n a as c}\n` +
|
||||
`// export { myFunction as default }`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"const a = 1
|
||||
export {
|
||||
a as b,
|
||||
|
||||
a as c}
|
||||
// export { myFunction as default }
|
||||
const script = a"
|
||||
`)
|
||||
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`const a = 1 \n export {\n a as b,\n a as default ,\n a as c}\n` +
|
||||
`// export { myFunction as default }`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"const a = 1
|
||||
export {
|
||||
a as b,
|
||||
|
||||
a as c}
|
||||
// export { myFunction as default }
|
||||
const script = a"
|
||||
`)
|
||||
})
|
||||
|
||||
test(`export { default } from '...'`, async () => {
|
||||
expect(
|
||||
rewriteDefault(`export { default, foo } from './index.js'`, 'script')
|
||||
).toMatchInlineSnapshot(`
|
||||
"import { default as __VUE_DEFAULT__ } from './index.js'
|
||||
export { foo } from './index.js'
|
||||
const script = __VUE_DEFAULT__"
|
||||
`)
|
||||
|
||||
expect(
|
||||
rewriteDefault(`export { default , foo } from './index.js'`, 'script')
|
||||
).toMatchInlineSnapshot(`
|
||||
"import { default as __VUE_DEFAULT__ } from './index.js'
|
||||
export { foo } from './index.js'
|
||||
const script = __VUE_DEFAULT__"
|
||||
`)
|
||||
|
||||
expect(
|
||||
rewriteDefault(`export { foo, default } from './index.js'`, 'script')
|
||||
).toMatchInlineSnapshot(`
|
||||
"import { default as __VUE_DEFAULT__ } from './index.js'
|
||||
export { foo, } from './index.js'
|
||||
const script = __VUE_DEFAULT__"
|
||||
`)
|
||||
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`export { foo as default, bar } from './index.js'`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"import { foo } from './index.js'
|
||||
export { bar } from './index.js'
|
||||
const script = foo"
|
||||
`)
|
||||
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`export { foo as default , bar } from './index.js'`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"import { foo } from './index.js'
|
||||
export { bar } from './index.js'
|
||||
const script = foo"
|
||||
`)
|
||||
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`export { bar, foo as default } from './index.js'`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"import { foo } from './index.js'
|
||||
export { bar, } from './index.js'
|
||||
const script = foo"
|
||||
`)
|
||||
})
|
||||
|
||||
test('export default class', async () => {
|
||||
expect(rewriteDefault(`export default class Foo {}`, 'script'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"class Foo {}
|
||||
const script = Foo"
|
||||
`)
|
||||
})
|
||||
|
||||
test('export default class w/ comments', async () => {
|
||||
expect(
|
||||
rewriteDefault(`// export default\nexport default class Foo {}`, 'script')
|
||||
).toMatchInlineSnapshot(`
|
||||
"// export default
|
||||
class Foo {}
|
||||
const script = Foo"
|
||||
`)
|
||||
})
|
||||
|
||||
test('export default class w/ comments 2', async () => {
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`export default {}\n` + `// export default class Foo {}`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"const script = {}
|
||||
// export default class Foo {}"
|
||||
`)
|
||||
})
|
||||
|
||||
test('export default class w/ comments 3', async () => {
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`/*\nexport default class Foo {}*/\n` + `export default class Bar {}`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"/*
|
||||
export default class Foo {}*/
|
||||
class Bar {}
|
||||
const script = Bar"
|
||||
`)
|
||||
})
|
||||
|
||||
test('@Component\nexport default class', async () => {
|
||||
expect(rewriteDefault(`@Component\nexport default class Foo {}`, 'script'))
|
||||
.toMatchInlineSnapshot(`
|
||||
"@Component
|
||||
class Foo {}
|
||||
const script = Foo"
|
||||
`)
|
||||
})
|
||||
|
||||
test('@Component\nexport default class w/ comments', async () => {
|
||||
expect(
|
||||
rewriteDefault(`// export default\n@Component\nexport default class Foo {}`, 'script')
|
||||
).toMatchInlineSnapshot(`
|
||||
"// export default
|
||||
@Component
|
||||
class Foo {}
|
||||
const script = Foo"
|
||||
`)
|
||||
})
|
||||
|
||||
test('@Component\nexport default class w/ comments 2', async () => {
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`export default {}\n` + `// @Component\n// export default class Foo {}`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"const script = {}
|
||||
// @Component
|
||||
// export default class Foo {}"
|
||||
`)
|
||||
})
|
||||
|
||||
test('@Component\nexport default class w/ comments 3', async () => {
|
||||
expect(
|
||||
rewriteDefault(
|
||||
`/*\n@Component\nexport default class Foo {}*/\n` + `export default class Bar {}`,
|
||||
'script'
|
||||
)
|
||||
).toMatchInlineSnapshot(`
|
||||
"/*
|
||||
@Component
|
||||
export default class Foo {}*/
|
||||
class Bar {}
|
||||
const script = Bar"
|
||||
`)
|
||||
})
|
||||
})
|
137
node_modules/vue/packages/compiler-sfc/test/stylePluginScoped.spec.ts
generated
vendored
Normal file
137
node_modules/vue/packages/compiler-sfc/test/stylePluginScoped.spec.ts
generated
vendored
Normal file
@ -0,0 +1,137 @@
|
||||
import { compileStyle } from '../src/compileStyle'
|
||||
|
||||
// vue-loader/#1370
|
||||
test('spaces after selector', () => {
|
||||
const { code } = compileStyle({
|
||||
source: `.foo , .bar { color: red; }`,
|
||||
filename: 'test.css',
|
||||
id: 'test'
|
||||
})
|
||||
|
||||
expect(code).toMatch(`.foo[test], .bar[test] { color: red;`)
|
||||
})
|
||||
|
||||
test('leading deep selector', () => {
|
||||
const { code } = compileStyle({
|
||||
source: `>>> .foo { color: red; }`,
|
||||
filename: 'test.css',
|
||||
id: 'test'
|
||||
})
|
||||
|
||||
expect(code).toMatch(`[test] .foo { color: red;`)
|
||||
})
|
||||
|
||||
test('scoped css', () => {
|
||||
const { code: style } = compileStyle({
|
||||
id: 'v-scope-xxx',
|
||||
scoped: true,
|
||||
filename: 'example.vue',
|
||||
source: `
|
||||
.test {
|
||||
color: yellow;
|
||||
}
|
||||
.test:after {
|
||||
content: 'bye!';
|
||||
}
|
||||
h1 {
|
||||
color: green;
|
||||
}
|
||||
.anim {
|
||||
animation: color 5s infinite, other 5s;
|
||||
}
|
||||
.anim-2 {
|
||||
animation-name: color;
|
||||
animation-duration: 5s;
|
||||
}
|
||||
.anim-3 {
|
||||
animation: 5s color infinite, 5s other;
|
||||
}
|
||||
.anim-multiple {
|
||||
animation: color 5s infinite, opacity 2s;
|
||||
}
|
||||
.anim-multiple-2 {
|
||||
animation-name: color, opacity;
|
||||
animation-duration: 5s, 2s;
|
||||
}
|
||||
|
||||
@keyframes color {
|
||||
from { color: red; }
|
||||
to { color: green; }
|
||||
}
|
||||
@-webkit-keyframes color {
|
||||
from { color: red; }
|
||||
to { color: green; }
|
||||
}
|
||||
@keyframes opacity {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
@-webkit-keyframes opacity {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
.foo p >>> .bar {
|
||||
color: red;
|
||||
}
|
||||
.foo div /deep/ .bar {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.foo span ::v-deep .bar {
|
||||
color: red;
|
||||
}
|
||||
`
|
||||
})
|
||||
|
||||
expect(style).toContain(`.test[v-scope-xxx] {\n color: yellow;\n}`)
|
||||
expect(style).toContain(`.test[v-scope-xxx]:after {\n content: \'bye!\';\n}`)
|
||||
expect(style).toContain(`h1[v-scope-xxx] {\n color: green;\n}`)
|
||||
// scoped keyframes
|
||||
expect(style).toContain(
|
||||
`.anim[v-scope-xxx] {\n animation: color-v-scope-xxx 5s infinite, other 5s;`
|
||||
)
|
||||
expect(style).toContain(
|
||||
`.anim-2[v-scope-xxx] {\n animation-name: color-v-scope-xxx`
|
||||
)
|
||||
expect(style).toContain(
|
||||
`.anim-3[v-scope-xxx] {\n animation: 5s color-v-scope-xxx infinite, 5s other;`
|
||||
)
|
||||
expect(style).toContain(`@keyframes color-v-scope-xxx {`)
|
||||
expect(style).toContain(`@-webkit-keyframes color-v-scope-xxx {`)
|
||||
|
||||
expect(style).toContain(
|
||||
`.anim-multiple[v-scope-xxx] {\n animation: color-v-scope-xxx 5s infinite,opacity-v-scope-xxx 2s;`
|
||||
)
|
||||
expect(style).toContain(
|
||||
`.anim-multiple-2[v-scope-xxx] {\n animation-name: color-v-scope-xxx,opacity-v-scope-xxx;`
|
||||
)
|
||||
expect(style).toContain(`@keyframes opacity-v-scope-xxx {`)
|
||||
expect(style).toContain(`@-webkit-keyframes opacity-v-scope-xxx {`)
|
||||
// >>> combinator
|
||||
expect(style).toContain(`.foo p[v-scope-xxx] .bar {\n color: red;\n}`)
|
||||
// /deep/ alias for >>>
|
||||
expect(style).toContain(`.foo div[v-scope-xxx] .bar {\n color: red;\n}`)
|
||||
// ::-v-deep alias for >>>
|
||||
expect(style).toContain(`.foo span[v-scope-xxx] .bar {\n color: red;\n}`)
|
||||
})
|
||||
|
||||
test('pseudo element', () => {
|
||||
const { code } = compileStyle({
|
||||
source: '::selection { display: none; }',
|
||||
filename: 'test.css',
|
||||
id: 'test'
|
||||
})
|
||||
|
||||
expect(code).toContain('[test]::selection {')
|
||||
})
|
||||
|
||||
test('spaces before pseudo element', () => {
|
||||
const { code } = compileStyle({
|
||||
source: '.abc, ::selection { color: red; }',
|
||||
filename: 'test.css',
|
||||
id: 'test'
|
||||
})
|
||||
|
||||
expect(code).toContain('.abc[test],')
|
||||
expect(code).toContain('[test]::selection {')
|
||||
})
|
7
node_modules/vue/packages/compiler-sfc/test/tsconfig.json
generated
vendored
Normal file
7
node_modules/vue/packages/compiler-sfc/test/tsconfig.json
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node", "vitest/globals"]
|
||||
},
|
||||
"include": ["../src", "."]
|
||||
}
|
35
node_modules/vue/packages/compiler-sfc/test/util.ts
generated
vendored
Normal file
35
node_modules/vue/packages/compiler-sfc/test/util.ts
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
import {
|
||||
parse,
|
||||
compileScript,
|
||||
type SFCParseOptions,
|
||||
type SFCScriptCompileOptions
|
||||
} from '../src'
|
||||
import { parse as babelParse } from '@babel/parser'
|
||||
|
||||
export const mockId = 'xxxxxxxx'
|
||||
|
||||
export function compile(
|
||||
source: string,
|
||||
options?: Partial<SFCScriptCompileOptions>,
|
||||
parseOptions?: Partial<SFCParseOptions>
|
||||
) {
|
||||
const sfc = parse({
|
||||
...parseOptions,
|
||||
source
|
||||
})
|
||||
return compileScript(sfc, { id: mockId, ...options })
|
||||
}
|
||||
|
||||
export function assertCode(code: string) {
|
||||
// parse the generated code to make sure it is valid
|
||||
try {
|
||||
babelParse(code, {
|
||||
sourceType: 'module',
|
||||
plugins: ['typescript']
|
||||
})
|
||||
} catch (e: any) {
|
||||
console.log(code)
|
||||
throw e
|
||||
}
|
||||
expect(code).toMatchSnapshot()
|
||||
}
|
Reference in New Issue
Block a user