第一
This commit is contained in:
		
							parent
							
								
									fa6556a0d5
								
							
						
					
					
						commit
						05b8cc7469
					
				| @ -65,6 +65,7 @@ export function baseCompile( | ||||
|   const onError = options.onError || defaultOnError | ||||
|   const isModuleMode = options.mode === 'module' | ||||
|   /* istanbul ignore if */ | ||||
|   // 只要不是 dev onError 就是空函数
 | ||||
|   if (__BROWSER__) { | ||||
|     if (options.prefixIdentifiers === true) { | ||||
|       onError(createCompilerError(ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED)) | ||||
| @ -81,7 +82,7 @@ export function baseCompile( | ||||
|   if (options.scopeId && !isModuleMode) { | ||||
|     onError(createCompilerError(ErrorCodes.X_SCOPE_ID_NOT_SUPPORTED)) | ||||
|   } | ||||
| 
 | ||||
|   // 给options 赋初始值 如果不是字符串 直接返回 template
 | ||||
|   const ast = isString(template) ? baseParse(template, options) : template | ||||
|   const [nodeTransforms, directiveTransforms] = | ||||
|     getBaseTransformPreset(prefixIdentifiers) | ||||
|  | ||||
| @ -67,17 +67,17 @@ const decodeMap: Record<string, string> = { | ||||
| } | ||||
| 
 | ||||
| export const defaultParserOptions: MergedParserOptions = { | ||||
|   delimiters: [`{{`, `}}`], | ||||
|   getNamespace: () => Namespaces.HTML, | ||||
|   getTextMode: () => TextModes.DATA, | ||||
|   isVoidTag: NO, | ||||
|   isPreTag: NO, | ||||
|   isCustomElement: NO, | ||||
|   delimiters: [`{{`, `}}`], // 模板分割付
 | ||||
|   getNamespace: () => Namespaces.HTML, // HTML
 | ||||
|   getTextMode: () => TextModes.DATA, //DATA
 | ||||
|   isVoidTag: NO, // 无效标签
 | ||||
|   isPreTag: NO, // 是不是pre标签
 | ||||
|   isCustomElement: NO, // 是不是自定义标签
 | ||||
|   decodeEntities: (rawText: string): string => | ||||
|     rawText.replace(decodeRE, (_, p1) => decodeMap[p1]), | ||||
|     rawText.replace(decodeRE, (_, p1) => decodeMap[p1]), // 讲实体字符转换成字符串
 | ||||
|   onError: defaultOnError, | ||||
|   onWarn: defaultOnWarn, | ||||
|   comments: __DEV__ | ||||
|   comments: __DEV__ // ???
 | ||||
| } | ||||
| 
 | ||||
| export const enum TextModes { | ||||
| @ -105,8 +105,11 @@ export function baseParse( | ||||
|   content: string, | ||||
|   options: ParserOptions = {} | ||||
| ): RootNode { | ||||
|   // 给options 覆初始值 没有的属性都赋值进去
 | ||||
|   const context = createParserContext(content, options) | ||||
|   // 貌似获取的是固定的
 | ||||
|   const start = getCursor(context) | ||||
|   // create root
 | ||||
|   return createRoot( | ||||
|     parseChildren(context, TextModes.DATA, []), | ||||
|     getSelection(context, start) | ||||
| @ -117,15 +120,12 @@ function createParserContext( | ||||
|   content: string, | ||||
|   rawOptions: ParserOptions | ||||
| ): ParserContext { | ||||
|   const options = extend({}, defaultParserOptions) | ||||
| 
 | ||||
|   const options = extend({}, defaultParserOptions) // 这一行将所有defaultParserOptions属性复制给options
 | ||||
|   // 如果对象属性没有 讲使用默认的 defaultParserOptions
 | ||||
|   let key: keyof ParserOptions | ||||
|   for (key in rawOptions) { | ||||
|     // @ts-ignore
 | ||||
|     options[key] = | ||||
|       rawOptions[key] === undefined | ||||
|         ? defaultParserOptions[key] | ||||
|         : rawOptions[key] | ||||
|     options[key] = rawOptions[key] === undefined ? defaultParserOptions[key] : rawOptions[key] // 当rawOptions key值是undefined的时候 给defaultParserOptionsde的值 不是unidentified 给 rawOptions的值
 | ||||
|   } | ||||
|   return { | ||||
|     options, | ||||
| @ -139,24 +139,27 @@ function createParserContext( | ||||
|     onWarn: options.onWarn | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // 解析标签
 | ||||
| // ancestors 默认是空数组
 | ||||
| function parseChildren( | ||||
|   context: ParserContext, | ||||
|   mode: TextModes, | ||||
|   ancestors: ElementNode[] | ||||
| ): TemplateChildNode[] { | ||||
|   // ancestors 获取最后一个元素 默认undefined
 | ||||
|   // mode DATA
 | ||||
|   const parent = last(ancestors) | ||||
|   const ns = parent ? parent.ns : Namespaces.HTML | ||||
|   const nodes: TemplateChildNode[] = [] | ||||
| 
 | ||||
|   const ns = parent ? parent.ns : Namespaces.HTML // 如果有 就取ns 没有     HTML ?
 | ||||
|   const nodes: TemplateChildNode[] = [] // ??创建列表
 | ||||
|   // 判断是不是结束标签 
 | ||||
|   while (!isEnd(context, mode, ancestors)) { | ||||
|     __TEST__ && assert(context.source.length > 0) | ||||
|     const s = context.source | ||||
|     const s = context.source // html 代码
 | ||||
|     let node: TemplateChildNode | TemplateChildNode[] | undefined = undefined | ||||
| 
 | ||||
|     if (mode === TextModes.DATA || mode === TextModes.RCDATA) { | ||||
|       if (!context.inVPre && startsWith(s, context.options.delimiters[0])) { | ||||
|         // '{{'
 | ||||
|         // 判断是不是'{{' 开头
 | ||||
|         node = parseInterpolation(context, mode) | ||||
|       } else if (mode === TextModes.DATA && s[0] === '<') { | ||||
|         // https://html.spec.whatwg.org/multipage/parsing.html#tag-open-state
 | ||||
| @ -964,11 +967,12 @@ function parseInterpolation( | ||||
|   context: ParserContext, | ||||
|   mode: TextModes | ||||
| ): InterpolationNode | undefined { | ||||
|   const [open, close] = context.options.delimiters | ||||
|   __TEST__ && assert(startsWith(context.source, open)) | ||||
|   const [open, close] = context.options.delimiters // open {{ close }}
 | ||||
|   __TEST__ && assert(startsWith(context.source, open)) // 是否为test
 | ||||
| 
 | ||||
|   const closeIndex = context.source.indexOf(close, open.length) | ||||
|   if (closeIndex === -1) { | ||||
|   const closeIndex = context.source.indexOf(close, open.length)// 获取结束位置
 | ||||
|   if (closeIndex === -1) {  | ||||
|     // 找不到结束
 | ||||
|     emitError(context, ErrorCodes.X_MISSING_INTERPOLATION_END) | ||||
|     return undefined | ||||
|   } | ||||
| @ -1057,6 +1061,7 @@ function parseTextData( | ||||
| } | ||||
| 
 | ||||
| function getCursor(context: ParserContext): Position { | ||||
|   console.log(context) | ||||
|   const { column, line, offset } = context | ||||
|   return { column, line, offset } | ||||
| } | ||||
| @ -1067,6 +1072,7 @@ function getSelection( | ||||
|   end?: Position | ||||
| ): SourceLocation { | ||||
|   end = end || getCursor(context) | ||||
|   console.log(start,end) | ||||
|   return { | ||||
|     start, | ||||
|     end, | ||||
| @ -1132,7 +1138,7 @@ function isEnd( | ||||
|   mode: TextModes, | ||||
|   ancestors: ElementNode[] | ||||
| ): boolean { | ||||
|   const s = context.source | ||||
|   const s = context.source // 原始html
 | ||||
| 
 | ||||
|   switch (mode) { | ||||
|     case TextModes.DATA: | ||||
|  | ||||
| @ -37,10 +37,14 @@ export const DOMDirectiveTransforms: Record<string, DirectiveTransform> = { | ||||
|   show: transformShow | ||||
| } | ||||
| 
 | ||||
| // 生成语法树
 | ||||
| export function compile( | ||||
|   template: string, | ||||
|   options: CompilerOptions = {} | ||||
| ): CodegenResult { | ||||
|   // template 模板
 | ||||
|   // options 不知道干啥的参数
 | ||||
|   // console.log(options)
 | ||||
|   return baseCompile( | ||||
|     template, | ||||
|     extend({}, parserOptions, options, { | ||||
|  | ||||
| @ -756,6 +756,7 @@ let installWithProxy: (i: ComponentInternalInstance) => void | ||||
|  * For runtime-dom to register the compiler. | ||||
|  * Note the exported method uses any to avoid d.ts relying on the compiler types. | ||||
|  */ | ||||
| // ???
 | ||||
| export function registerRuntimeCompiler(_compile: any) { | ||||
|   compile = _compile | ||||
|   installWithProxy = i => { | ||||
|  | ||||
| @ -14,6 +14,7 @@ export const vShow: ObjectDirective<VShowElement> = { | ||||
|       setDisplay(el, value) | ||||
|     } | ||||
|   }, | ||||
|   // 监听器 属性复制
 | ||||
|   mounted(el, { value }, { transition }) { | ||||
|     if (transition && value) { | ||||
|       transition.enter(el) | ||||
|  | ||||
| @ -21,24 +21,31 @@ import * as runtimeDom from '@vue/runtime-dom' | ||||
| 
 | ||||
| function wrappedCreateApp(...args: any[]) { | ||||
|   // @ts-ignore
 | ||||
|   // 兼容new Vue
 | ||||
|   const app = createApp(...args) | ||||
|   // todo: 是不是看内部组件是否兼容??
 | ||||
|   if (compatUtils.isCompatEnabled(DeprecationTypes.RENDER_FUNCTION, null)) { | ||||
|     // register built-in components so that they can be resolved via strings
 | ||||
|     // in the legacy h() call. The __compat__ prefix is to ensure that v3 h()
 | ||||
|     // doesn't get affected.
 | ||||
|     // 。注册内部组件
 | ||||
|     app.component('__compat__transition', Transition) | ||||
|     app.component('__compat__transition-group', TransitionGroup) | ||||
|     app.component('__compat__keep-alive', KeepAlive) | ||||
|     // built-in directives. No need for prefix since there's no render fn API
 | ||||
|     // for resolving directives via string in v3.
 | ||||
|     // v-show 实现
 | ||||
|     app._context.directives.show = vShow | ||||
|     // v-model 实现
 | ||||
|     app._context.directives.model = vModelDynamic | ||||
|   } | ||||
|   return app | ||||
| } | ||||
| 
 | ||||
| export function createCompatVue() { | ||||
|   // 旧得全局构造函数????
 | ||||
|   const Vue = compatUtils.createCompatVue(createApp, wrappedCreateApp) | ||||
|   // 把所有runtimeDom里面的属性方法放到Vue里面
 | ||||
|   extend(Vue, runtimeDom) | ||||
|   return Vue | ||||
| } | ||||
|  | ||||
| @ -17,23 +17,31 @@ function compileToFunction( | ||||
|   template: string | HTMLElement, | ||||
|   options?: CompilerOptions | ||||
| ): RenderFunction { | ||||
|   // 不是string
 | ||||
|   if (!isString(template)) { | ||||
|     // 判断节点类型  没有就不是节点
 | ||||
|     if (template.nodeType) { | ||||
|       // 取内部的html代码
 | ||||
|       template = template.innerHTML | ||||
|     } else { | ||||
|       // 报错 返回一个空函数
 | ||||
|       __DEV__ && warn(`invalid template option: `, template) | ||||
|       return NOOP | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   const key = template | ||||
|   // 获取值
 | ||||
|   const cached = compileCache[key] | ||||
|   // 如果有值 直接返回缓存之前的
 | ||||
|   if (cached) { | ||||
|     return cached | ||||
|   } | ||||
| 
 | ||||
|   // 判断第一个字符串是不是#
 | ||||
|   if (template[0] === '#') { | ||||
|     // 那么通过id 去选择元素
 | ||||
|     const el = document.querySelector(template) | ||||
|     // 如果获取不到
 | ||||
|     if (__DEV__ && !el) { | ||||
|       warn(`Template element not found or is empty: ${template}`) | ||||
|     } | ||||
| @ -41,13 +49,14 @@ function compileToFunction( | ||||
|     // Reason: potential execution of JS expressions in in-DOM template.
 | ||||
|     // The user must make sure the in-DOM template is trusted. If it's rendered
 | ||||
|     // by the server, the template should not contain any user data.
 | ||||
|     // 获取的到 取内部的html
 | ||||
|     template = el ? el.innerHTML : `` | ||||
|   } | ||||
| 
 | ||||
|   // 如果是 dev 不是test 不包含 options.whitespace 发出警告 压缩空白
 | ||||
|   if (__DEV__ && !__TEST__ && (!options || !options.whitespace)) { | ||||
|     warnDeprecation(DeprecationTypes.CONFIG_WHITESPACE, null) | ||||
|   } | ||||
| 
 | ||||
|   // template html 模板
 | ||||
|   const { code } = compile( | ||||
|     template, | ||||
|     extend( | ||||
| @ -89,9 +98,11 @@ function compileToFunction( | ||||
|   return (compileCache[key] = render) | ||||
| } | ||||
| 
 | ||||
| // 为runtime-dom 注册编译器
 | ||||
| registerRuntimeCompiler(compileToFunction) | ||||
| 
 | ||||
| // 创建vue 初始化属性 自带组件
 | ||||
| const Vue = createCompatVue() | ||||
| // 编译?函数
 | ||||
| Vue.compile = compileToFunction | ||||
| 
 | ||||
| export default Vue | ||||
|  | ||||
| @ -6,7 +6,7 @@ import { registerRuntimeCompiler, RenderFunction, warn } from '@vue/runtime-dom' | ||||
| import * as runtimeDom from '@vue/runtime-dom' | ||||
| import { isString, NOOP, generateCodeFrame, extend } from '@vue/shared' | ||||
| import { InternalRenderFunction } from 'packages/runtime-core/src/component' | ||||
| 
 | ||||
| //  判断是不是调试模式
 | ||||
| if (__DEV__) { | ||||
|   initDev() | ||||
| } | ||||
| @ -17,21 +17,27 @@ function compileToFunction( | ||||
|   template: string | HTMLElement, | ||||
|   options?: CompilerOptions | ||||
| ): RenderFunction { | ||||
|   // 判断是不是字符串 
 | ||||
|   if (!isString(template)) { | ||||
|     // 不是字符串判断下有没有nodeType属性
 | ||||
|     if (template.nodeType) { | ||||
|       // 获取内部的html代码
 | ||||
|       template = template.innerHTML | ||||
|     } else { | ||||
|       // 报错 返回空函数
 | ||||
|       __DEV__ && warn(`invalid template option: `, template) | ||||
|       return NOOP | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // key 等于传入末班
 | ||||
|   const key = template | ||||
|   // 获取缓存 ??
 | ||||
|   const cached = compileCache[key] | ||||
|   // 有直接返回缓存
 | ||||
|   if (cached) { | ||||
|     return cached | ||||
|   } | ||||
| 
 | ||||
|   // 判断是不是id
 | ||||
|   if (template[0] === '#') { | ||||
|     const el = document.querySelector(template) | ||||
|     if (__DEV__ && !el) { | ||||
| @ -43,7 +49,10 @@ function compileToFunction( | ||||
|     // by the server, the template should not contain any user data.
 | ||||
|     template = el ? el.innerHTML : `` | ||||
|   } | ||||
| 
 | ||||
|   // 合并传入的选项
 | ||||
|   // 添加 hoistStatic
 | ||||
|   // onError
 | ||||
|   // onWarn
 | ||||
|   const opts = extend( | ||||
|     { | ||||
|       hoistStatic: true, | ||||
| @ -52,7 +61,9 @@ function compileToFunction( | ||||
|     } as CompilerOptions, | ||||
|     options | ||||
|   ) | ||||
| 
 | ||||
|   //  ?? 不知道这个是干啥的
 | ||||
|   // 根不执行
 | ||||
|   console.log(opts.isCustomElement,customElements) | ||||
|   if (!opts.isCustomElement && typeof customElements !== 'undefined') { | ||||
|     opts.isCustomElement = tag => !!customElements.get(tag) | ||||
|   } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user