7.1 编译原理与多端输出


7.1 编译原理与多端输出

本节导读:交付段从原理开始。本节打开罗盘的表盖:一段 Vue 源码如何被编译器拆成模板、逻辑、样式三条转译线,条件编译在哪个阶段介入裁决,manifest 的平台配置如何参与,最后交代自定义构建配置的扩展点。看懂这一节,此前六章的所有约定都会在产物里找到落点。

一段源码的三条转译线

编译器拿到工程后,按文件类型走三条不同的转译线。模板线:template 里的 uni 标签被逐个映射成目标端组件——view 在微信端落成 view 标签、在 H5 端落成带样式约束的元素,事件绑定 @tap 翻成 bindtap 或 DOM 监听(2.2 节的翻译链就是这条线的产物)。逻辑线:script 部分被打包器处理,uni API 的调用被注入各端实现(微信端桥接 wx 对象、H5 端走自实现层、App 端桥接 plus),生命周期由框架运行时对齐。样式线:rpx 在编译或运行期换算,nvue 页面的样式被校验进原生排版引擎的子集。三条线合流的产出按端落盘:微信端是 wxml、wxss、js 与 json 的组合,H5 端是带路由的静态资源,App 端是打包进原生工程的 js 与资源。

条件编译在哪一步介入

回答这个问题只需一个观察:产物里根本不存在被排除端的代码——#ifdef MP-WEIXIN 圈住的块在 H5 产物里连字节都没有。这说明条件编译是编译期的文本级裁剪,发生在转译与打包之前:预处理先按目标平台把源码裁剪成"该端版本",再交给后续管线。两个推论值得记住。其一,条件编译的开销为零——产物里没有那行代码,运行期不存在任何判断;其二,被裁剪分支里的语法错误不会被当前端编译发现(那段文本已被删掉),所以适配层公约里"矩阵编译"(每个端的产物都编译一遍)不是洁癖,是唯一的语法兜底。

manifest.json 的平台配置在裁剪之外参与第二轮裁决:App 端的模块声明(支付、推送、蓝牙)决定原生层打包哪些能力,H5 端的 router 配置决定路由模式与资源路径,各小程序端的 appid 与专属字段决定上传配置。一份配置里"哪些字段属于哪端"由平台的配置规范约定,条件编译块可以在其中进一步细分(比如 Android 与 iOS 各自的模块开关)。

从源码到产物:以微信端为例的完整链路

把链路串起来走一遍。商城工程执行微信端构建后,产物目录大约长这样:

dist/build/mp-weixin/ ├── app.js / app.json / app.wxss # 应用壳:App.vue 与全局配置的转译产物 ├── pages/ │ ├── index/ # 每个页面一组四件 │ │ ├── index.wxml # 模板线:uni 标签已映射、指令已翻写 │ │ ├── index.js # 逻辑线:页面注册与运行时注入 │ │ ├── index.json # 页面级窗口配置 │ │ └── index.wxss # 样式线:rpx 保留待运行期换算 │ └── ... ├── pagesOrder/ # 分包:独立成组,按需下载 └── common/ # 公共 chunk:vendor 与运行时

对着目录就能解释此前的约定:pages.json 没登记的页面不在这棵树里;static 的平台子目录只出现在对应端产物;分包目录独立成组;uni.scss 的变量已经展开进每个 wxss。读产物是排查"书写层看不出的问题"的最后手段——模板行为诡异时打开对应 wxml 看一眼翻成了什么,比反复试错快得多。

自定义构建配置:两个扩展点

标准管线覆盖九成需求,剩下的一成靠扩展点。H5 与 App-vue 端支持自定义工程配置:环境变量注入(按 VUE_APP_ 前缀约定)、构建产物目录与资源前缀调整、按环境的插件开关。小程序端的定制空间较小,主要靠 manifest 的各端配置与构建前脚本(在 package.json 的脚本里串预处理命令)实现。一个实用的组合技是"环境加平台"二维构建:CI 里按参数组合跑不同构建命令,测试与生产用不同域名常量,产物互不污染。

// package.json 脚本节选:环境与平台的二维组合 { "scripts": { "dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vite", "build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vite build", "build:mp": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vite build" } }

⚠️ 自定义配置最容易翻车的位置是"产物路径":改了输出目录却忘了同步微信开发者工具里导入的路径,工具吃的是旧产物,你怎么改源码它都不动——"改了没生效"类问题的又一惯犯。

产物体积从哪来:一份来源分析

理解了产物结构,就能做体积归因。以微信端为例,产物体积的四大来源按常见占比排:公共 vendor(第三方依赖与运行时)、页面代码(模板加逻辑的转译产物)、static 静态资源、各页面的配置与样式。归因方法就是打开产物目录逐层看大小,再对照源码定位"谁把它带进来的"——vendor 大多数时候是体积第一主角,一个图表库或/moment 类工具就能占去几百 KB。治理优先级跟着归因走:vendor 换轻量替代或按需引入,static 大图迁网络(1.5 节的公约),页面代码做分包。把"先归因再动手"变成体积治理的条件反射,能省掉大量方向错误的优化。

编译期与运行期的分工清单

把全册反复出现的"编译期还是运行期"问题收成一张清单,作为本册原理部分的备忘。编译期发生的事:条件编译裁剪、模板转译、rpx 之外的样式预处理、pages 与 manifest 的解析、静态资源的拷贝与归并——产物定型,改配置要重新构建。运行期发生的事:rpx 换算、uni API 桥接、页面栈管理、生命周期派发、数据通信——行为发生,排查要看运行日志与调试器。清单的用法:遇到任何"不生效",先判断它属于哪一期,编译期问题查配置与产物,运行期问题查日志与断点,方向对了再动手,效率差一个量级。

本节要点回顾

  • 三条转译线:模板映射端组件、逻辑注入端实现、样式按端处理,合流产出各端专属产物;
  • 条件编译是编译期文本裁剪,产物零残留零开销,被裁分支的错误要靠矩阵编译兜底;
  • manifest 平台配置参与第二轮裁决:原生模块、路由模式、各端专属字段;
  • 读产物是排查怪问题的最后手段,目录结构与此前六章的约定一一对应;
  • 自定义构建走环境变量与脚本组合,产物路径改动记得同步工具侧。

原理在手,下一节走完四条交付线:各端构建、混淆签名、上架审核的完整流程。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U