架构总览
本节把 1972 行手写 IIFE 的
bundle.js「拆开看」,覆盖五层架构(helper / template / sub-component / main / export)、三对外组件的组件树、双通道数据流,以及与 metric_card 的架构代差对比。
IIFE 顶层结构
ne101_camera 的 bundle.js 第一行不是 import,而是一句对 window 的契约声明。查看源码:
// bundle.js L1-L5
var NE101CameraPanel = (function () {
var React = window.React;
var jsx = window.jsxRuntime.jsx;
var jsxs = window.jsxRuntime.jsxs;
Source: bundle.js L1-L5
这三行 var React = window.React + var jsx = window.jsxRuntime.jsx + var jsxs = window.jsxRuntime.jsxs 是 NeoMind 组件市场的「注入三连」,也是与 metric_card(6 metric_card 3.2)共享的底层约定。
它意味着 bundle 不打包 React,而是从宿主页面已经加载好的单例里「借」一份 React,从而保证全仪表板只有一个 React 实例,hooks 不会跨实例失效(useContext 返回 undefined、useRef 报错这类经典症状)。
为什么用 var Name = (function(){ ... })() 这种 IIFE 形式而不是 UMD / CommonJS / ESM?根本原因是 Dashboard 宿主通过 <script> 标签注入 bundle。<script> 标签没有模块作用域,IIFE 是唯一能用「函数作用域 + 闭包」模拟私有命名空间的零依赖手段:函数体内的 function classColor / var white 等等不会泄漏到 window 上,只有最后那一句 return { ... } 的对象挂到 window.NE101CameraPanel。
UMD 虽然也能跑在 <script> 下,但它多了一层 define / module.exports 的探测分支,对「不跑打包器」的 NeoMind 范式是冗余的;CommonJS 的 require 在浏览器里根本不工作。
最后一行 bundle.js L1971 是命名导出 + default 双暴露:
// bundle.js L1971
return { default: NE101CameraPanel, NE101CameraPanel: NE101CameraPanel, ConfigPanel: ConfigPanel, AdvancedPanel: AdvancedPanel };