一早打开 uni-app 项目准备在真机上验证刚接入的原生插件结果控制台第一行就是红得刺眼的提示[JS Framework] 当前运行的基座不包含原生插件[xxxx]请在manifest中配置该插件重新制作包括该原生插件的自定义运行基座。第一次遇到的人多半会懵我明明在项目里加了插件代码也引了为什么还说不包含其实这句话已经把答案说了一半——问题不出在源码而出在“基座”。今天我把这行报错拆开从运行机制、manifest 配置、自定义基座制作到“重做完还报错”的排查链路完整走一遍这些都是我实际项目中踩过、验证过的东西希望能帮你少绕几圈。1. 先看懂这行报错它到底在说什么1.1 标准基座和自定义基座差了哪些东西uni-app 的 App 端运行环境分两层上面是 JavaScript 逻辑下面是原生能力层。原生插件不是普通 npm 包它本质是一段编译进 App 壳子里的原生代码JS 层通过固定的模块名去调用。而这个“壳子”就是我们常说的“基座”。HBuilderX 自带的基座叫“标准基座”它能满足大部分普通页面的开发和调试比如路由、网络、基础 UI 组件。但它只有一个固定组合的原生能力集合不包含任何第三方原生插件。一旦你开始使用原生插件就必须用“自定义基座”——也就是把当前项目 manifest 里登记过的插件一起编译打包出一个新的 App 壳子。打个比方标准基座是精装交付的样板间床、桌、椅子都有原生插件是你额外订购的智能马桶和洗碗机。样板间已经交付你再怎么搬家电也塞不进墙里必须提前跟开发商说好在施工阶段就把管线预埋进去。这个“预埋”动作就是制作自定义基座。这行报错就是 JS 框架在启动时检查基座里的原生模块清单发现你要调用的插件 ID 不在清单里于是直接把问题甩到你脸上。它不是提示你代码写错了而是告诉你你现在跑的这套壳子根本没把这个原生插件编译进去。1.2 报错里的 [xxxx] 是什么去哪查报错里的[xxxx]不会被 JS 框架翻译成人话它输出的是插件 ID。不同插件市场、不同来源的插件ID 命名规则不一样有的像video-player有的是一串包名。你不需要背下来但必须知道它在哪里能找到。如果你用的是可视化配置打开项目根目录的manifest.json切到“App 原生插件配置”页面添加过的插件会以列表展示每一行都有插件 ID。如果你用的是本地插件去项目里的nativeplugins/插件目录/package.json里找id字段。云端插件一般在你插件市场的账号中心或已购列表里也能看到。通常报错里给出[xxxx]就说明运行基座在找这个 ID。你重点要做的不是改代码而是确认这个 ID 是否已经出现在 manifest 的插件配置中。如果项目同时用了多个原生插件JS 框架往往会在第一个缺失的插件处停下来报错所以只解决“当前报错的那个”还不够最好把 manifest 里的插件清单整体过一遍。还有一个容易忽略的点原生插件的检测分“启动时检测”和“调用时检测”。有的插件在 App 启动初始化阶段就会注册所以一打开 App 就报错有的插件是懒加载等 JS 真正调用它时才报错。这也是为什么有些人“没跑任何插件相关代码”也会被这条报错拦截——插件在启动阶段已经尝试初始化了。2. manifest.json 里的插件登记表才是源头2.1 可视化配置入口和最终生成的 JSON 节点原生插件能不能进基座第一步就是看 manifest 里有没有它。HBuilderX 的 manifest 页面是一个可视化编辑器左侧有 App 相关配置入口。不同版本菜单位置稍有差异但通常都在“App 原生插件配置”或“原生插件”这一栏。操作路径我按实际项目里的做法整理成四步打开项目根目录的manifest.json进入可视化编辑页找到“App 原生插件配置”点击“添加”如果是项目nativeplugins目录下的本地插件选“本地插件”如果是从插件市场买的选“云端插件”并确认已登录有授权的账号保存HBuilderX 会自动生成对应的app-plus.nativePlugins节点。最终生成的 JSON 大概长这样{ app-plus: { nativePlugins: { xxxx-plugin-id: { __plugin_info__: { name: xxxx插件, version: 1.0.0 } } } } }注意不同 HBuilderX 版本生成的字段细节可能不一样你不需要死记这个结构。重要的是你能在 JSON 里看到nativePlugins节点下存在报错里的那个插件 ID。如果它不在这里后面一切重做基座的动作都没有意义。2.2 云端插件与本地插件在配置上的区别本地插件有一个天然优势它的原生代码文件就在项目nativeplugins目录里不依赖网络制作基座的时候 IDE 直接读取本地文件打包速度快也容易确认是否被包含。云端插件则不一样。你在插件市场添加后项目里可能只有一个引用记录真正的插件内容要在制作基座或云打包时通过网络下载。这就意味着三件事第一制作基座时电脑必须联网第二登录的账号必须是拥有该插件权限的账号第三插件授权通常和某个 AppID 绑定如果你的项目 AppID 不是授权时用的那个云端构建时很可能会跳过这个插件。我见过一个很典型的例子某开发者用测试项目 A 的 AppID 购买的插件授权后来换了一个新项目 B直接把插件拖进 B 的 manifest制作基座时日志显示“插件处理失败”运行时报错。查了一圈才发现 B 项目的 AppID 根本不在授权名单里。所以在排查报错之前先确认项目 AppID、插件授权、登录账号这三者是不是同一套体系。2.3 少配、配错、没保存最常见的三种配置问题第一种是“配错了入口”。原生插件需要的是app-plus.nativePlugins配置而不是“App 模块配置”。后者只是给官方内置模块开权限比如定位、推送、蓝牙。很多第三方插件文档里会同时要求你勾选某些内置模块这是对的但如果你只勾了模块权限、没在原生插件列表里添加插件基座照样不会包含它。这一点最容易让人误以为“我已经配置过了”。第二种是“配了但从来没保存”。可视化编辑页如果忘记点保存就直接去跑手机HBuilderX 编译时读到的还是旧 manifest报错当然照旧。听起来很蠢但在多人协作、频繁切换分支的场景下经常发生尤其是从 git 拉代码后没有重新加载 manifest 的时候。第三种是“插件是后面才加的”。你已经有一个旧的自定义基座后来又往 manifest 里加了一个新插件但没有重新制作基座。基座是个静态的包不是运行时能热插拔的。你代码里引了插件JS 框架去基座里找找不到于是报错。这种属于“配置和基座版本不同步”下面第三节专门讲怎么重做。3. 重制自定义运行基座的完整流程与细节3.1 Android连真机走 HBuilderX 生成自定义基座先把手机连上电脑打开 USB 调试然后用真实设备做验证。模拟器不是不行但很多原生插件不支持模拟器的 x86 架构或者只在真机上才有完整功能所以我一般建议调试原生插件时直接用真机。接下里在 HBuilderX 里点“运行”-“运行到手机或模拟器”下方会有一个“制作自定义调试基座”的入口部分版本显示为“制作自定义运行基座”。点击后HBuilderX 会读取当前项目的 manifest 插件配置把本地插件和云端插件一起纳入打包计划。如果你用的是云端插件此时会触发下载和编译日志里应该能看到“处理原生插件 xxx 成功”一类的输出。等基座打包完成后HBuilderX 一般会提示安装到已连接设备。如果没有自动装你手动装一次。然后再次点“运行到手机或模拟器”这时候运行目标旁边会有一个基座类型的选择务必切换到“自定义基座”。注意不是“重新运行标准基座”那会让你重新踩一遍最初的报错。这里有个关键细节Android 基座制作完成后如果你项目里的包名、签名和之前装过的旧基座不一致安装时可能会因为签名冲突失败。遇到这种情况先把设备上旧的基座 App 卸载再装新的不要试图覆盖安装。3.2 iOS证书、描述文件与基座重制iOS 的自定义基座流程和 Android 差别比较大。制作 iOS 自定义基座一般需要在 macOS 环境上操作并且必须提前准备好开发证书和描述文件。没有这两个东西Feva 云打包阶段就会直接失败。在“制作自定义调试基座”流程里HBuilderX 会让你选择证书然后它会生成一个.ipa格式的基座包。真机调试之前记得在系统设置里信任对应的开发者证书否则 App 会提示无法打开。这一点容易被忽略尤其是刚接手别人项目的测试机。iOS 的基座做好之后运行选项同样要切换到“自定义基座”。因为 iOS 的系统限制原生插件必须编译进安装包不可能运行时动态加载所以“重新制作”这一步是绕不开的。不要觉得 iOS 和 Android 共用一个基座制作入口就可以偷懒。实际上你必须在目标平台上各自制作各自的基座。你只制作了 Android 自定义基座然后用它去跑 iOS 报错JS 框架会给出同样的“基座不包含原生插件”提示。这个问题在跨平台项目里尤其容易踩。3.3 制作完成后的安装与切换操作基座制作完成只是第一步真正让人崩溃的是“做完了还是报错”。这时候先检查运行配置。HBuilderX 的“运行”菜单里同样一个设备可以分别跑“标准基座”和“自定义基座”。如果你之前选过标准基座工具会记住你的选择下次运行可能还是标准基座。所以正确做法是在运行窗口或工具栏的运行目标下拉框里手动确认当前使用的是“自定义基座”。有些版本里折叠在“设置”或“更多选项”里不要嫌麻烦翻一下。另外一个容易被忽略的点设备上安装的基座是不是最新的因为 HBuilderX 有时不会自动卸载旧版基座你看到手机上有个 App就以为运行的是新基座实际上那个包是三天前打的里面没有刚加的插件。最稳妥的判断方法卸载旧基座重新安装新打出来的基座包再跑一次。这比在任何日志里找答案都干脆。提示自定义基座本质上是一个带有调试能力的 App 壳子。它可以用于开发验证但不要把它当作正式包发给用户。后面要发版时走正式的“原生 App 云打包”或离线打包。4. 基座已经重制为什么还是会报同一个错4.1 常见翻车插件配置在 A 工程跑的是 B 工程这是我排查过最能折腾的一种情况。开发者有多个 uni-app 工程误以为插件已经“加到 IDE 里”了于是打开项目 B 去运行结果报错。一看 manifest插件根本没配在 B 里。原生插件是跟着项目走的不是跟着 HBuilderX 全局走的。你的插件配置、nativeplugins 目录、AppID 授权全部围绕某一个具体项目。排查报错时先确认你当前打开的运行项目和你配置插件的项目是同一个。这种低级问题在窗口标签开多了之后特别容易发生。还有一种是“同一个项目但多人协作后插件配置被覆盖”。某队友从旧分支拉代码他那份 manifest 里根本没有新插件制作基座时自然也不会包含。这种情况下让全队统一支付最新主干代码再重新制作基座。不要指望 git 合并能自动帮你把插件配置合进去。4.2 缓存、旧基座、AppID 不一致重做了基座、也确认运行选项没问题依然报错那就要考虑缓存和版本上下文。先处理工程缓存。uni-app 项目的编译产物在unpackage/dist目录里某些原生插件相关的内置资源如果缓存不正确运行时可能沿用旧的配置文件。我之前遇到过一次manifest 里已经删掉一个旧插件但运行报错却在抱怨一个已经不存在的插件 ID。后来把 HBuilderX 的编译缓存清理了一遍重新编译就好了。“清理缓存”这种老土操作在处理基座类问题时意外地有效。然后看 AppID。uni-app 项目的 AppID 不只是文档里的一个标识它和原生插件的授权、云端打包配置绑定。如果你换了 AppID插件权限失效是轻的基座构建流程里插件被静默跳过都有可能。排查时打开 manifest 可视化页面把项目 AppID 和插件市场账号后台看到的授权 AppID 对照一下不一致就解释了很多奇怪现象。最后是旧基座残留。Android 上如果设备里存在一个同包名的老基座而它和你新基座的签名不一样系统会拒绝安装新包。很多开发者看到“安装失败”就把手机一拔换哪台设备再跑结果每台设备都装的是旧基座。先卸载再安装是解决这个残留问题的唯一稳定办法。4.3 排查优先级与验证清单如果你现在正被这条报错卡住按下面的顺序排查不要东翻西找确认报错里的插件 ID在 manifest 的app-plus.nativePlugins节点里存在确认这个插件是在制作基座之前配置的不是基座打好之后才加的确认当前运行选项用的是“自定义基座”不是“标准基座”确认设备上安装的是最新打出的基座包必要时卸载重装查看制作基座时的日志搜“插件”“failed”“error”这些关键词看有没有插件被跳过或处理失败确认项目 AppID、插件授权账号、打包证书三者在同一个业务体系下如果还是不行清理 HBuilderX 编译缓存重新编译并重做基座再试。下面这个表是我在多个项目里总结出的快速对照适用于大多数情况现象最可能的原因先检查什么没配插件直接报错manifest 中缺少 nativePlugins 配置可视化配置页是否有该插件配了插件运行还报错用的是标准基座或基座是旧包运行选项和手机上的安装时间基座制作日志没有插件云端插件授权失败 / 本地插件目录缺失登录账号、AppID、nativeplugins 目录重做基座后仍然报错HBuilderX 缓存 / 签名冲突 / 插件依赖缺失清理缓存、卸载旧基座、看插件文档模拟器报错、真机正常插件不支持模拟器架构换真机调试5. 从调试到发布正式包、离线打包与团队协作5.1 云打包与自定义基座之间的关系很多人以为自定义基座做出来以后直接拿这个包去发布上架反正功能都验证过了。这是不行的。自定义基座默认带调试能力和测试配置正式发布必须走“发行”里的“原生 App 云打包”。云打包也会读取 manifest 里的插件配置但它会按正式环境的要求重新生成包你需要配置 App 图标、启动图、权限声明、证书签名等。插件内容同样会被编译进去但和你开发时用的调试基座是两套构建链路。所以流程上要记住一句话调试用自定义基座发布用正式打包两者从不是一回事。如果你在发布前改了 manifest 里的插件列表记得重新走一遍正式打包不要拿上次发布的一个月前的包去推。5.2 离线打包时原生插件的接入点有些团队不用云打包而是用 uni-app 官方 SDK 在 Android Studio 或 Xcode 里做离线打包。这种模式下原生插件的接入点完全不同。以 Android 为例你需要把插件提供的 AAR 或 SDK 放到原生工程里并在应用的dcloud_uniplugins.json文件中注册插件信息。这一步做完后再编译 Android 工程生成的 APK 才是包含该插件的正式壳子。如果你在原生工程里漏了注册uni-app 的 JS 层一样会在运行时告诉你“基座不包含原生插件”。离线打包的问题在于它绕过了 HBuilderX 的自动化配置所有环节都要手动处理对团队成员的原生开发能力要求更高。如果你走的是这条路线就不要回头纠结 HBuilderX 的可视化页面了所有问题都集中在原生工程和插件注册文件里。5.3 多人协作时基座和插件的同步管理团队开发里基座是一个经常被忽略的“共享资产”。我见过不少项目一开始某个人本地做了一个自定义基座然后整个团队都拿这个包来联调。前期没问题但一旦某个人改了 manifest加了新插件其他人的基座就集体过期报错铺天盖地。建议在项目里维护一个简单的说明文档记录三件事HBuilderX 版本号、最近一次基座制作时间、当前 manifest 里启用的插件列表。新成员加入时先按文档制作一份基座再开始联调。不要直接从一个同事手里拷贝基座包因为你不知道他的项目配置和你是否是同一套。另外云端插件的授权是跟账号走的。团队里如果只有一个人付费购买了插件那么只有他能成功制作包含该插件的基座。其他成员即使代码拉了下来制作基座时也会因为没有权限而失败。要么统一用一个公共账号要么公司层面统一购买授权不要在这个问题上省事。5.4 我的几点实测经验与避坑总结文章最后分享几条我自己的实操体会。第一把“改 manifest - 重做基座 - 跑自定义基座”固化成肌肉记忆。大部分报错不是因为你不会配置而是因为配置和基座的时间线错位。先改配置再打基座最后运行顺序乱一步都会看到同样报错。第二升级 HBuilderX 之后不要偷懒直接接着用旧基座。HBuilderX 版本更新后编译产物和基座运行框架可能不完全兼容最稳妥的做法是先清理缓存、重新制作自定义基座。我因为省这几分钟曾经在某个版本升级后排查了一下午。第三支付、登录、定位这类 SDK往往对包名和签名有强绑定。制作自定义基座之前先把项目 manifest 里的 Android 包名、iOS Bundle ID 和真正的签名配置成最终上架的版本否则你调试功能都正常但真正发版后回调不触发到时候很难定位。最后再说一个我自己的踩坑案例有次我连续重做了三次基座每次都显示成功但运行时还是报“不包含原生插件”。后来才发现插件文档要求同时配套引入另一个底层依赖插件我只配了业务插件漏了依赖。插件文档里的“依赖插件”一栏很多时候比插件主功能更值得先看。如果你也排到山穷水尽去翻一下插件依赖和版本兼容性答案往往就在那里。