1.sourcemap的源码用途认知与运用
2.10分钟快速精通rollup.js——Vue.js源码打包原理深度分析
3.FPGA高端项目:FPGA实现SDI视频编解码工程解决方案,提供3套工程源码和技术支持
sourcemap的输出认知与运用
在讨论sourcemap之前,我们首先需要了解编程语言的源码用途编译过程。
编译是输出将编程语言转换为可执行代码的过程。然而,源码用途可执行代码和源代码是输出网页设计 源码完全不同的两种格式。如果在执行过程中出现错误,源码用途很难定位源代码编写过程中出现的输出问题。因此,源码用途现代编译器基本上都支持一种标准的输出可执行代码与源代码之间的映射,以特定格式将这种映射关系持久化存储到文件中。源码用途当程序执行出现问题时,输出根据堆栈信息使用映射文件逆向还原到源代码,源码用途可以清晰地、输出语义化地查找编写过程中的源码用途错误。
在常见的C Family languages中,这种可执行代码和源码之间映射的格式已经是一种标准化的东西了,称为DWARF。尽管在每个厂商应用的平台上产生的文件格式不尽相同,但它们内里遵循的映射格式都遵循了DWARF调试标准。
回到Web前端领域讨论这个问题,类似地,我们有sourcemap这个东西。或者我们应该称它为sourcemap调试格式标准。因为目前我们对sourcemap的格式都遵循了一定的标准,但在它的用途上,却出现了千差万别。
本文中讨论sourcemap的格式组成是没有意义的,sourcemap的格式应当是一种持续发展的标准,每当标准更新,自然会有健壮的工具帮助解读。理解sourcemap的格式对它的应用不会有太明显的帮助。
按照我的etcd 源码解析理解,最早sourcemap是为了协助JavaScript代码混淆(或者压缩)而产生的。框架的作者为了缩小代码体积、避免生产环境的JavaScript代码能被轻松地阅读,使用压缩、混淆工具对源码进行了处理。如果产生了问题,有sourcemap还能轻松地还原代码。但当时的sourcemap并不是web标准之一,这为今日的web前端工程化体系埋下了隐患。
在上一节中提到,sourcemap是一种“可执行代码”和源码之间的映射关系,那么只要是产生编译的地方,就应该会有sourcemap产生。
首先想到了Babel这个工具,它是应用最广泛的JavaScript编译器,接下来我们尝试一个示例:
接着,我们安装babel,指定sourcemap参数为inline,并对其进行转换,得到:
可以看到,转换后的代码和源码产生了很大的区别,并且sourcemap以注释的形式紧跟在可执行代码尾部,它的链接指向了一个data URL。
这么看就很容易了解到,sourcemap是一个基于之前的web标准拓展的功能,它只需要以固定的注释格式跟随在一个脚本文件的末尾即可。那么不同的浏览器厂商想要兼容这个标准,只需要加以识别这个格式即可。
但上文可以看出,data URL加在注释中,任何外部人员都可以轻易获得。因此在做代码转换时,firefox firebug源码可以将sourcemap生成到一个单独的文件中,一般是文件名加.map后缀,那么对应的sourcemap的地址也就变成:
sourcemap的这种设计方法并不是独一份的。例如在C Family Language的构建交付体系中,为了调试方便,对于测试环境交付的库、可执行代码,并不会将它们的"sourcemap"从可执行代码中分离出来。它们的执行环境和大部分JavaScript引擎一样,在调试断点或者Exception时,都能自动地载入"sourcemap"并且给出对应的源码栈信息。而在生产交付时,都会在构建时将"sourcemap"从库和可执行文件中提取出来单独保存。这样既减小了交付的产物体积,还能保证源码信息不被外部人员知晓。
既然sourcemap在逐渐地成为一个标准,那么自然就有配套的标准工具对这种格式进行解析。除了Chrome devtools自带的以外,还可以使用常见的库,接下来我们使用mozilla的source-map库,对刚才的代码进行一些还原的操作。
这是断点调试常见经常会碰到的场景,比如某个exception发生在了我们刚才代码的line 9; column 2; 即console.log的位置。那么我们可以这么做:
通过载入map文件,然后查找line 9 column 2对应的源代码位置可得:
然后我们去index.ts中的3行2列,正好是ts文件中的console.log
可以看到,sourcemap不仅记录了代码行列数,还记录了源文件的位置,那么不用翻sourcemap的manual也能说明,sourcemap也像其他编译系统一样,支持多个文件、库的hiwifi os源码代码映射的集成合并。这对于大型工程的构建十分有用,大型工程往往由数以千计万计的库和代码文件组成,在这种复杂的构建中,我们往往只想要获得有限几个产物。除了可执行代码,sourcemap的统一产出也有利于我们方便地追溯生产环境的问题。
mozilla的source-map标准库不止有查找映射位置的这个作用,更能直接还原代码。我们可以直接载入一个sourcemap文件,然后查看它对应了那些源代码文件,然后根据这些文件进行逐个还原内容:
由于我们只有一个,得到的输出是
在实际开发场景中,我们碰到的sourcemap运用比上面提到的情况复杂得多,但是问题又没有办法一一枚举,所以这里讨论一些常见的例子
前面就见过两种形式:dataURL放在JavaScript文件结尾的、和独立写入文件的。他们的形式是显而易见的,并且特点也能清楚地看出来。前者内联,增大了体积,但是降低了使用的门槛。后者独立,可以隐藏保存起来,非必要时不使用。
但在webpack这种打包构建工具中,对sourcemap做了更多更详细的定义,其基本分类的依据也遵循以下几个维度:
具体的规则可以翻阅webpack对应的文档,光靠脑子记是没办法的。
对库、预编译/转换的sourcemap处理
日常开发中,使用库或者预编译的组件是很常见的事,例如:
预编译文件的ican 源码实现处理
像这些场景对工程的构建提出了比较多的要求。这里就针对常用的webpack做一个处理的展示,还是以前面的工程为例,我们的Typescript库导出了函数a,然后我们直接引用dist/index.js(而非src/index.ts)
然后我们通过webpack打包并且导出它的sourcemap
最后我们得到了./dist/demo.dist.js.map(名字有点诡异哈)
然后我们再通过刚才写的sourcemap工具进行还原看看:
可以看到,webpack默认情况下可以识别预编译的文件它的sourcemap,并且进行合理的目录转换,保证指向正确
那么我们如果删除预编译文件的sourcemap呢?我对a函数的库重新编译了一遍,并且不导出任何sourcemap,结果对引入的a函数库的文件还原就变成了
库的处理
如果a函数是从npm库引用的呢?我尝试了下把函数a放到了库中,然后将源码引用改成了
结果虽然node_modules中带了sourcemap,但是还原后并不是原本的ts代码
这时候需要对webpack进行配置,增加source-map-loader作为预处理,且不能排除node_modules目录:
然后再进行打包编译出来的map我们对其进行还原发现:
webpack成功帮我们提取了node_modules库中的sourcemap
本文主要阐述了sourcemap的基本知识,包含了几个方面:
分钟快速精通rollup.js——Vue.js源码打包原理深度分析
Vue.js源码打包基于rollup.js的API,流程大致可分为五步。首先将Vue.js源码clone到本地,安装依赖,然后通过build指令进行打包。打包成功后会在dist目录下创建打包文件。Vue.js还提供了另外两种打包方式:“build:ssr"和"build:weex”。
Vue.js打包源码分析,Vue.js源码打包基于rollup.js的API,流程大致可分为五步,如下图所示:执行npm run build时,会从scripts/build.js开始执行。前5行分别导入了5个模块,这5个模块的用途在前置学习教程中已经详细过。第7行通过同步方法判断dist目录是否存在,如果不存在则通过同步方法创建dist目录。生成rollup配置,生成dist目录后,通过以下代码生成了rollup的配置文件。代码虽然只有短短一句,但是做了很多事情。首先它加载了scripts/config.js模块,然后调用其中的getAllBuilds()方法。接下来导入了scripts/alias.js模块,alias.js模块输出了一个对象,这个对象中定义了所有的别名及其对应的绝对路径。这个模块中定义了resolve()方法,用于生成绝对路径。
Vue.js打包流程分析,Vue.js源码打包基于rollup.js的API,流程大致可分为五步,如下图所示:执行npm run build时,会从scripts/build.js开始执行。前5行分别导入了5个模块,这5个模块的用途在前置学习教程中已经详细过。第7行通过同步方法判断dist目录是否存在,如果不存在则通过同步方法创建dist目录。生成rollup配置,生成dist目录后,通过以下代码生成了rollup的配置文件。代码虽然只有短短一句,但是做了很多事情。首先它加载了scripts/config.js模块,然后调用其中的getAllBuilds()方法。接下来导入了scripts/alias.js模块,alias.js模块输出了一个对象,这个对象中定义了所有的别名及其对应的绝对路径。这个模块中定义了resolve()方法,用于生成绝对路径。
Vue.js打包流程分析,Vue.js源码打包基于rollup.js的API,流程大致可分为五步,如下图所示:执行npm run build时,会从scripts/build.js开始执行。前5行分别导入了5个模块,这5个模块的用途在前置学习教程中已经详细过。第7行通过同步方法判断dist目录是否存在,如果不存在则通过同步方法创建dist目录。生成rollup配置,生成dist目录后,通过以下代码生成了rollup的配置文件。代码虽然只有短短一句,但是做了很多事情。首先它加载了scripts/config.js模块,然后调用其中的getAllBuilds()方法。接下来导入了scripts/alias.js模块,alias.js模块输出了一个对象,这个对象中定义了所有的别名及其对应的绝对路径。这个模块中定义了resolve()方法,用于生成绝对路径。
Vue.js打包流程分析,Vue.js源码打包基于rollup.js的API,流程大致可分为五步,如下图所示:执行npm run build时,会从scripts/build.js开始执行。前5行分别导入了5个模块,这5个模块的用途在前置学习教程中已经详细过。第7行通过同步方法判断dist目录是否存在,如果不存在则通过同步方法创建dist目录。生成rollup配置,生成dist目录后,通过以下代码生成了rollup的配置文件。代码虽然只有短短一句,但是做了很多事情。首先它加载了scripts/config.js模块,然后调用其中的getAllBuilds()方法。接下来导入了scripts/alias.js模块,alias.js模块输出了一个对象,这个对象中定义了所有的别名及其对应的绝对路径。这个模块中定义了resolve()方法,用于生成绝对路径。
Vue.js打包流程分析,Vue.js源码打包基于rollup.js的API,流程大致可分为五步,如下图所示:执行npm run build时,会从scripts/build.js开始执行。前5行分别导入了5个模块,这5个模块的用途在前置学习教程中已经详细过。第7行通过同步方法判断dist目录是否存在,如果不存在则通过同步方法创建dist目录。生成rollup配置,生成dist目录后,通过以下代码生成了rollup的配置文件。代码虽然只有短短一句,但是做了很多事情。首先它加载了scripts/config.js模块,然后调用其中的getAllBuilds()方法。接下来导入了scripts/alias.js模块,alias.js模块输出了一个对象,这个对象中定义了所有的别名及其对应的绝对路径。这个模块中定义了resolve()方法,用于生成绝对路径。
Vue.js打包流程分析,Vue.js源码打包基于rollup.js的API,流程大致可分为五步,如下图所示:执行npm run build时,会从scripts/build.js开始执行。前5行分别导入了5个模块,这5个模块的用途在前置学习教程中已经详细过。第7行通过同步方法判断dist目录是否存在,如果不存在则通过同步方法创建dist目录。生成rollup配置,生成dist目录后,通过以下代码生成了rollup的配置文件。代码虽然只有短短一句,但是做了很多事情。首先它加载了scripts/config.js模块,然后调用其中的getAllBuilds()方法。接下来导入了scripts/alias.js模块,alias.js模块输出了一个对象,这个对象中定义了所有的别名及其对应的绝对路径。这个模块中定义了resolve()方法,用于生成绝对路径。
FPGA高端项目:FPGA实现SDI视频编解码工程解决方案,提供3套工程源码和技术支持
FPGA高端项目:实现SDI视频编解码,提供3套工程源码与技术支持 本文详细阐述了如何使用Xilinx Kintex7-T FPGA开发板进行SDI视频编解码,设计过程涵盖了从输入高清SDI信号,通过GTX解串、SMPTE SDI解码,到最终输出HDMI或SDI视频的全过程。三种不同的工程源码分别对应不同的输出模式:HDMI输出(工程1)、HD-SDI模式(工程2)和3G-SDI模式(工程3),以适应不同的项目需求。工程1:适用于SDI转HDMI,分辨率为x@Hz,适合于需要高清输出的项目。
工程2:针对SDI转SDI,分辨率为x@Hz,适合于需要直接SDI传输的项目,但需注意x@Hz对显示器有一定要求。
工程3:适用于SDI转3G-SDI,同样支持x@Hz,适用于需要高带宽传输的场景。
设计中,使用了FPGA的GTP/GTX资源进行解串,SMPTE SDI IP核进行编码,配合BT转RGB模块转换视频格式,以及图像缓存和Gv驱动器等模块,确保视频处理的稳定性和兼容性。此外,还提供了完整的工程源码和设计文档,以及针对FPGA编解码SDI视频的培训计划,以帮助学生、研究生和在职工程师快速上手和开发相关项目。 要获取这些资源,请查看文章末尾的获取方式。注意,所有代码仅供学习研究,商业用途需谨慎,且部分代码基于公开资源,如有版权问题,请通过私信沟通。