您现在的位置是: 首页 > 成语成因 成语成因
compiled-compile
tamoadmin 2024-10-01 人已围观
简介Vue编译(Compile)入口Vue中的数据渲染到页面的整个流程,我们之前介绍过,不清楚可以点击这里,其中的编译流程,是将我们的template模板编译生成render函数。那为什么需要编译呢,因为template模板中有很多指令(比如@click,v-for等),原生js是识别不了的。接下来我们来分析一下Vue编译的过程:在我们之前分析的mount过程中有这样一段逻辑,compileToFun
Vue编译(Compile)入口
Vue中的数据渲染到页面的整个流程,我们之前介绍过,不清楚可以点击这里,其中的编译流程,是将我们的template模板编译生成render函数。那为什么需要编译呢,因为template模板中有很多指令(比如@click,v-for等),原生js是识别不了的。接下来我们来分析一下Vue编译的过程:
在我们之前分析的mount过程中有这样一段逻辑,compileToFunctions就是执行编译的函数,将我们定义的template作为参数传入,并生成render函数,下面我们来看下compileToFunctions:
if?(template)?{......const?{?render,?staticRenderFns?}?=?compileToFunctions(template,?{shouldDecodeNewlines,shouldDecodeNewlinesForHref,delimiters:?options.delimiters,comments:?options.comments},?this)options.render?=?renderoptions.staticRenderFns?=?staticRenderFns......}compileToFunctionscompileToFunctions定义在src/platform/web/compiler/index.js中:
import?{?baseOptions?}?from?'./options'import?{?createCompiler?}?from?'compiler/index'const?{?compile,?compileToFunctions?}?=?createCompiler(baseOptions)export?{?compile,?compileToFunctions?}可以看到,compileToFunctions是通过调用createCompiler生成的,参数baseOptions是web平台的一些配置项,继续看createCompiler函数,定义在src/compiler/index.js中:
import?{?parse?}?from?'./parser/index'import?{?optimize?}?from?'./optimizer'import?{?generate?}?from?'./codegen/index'import?{?createCompilerCreator?}?from?'./create-compiler'//?`createCompilerCreator`?allows?creating?compilers?that?use?alternative//?parser/optimizer/codegen,?e.g?the?SSR?optimizing?compiler.//?Here?we?just?export?a?default?compiler?using?the?default?parts.export?const?createCompiler?=?createCompilerCreator(function?baseCompile?(template:?string,options:?CompilerOptions):?CompiledResult?{//?解析成ast树const?ast?=?parse(template.trim(),?options)//?优化ast树if?(options.optimize?!==?false)?{optimize(ast,?options)}//?生成代码const?code?=?generate(ast,?options)return?{ast,render:?code.render,staticRenderFns:?code.staticRenderFns}})可以看到这里的createCompiler又是通过createCompilerCreator这个函数去生成的,createCompilerCreator这个函数的参数是一个函数baseCompile,这里面的逻辑是编译过程的核心,包含ast树的生成、ast树的优化、代码生成,这三个流程我们之后再去详细的分析。我们继续看createCompilerCreator这个函数,定义在src/compiler/create-compiler.js:
export?function?createCompilerCreator?(baseCompile:?Function):?Function?{return?function?createCompiler?(baseOptions:?CompilerOptions)?{//?这个函数的作用是将一些配置项合并一下,再执行传入的核心编译函数baseCompilefunction?compile?(template:?string,options?:?CompilerOptions):?CompiledResult?{//?web平台的基础配置,利用原型继承const?finalOptions?=?Object.create(baseOptions)const?errors?=?[]const?tips?=?[]finalOptions.warn?=?(msg,?tip)?=>?{(tip?tips?:?errors).push(msg)}//?配置合并if?(options)?{//?merge?custom?modulesif?(options.modules)?{finalOptions.modules?=(baseOptions.modules?||?[]).concat(options.modules)}//?merge?custom?directivesif?(options.directives)?{finalOptions.directives?=?extend(Object.create(baseOptions.directives?||?null),options.directives)}//?copy?other?optionsfor?(const?key?in?options)?{if?(key?!==?'modules'?&&?key?!==?'directives')?{finalOptions[key]?=?options[key]}}}//?核心编译函数const?compiled?=?baseCompile(template,?finalOptions)if?(process.env.NODE_ENV?!==?'production')?{errors.push.apply(errors,?detectErrors(compiled.ast))}compiled.errors?=?errorscompiled.tips?=?tipsreturn?compiled}return?{compile,compileToFunctions:?createCompileToFunctionFn(compile)}}}在这里,我们看到,compileToFunctions最终是调用了createCompileToFunctionFn这个函数,我们继续看createCompileToFunctionFn,定义在src/compiler/to-function.js:
export?function?createCompileToFunctionFn?(compile:?Function):?Function?{//?用来缓存const?cache?=?Object.create(null)return?function?compileToFunctions?(template:?string,options?:?CompilerOptions,vm?:?Component):?CompiledFunctionResult?{//?复制配置项options?=?extend({},?options)const?warn?=?options.warn?||?baseWarndelete?options.warn/*?istanbul?ignore?if?*///?判断是否支持new?Function语法if?(process.env.NODE_ENV?!==?'production')?{//?detect?possible?CSP?restrictiontry?{new?Function('return?1')}?catch?(e)?{if?(e.toString().match(/unsafe-eval|CSP/))?{warn('It?seems?you?are?using?the?standalone?build?of?Vue.js?in?an?'?+'environment?with?Content?Security?Policy?that?prohibits?unsafe-eval.?'?+'The?template?compiler?cannot?work?in?this?environment.?Consider?'?+'relaxing?the?policy?to?allow?unsafe-eval?or?pre-compiling?your?'?+'templates?into?render?functions.')}}}//?做缓存,编译是很耗时的工作,做缓存有助于提高性能,用空间换时间//?check?cacheconst?key?=?options.delimitersString(options.delimiters)?+?template:?templateif?(cache[key])?{return?cache[key]}//?compile?这儿执行传入的compile函数const?compiled?=?compile(template,?options)//?check?compilation?errors/tips//?检查编译的错误等if?(process.env.NODE_ENV?!==?'production')?{if?(compiled.errors?&&?compiled.errors.length)?{warn(`Error?compiling?template:\n\n${template}\n\n`?+compiled.errors.map(e?=>?`-?${e}`).join('\n')?+?'\n',vm)}if?(compiled.tips?&&?compiled.tips.length)?{compiled.tips.forEach(msg?=>?tip(msg,?vm))}}//?turn?code?into?functions//?这儿将编译生成的字符串代码转换成render函数,通过createFunction函数const?res?=?{}const?fnGenErrors?=?[]res.render?=?createFunction(compiled.render,?fnGenErrors)res.staticRenderFns?=?compiled.staticRenderFns.map(code?=>?{return?createFunction(code,?fnGenErrors)})//?check?function?generation?errors.//?this?should?only?happen?if?there?is?a?bug?in?the?compiler?itself.//?mostly?for?codegen?development?use/*?istanbul?ignore?if?*/if?(process.env.NODE_ENV?!==?'production')?{if?((!compiled.errors?||?!compiled.errors.length)?&&?fnGenErrors.length)?{warn(`Failed?to?generate?render?function:\n\n`?+fnGenErrors.map(({?err,?code?})?=>?`${err.toString()}?in\n\n${code}\n`).join('\n'),vm)}}return?(cache[key]?=?res)}}function?createFunction?(code,?errors)?{try?{return?new?Function(code)}?catch?(err)?{errors.push({?err,?code?})return?noop}}可以看到我们绕了很多圈,最终找到了compileToFunctions这个函数,现在我们来捋一下这个执行流程。
1.进入compileToFunctions函数:执行compileToFunctions这个函数,这个函数首先会验证当前环境是否支持newFunction语法,再利用闭包做了一个编译器缓存,然后执行传入的compile函数。
2.进入compile函数compile函数将平台的配置拿到做了一个赋值,再结合当前传入的options参数,做了一些合并配置的操作,然后会执行传入的baseCompile函数,
3.进入baseCompile函数baseCompile函数是编译的核心函数,这个地方会根据传入的template生成ast树、优化ast树、生成字符串代码,完成编译后,
4.完成baseCompile函数的执行,进入compile函数对编译返回结果compiled对象挂载了errors、tips两个属性,
5.完成compile函数,进入compileToFunctions函数进入compileToFunctions这个函数,检查编译过程有没有错误,再将生成的字符串代码利用newFunction语法,转换成匿名函数。
最终的这个匿名函数就是最终生成的render函数。关于模板编译的结果可以参考这个网址。
到此为止,我们清楚了编译的入口了,下一节我们继续去分析编译的核心流程!
点击去往下一节
原文: with 汉语什么意思
防止字符串被转义。compile要加r,是为了防止字符串被转义,但是re.complie 不会主动去转义。这个r代表了原字符串的意思,比如用户匹配信息item\n 时,如果没有r,要将正则表达式写成re.compile('item\\n');但是,当加上了r时,正则表达式写成re.compile(r'item\n')就可以了。
本人c语言菜鸟,问一下compile和build后的一大堆文件是什么意思
compile这里指搜集资料,计算机用语翻译为"汇编".
本提议涵盖了方法,系统设计和信息备份策略,备份移动/台式电脑/内部服务器的系统环境.
(因为搜集信息作为环境参数备份,很明显,翻译出来反而怪怪的,就省略了)
在做java开发时,build和compile有什么联系和区别?谢谢。
compile是编译,build是构建。你编写的C程序是不能直接运行的,要先转换成电脑能直接运行的程序,这个过程就是compile和build。compile会把源程序编译成后缀名为.obj的目标文件,这个文件还要经过build变成可执行程序exe。这个exe文件就是可以运行的程序了。
build会构建整个工程, compile只会编译工程,build包含compile, 是将源码解释后形成可执行文件。
命令行下的javac就是compile
java则是build。
在实际开发的时候这两个没太大区别, 只有部署的时候才会用到build。