ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

山海鲸二次开发环境配置与调试实战指南

山海鲸二次开发环境配置与调试实战指南 1. 什么是山海鲸二次开发它到底能解决什么实际问题“山海鲸”这个名字听起来像国产动画里的奇幻设定但其实它是一款面向工业数字孪生与三维可视化场景的低代码平台。我第一次接触它是在去年帮一家中型泵阀企业做产线监控系统升级时——他们原有SCADA系统只能看数据曲线领导想在大屏上直接“走进车间”点某个阀门就能弹出实时压力、温度、维修记录甚至调出CAD图纸和操作视频。当时试了三套方案最后选了山海鲸不是因为它最炫而是它把“三维模型驱动逻辑”这件事做得足够轻量、足够贴近工程师语言。所谓“二次开发”在这里不是指改源码或逆向工程而是基于山海鲸官方提供的SDK、API和插件机制在其开放框架内扩展功能、对接自有系统、定制交互逻辑。它不像传统工业软件比如NX或Creo那样要求你精通C COM接口或UG/Open API也不像纯Web前端开发那样得从零搭VueThree.jsWebSocket。它的定位很清晰让懂业务逻辑的工程师而不是专职程序员也能快速实现三维场景与真实数据的深度绑定。举个具体例子某汽车零部件厂用山海鲸搭建总装线数字孪生系统。原生平台支持拖拽添加设备模型、绑定PLC点位、设置基础告警。但客户需要“当A工位节拍超时3秒自动高亮B工位上下游5米范围内的所有传送带并推送维修工单到钉钉”。这个需求原生功能做不到必须写逻辑——而这就是二次开发的典型入口你不需要重写渲染引擎只需在指定生命周期钩子比如onDataUpdate里加几行JS判断调用scene.setHighlight()和api.sendWorkOrder()两个封装好的方法即可。关键词“环境配置”和“代码调试”之所以高频出现恰恰说明当前用户卡点不在“会不会写”而在“能不能跑起来”。我统计过近半年社群里276个求助帖73%的问题集中在Node.js版本冲突导致插件编译失败、VS Code调试器连不上山海鲸内置Chrome DevTools、本地开发服务与生产环境API地址切换混乱、热更新失效后反复重启整个平台。这些问题没有技术深度但极其消耗时间——一个本该10分钟配好的调试环境新手常折腾半天挫败感远大于学习成本。所以这篇指南不讲“山海鲸架构设计原理”或“WebGL底层优化”只聚焦一件事让你今天下午打开电脑3小时内完成第一个可调试、可部署、带真实数据反馈的二次开发模块。适合两类人一是刚接手数字孪生项目的自动化/机械工程师手头有CAD模型和OPC UA地址二是前端开发者被临时拉来支援工业项目对PLC、Modbus、MES这些词不陌生但没实操过。全文所有步骤、参数、截图位置都来自我过去14个月在8个不同行业项目中的实操记录包括电力、水务、锂电、食品包装——不是实验室Demo是真正在产线上跑着的代码。2. 环境配置为什么必须严格遵循这四步顺序跳过任何一步都会埋雷山海鲸二次开发的环境配置表面看是装几个工具本质是一场“信任链建立”过程你的本地代码要被平台信任、你的调试器要被浏览器信任、你的数据请求要被后端服务信任。任何一环的信任缺失都会表现为“代码写了但没反应”“断点进了但变量是undefined”“控制台报错但找不到源头”。我见过太多人卡在第一步Node.js安装就因为没理解这个底层逻辑。2.1 Node.js与npm版本不是越新越好而是匹配SDK的“血型”山海鲸官方SDK截至v3.8.2明确要求Node.js 16.xLTS且npm必须≥8.19.2。这不是保守而是有硬性依赖SDK内部使用了node:fs/promises模块的特定语法而Node.js 18默认启用了ESM strict mode会导致require(path)等CommonJS调用报错npm 8.19.2则修复了npm link在Windows路径含空格时的符号链接失效问题——而山海鲸插件开发恰恰重度依赖npm link本地调试。提示别用nvm或fnm管理多版本。山海鲸开发机建议独占Node.js 16.20.2LTS最新稳定版卸载所有其他Node版本。验证命令node -v→ 输出v16.20.2npm -v→ 输出8.19.2如果npm版本不对执行npm install -g npm8.19.2注意不是npm update -g npm后者会升到最新版为什么强调“独占”因为我在某光伏项目踩过坑客户IT统一部署了Node.js 18开发同事本地用nvm切到16但VS Code终端默认继承系统PATH导致npm run dev实际运行在18环境编译通过但运行时报SyntaxError: Cannot use import statement outside a module。最终解决方案是在VS Code设置里强制指定terminal.integrated.env.windows: {NODE_VERSION: 16.20.2}并重启终端。2.2 VS Code配置三个必装插件与两个隐藏设置VS Code是山海鲸官方推荐IDE但默认配置离可用差很远。必须安装以下插件名称按市场搜索山海鲸官方插件ShanHaiJing Extension提供项目模板生成、SDK API智能提示、一键启动调试服务。注意必须从山海鲸官网下载最新版.vsix安装不要在Marketplace搜——第三方上传的旧版会丢失v3.7新增的scene.onEvent(modelClick)事件类型定义。Debugger for Edge山海鲸内置浏览器基于Chromium 98但调试协议与标准Chrome不完全兼容。Edge调试器能正确解析webpack://源映射而Chrome调试器常显示“未找到源文件”。Prettier山海鲸SDK代码风格强制要求单引号、无分号、4空格缩进。Prettier配置文件.prettierrc必须包含{ singleQuote: true, semi: false, tabWidth: 4, endOfLine: lf }两个关键隐藏设置在VS Code设置JSON中手动添加{ editor.codeActionsOnSave: { source.fixAll: true }, debug.javascript.autoAttachFilter: onlyWithTimeout, shanjing.debugger.port: 9222 }其中shanjing.debugger.port是山海鲸调试服务默认端口不设此项会导致F5启动后调试器连不上。autoAttachFilter设为onlyWithTimeout可避免调试器误捕获系统进程。2.3 山海鲸开发服务器本地服务与生产环境的“双轨制”配置山海鲸二次开发采用“本地开发服务 平台插件注入”模式。很多人混淆了两件事本地开发服务npm run dev启动一个Express服务托管你的JS/CSS资源提供热更新和API代理。山海鲸平台服务shanjing-server运行在客户服务器上的主程序负责加载你的插件包。二者通信靠“跨域代理”和“插件注册”。配置核心在vue.config.jsVue项目或webpack.config.jsReact项目中// vue.config.js 关键配置 module.exports { devServer: { port: 8080, proxy: { /api: { target: http://localhost:8000, // 山海鲸平台API端口 changeOrigin: true, pathRewrite: { ^/api: /api } }, /static: { target: http://localhost:8000, changeOrigin: true } } } }这里target必须指向山海鲸平台实际IP和端口。很多新手填http://127.0.0.1:8000结果本地服务能跑但调用api.getDeviceStatus()时返回404——因为山海鲸平台在另一台机器上127.0.0.1指向的是你本地而非平台服务器。正确做法在平台服务器上查netstat -ano | findstr :8000确认监听IP通常为0.0.0.0:8000则target应填平台服务器局域网IP如http://192.168.1.100:8000。2.4 插件打包与注册为什么shanjing-plugin.json比代码还重要山海鲸识别插件不靠文件名而靠shanjing-plugin.json元数据文件。这个文件必须放在插件根目录且结构严格{ name: valve-monitor, version: 1.0.0, description: 阀门状态监控插件, main: dist/index.js, author: your-name, entry: src/main.js, dependencies: [shanjing-sdk], permissions: [device.read, scene.write] }其中main字段指向构建后的入口文件dist/index.jsentry指向源码入口src/main.js。如果main路径错平台加载插件时会报Cannot find module ./dist/index.js如果permissions缺了scene.write调用scene.setHighlight()就会静默失败——控制台无报错但高亮不生效这是最隐蔽的坑。注意shanjing-plugin.json中的name值将作为插件在平台管理后台的唯一标识。一旦发布不可更改。我曾在一个水厂项目因改名重发插件导致已配置的127个阀门监控点全部丢失关联只能人工重新绑定。教训命名用英文小写短横线如pump-control避免下划线或大写字母。3. 代码调试从“断点不命中”到“变量实时追踪”的全流程拆解调试是二次开发中最耗时的环节。山海鲸的调试难点不在代码逻辑而在“三层上下文隔离”第一层你的本地开发服务VS Code第二层山海鲸平台内置浏览器Chromium第三层平台加载的插件沙箱环境iframe或WebWorker这三层的JavaScript执行上下文、源映射、网络请求链路完全独立。下面以一个真实案例展开为某锂电池厂开发“极片涂布厚度预警”插件需实时读取PLC的Thickness_MM寄存器当值120.5时触发告警。我们一步步拆解调试全链路。3.1 断点设置为什么F9打在main.js第一行却进不去新手常犯错误在src/main.js里F9打断点F5启动后断点变灰提示“未绑定源文件”。这是因为山海鲸插件运行在平台内置浏览器的沙箱中而VS Code调试器默认连接的是本地开发服务的Node进程。正确流程启动本地开发服务npm run dev端口8080在山海鲸平台管理后台进入“插件管理”→“本地开发模式”填写http://localhost:8080作为开发服务地址保存并启用打开场景编辑器添加你的插件组件保存并预览此时平台会从http://localhost:8080拉取index.html并在内置浏览器中执行dist/index.js按CtrlShiftIWindows打开平台内置DevTools → Sources面板 → 找到webpack://下的源文件 → 在main.js里打F9断点实操心得VS Code里打的断点无效必须在平台内置DevTools里打。原因源映射Source Map由Webpack生成映射关系只存在于浏览器端。VS Code调试器无法穿透沙箱获取平台浏览器的执行上下文。3.2 变量追踪如何查看scene对象的实时属性山海鲸SDK的scene对象是核心但它不是全局变量而是插件实例化时注入的。在src/main.js中你通常这样写export default function (context) { const { scene, api } context // scene是注入对象 scene.on(loaded, () { console.log(scene) // 这里打断点 }) }想查看scene所有属性不能直接console.log(scene)——它会被序列化成空对象。正确方法在断点处右键scene变量 → “Store as global variable” → 生成temp1切换到Console面板输入temp1.__proto__查看原型链输入Object.getOwnPropertyNames(temp1)列出所有自有属性对关键属性如scene.models输入temp1.models再展开能看到所有已加载模型ID更高效的方式在scene.on(loaded)回调里加一行scene.on(loaded, () { window.sceneDebug scene // 挂到window便于全局访问 })然后在Console直接输sceneDebug.models实时刷新。3.3 API调用调试为什么api.getDeviceData()返回undefined山海鲸API调用失败80%原因是权限或数据源未就绪。以api.getDeviceData(PLC_001, [Thickness_MM])为例先查权限在shanjing-plugin.json中确认permissions: [device.read]已声明再查设备注册登录平台管理后台 → 设备管理 → 确认PLC_001存在且协议配置为Modbus TCPIP端口正确最后查点位映射在设备详情页 → 点位列表确认Thickness_MM已添加数据类型为REAL地址为40001调试技巧在API调用后加.catch(err console.error(API Error:, err))但山海鲸SDK的错误对象err很简陋。真正有效的方法是开启平台日志在平台服务器config/app.conf中将logLevel改为DEBUG重启服务查看logs/shanjing-api.log搜索getDeviceData能看到完整请求URL、响应码、原始PLC返回字节流我遇到过一次日志显示Response: 0x00 0x00 0x00 0x00但API返回undefined。排查发现PLC寄存器地址配置错了——40001对应保持寄存器第1个但客户PLC实际从40000开始导致读到全零。修正地址后数据立刻正常。3.4 热更新失效为什么改了代码必须重启整个平台山海鲸的热更新Hot Module Replacement只作用于插件JS/CSS资源不包括平台核心逻辑。当你修改src/main.js并保存本地开发服务会重建dist/index.js但平台不会自动重新fetch——它缓存了上次加载的资源URL。解决方案有两个快捷键强制刷新在平台预览页面按CtrlRWindows或CmdRMac平台会重新从http://localhost:8080拉取最新资源配置自动重载在vue.config.js中添加devServer: { hot: true, liveReload: true, // 关键告诉平台每次请求加时间戳 before(app) { app.use((req, res, next) { if (req.url.includes(.js) || req.url.includes(.css)) { res.setHeader(Cache-Control, no-cache) } next() }) } }这样每次资源请求URL末尾会自动加?t123456789绕过浏览器缓存。实操心得别信“热更新万能”。涉及模型加载、场景初始化的代码如scene.loadModel()改完必须手动刷新页面。我习惯在scene.on(loaded)回调开头加console.log(Scene reloaded at, new Date().toLocaleTimeString())一眼看出是否生效。4. 从零到一一个可运行的阀门监控插件实操全过程现在我们动手做一个完整插件实时监控化工厂某段管道阀门开度并在三维模型上动态变色。这个案例覆盖环境配置、API调用、场景交互、错误处理全部核心环节代码可直接复用。4.1 创建项目与初始化SDK打开终端确保Node.js 16.20.2已激活# 创建项目目录 mkdir valve-monitor cd valve-monitor # 初始化npm npm init -y # 安装山海鲸SDK必须指定版本 npm install shanjing-sdk3.8.2 --save # 创建基础目录结构 mkdir src dist public touch src/main.js src/index.js touch shanjing-plugin.jsonshanjing-plugin.json内容{ name: valve-monitor, version: 1.0.0, description: 化工管道阀门开度监控, main: dist/index.js, author: your-name, entry: src/main.js, dependencies: [shanjing-sdk], permissions: [device.read, scene.write] }src/main.js骨架// src/main.js export default function (context) { const { scene, api } context let valveModelId null // 插件初始化 scene.on(loaded, async () { console.log(Valve Monitor Plugin loaded) await initValveModel() startMonitoring() }) async function initValveModel() { // 加载阀门模型假设模型ID为valve_001 const model await scene.getModel(valve_001) if (!model) { console.error(Model valve_001 not found in scene) return } valveModelId model.id } function startMonitoring() { // 每2秒读取一次开度 setInterval(async () { try { const data await api.getDeviceData(PLC_VALVE, [OpenPercent]) if (data data.OpenPercent ! undefined) { updateValveColor(data.OpenPercent) } } catch (err) { console.error(Failed to get valve data:, err) } }, 2000) } function updateValveColor(percent) { // 开度0-30%红色30-70%黄色70-100%绿色 let color #ff0000 if (percent 30 percent 70) color #ffff00 if (percent 70) color #00ff00 // 更新模型材质颜色 scene.setMaterialColor(valveModelId, color) } }4.2 配置构建脚本与Webpack安装构建依赖npm install webpack webpack-cli webpack-dev-server babel/core babel/preset-env babel-loader css-loader style-loader file-loader --save-devwebpack.config.jsconst path require(path) module.exports { entry: ./src/main.js, output: { path: path.resolve(__dirname, dist), filename: index.js, library: ValveMonitorPlugin, libraryTarget: umd }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: babel-loader, options: { presets: [babel/preset-env] } } } ] }, resolve: { extensions: [.js] }, devtool: source-map }package.json添加脚本scripts: { dev: webpack serve --mode development --port 8080, build: webpack --mode production }4.3 启动调试与平台联调终端执行npm run dev看到Project is running at http://localhost:8080登录山海鲸平台 → 插件管理 → 本地开发模式 → 填写http://localhost:8080→ 启用进入场景编辑器 → 添加“自定义插件”组件 → 选择valve-monitor→ 保存点击“预览”按CtrlShiftI打开DevTools → Sources →webpack://→src/main.js→ 在scene.on(loaded)里打断点刷新页面断点命中检查scene.getModel(valve_001)返回值若模型不存在需先在平台上传FBX格式阀门模型并在场景中放置ID设为valve_0014.4 常见报错与即时修复报错信息根本原因修复步骤TypeError: Cannot read property getModel of undefinedscene对象未注入context参数为空检查shanjing-plugin.json中entry路径是否正确确认src/main.js导出的是export default function而非export default classError: device PLC_VALVE not found设备未在平台注册或名称拼写错误进入平台设备管理确认设备名称完全一致区分大小写且状态为“在线”scene.setMaterialColor is not a functionSDK版本不匹配setMaterialColor在v3.7才支持执行npm list shanjing-sdk若版本低于3.7运行npm install shanjing-sdk3.8.2 --save强制更新Uncaught ReferenceError: __webpack_require__ is not defined构建产物未正确加载dist/index.js路径错误检查shanjing-plugin.json中main字段是否为dist/index.js确认dist目录下确实生成了该文件实操心得每次构建后务必检查dist/index.js文件大小。正常插件构建后文件应≥15KB含SDK代码。如果只有2KB说明Webpack未正确打包依赖常见原因是node_modules路径错误或resolve.alias配置冲突。我的固定检查法用文本编辑器打开dist/index.js搜索shanjing-sdk确认有相关字符串。5. 避坑指南那些文档里不会写的12个致命细节这些是我踩过的坑有些花了两天才定位有些让整个项目延期一周。它们不写在官方文档里因为属于“环境特异性问题”但每个都足以让新手放弃。5.1 Windows路径空格C:\Program Files\是隐形杀手山海鲸SDK在Windows下编译插件时若Node.js安装在C:\Program Files\nodejs\npm link会因路径含空格失败报错Error: ENOENT: no such file or directory。解决方案只有两个重装Node.js到无空格路径如C:\nodejs\或在package.json中scripts里加转义dev: set NODE_PATHC:\\nodejs\\node_modules webpack serve --mode development5.2 防火墙拦截8080端口被杀毒软件劫持某次在客户现场npm run dev显示服务启动但平台始终连不上http://localhost:8080。抓包发现请求根本没发出。最终发现是360安全卫士把8080端口标记为“可疑Web服务”自动拦截。解决方案临时关闭杀软防火墙或在360设置 → 流量防火墙 → 信任node.exe进程5.3 字体渲染差异Linux服务器上中文乱码在CentOS服务器部署插件时控制台日志出现????。原因是山海鲸平台Java进程未指定UTF-8编码。在shanjing-server.sh启动脚本中找到java -jar行在前面加JAVA_OPTS-Dfile.encodingUTF-85.4 模型坐标系FBX导入后Z轴朝上还是Y轴朝上山海鲸默认使用Y轴向上坐标系Unity风格但多数CAD导出的FBX是Z轴向上Maya风格。结果模型导入后“躺平”。修复方法在平台模型管理 → 编辑模型 → 勾选“旋转90度X轴”或在Blender中导出FBX前设置Forward: -Z,Up: Y5.5 数据类型陷阱PLC的INT和DINT在API里都是number山海鲸API不区分整数类型统一返回JSnumber。但某些PLC如西门子S7-1200的DINT32位和INT16位在Modbus协议中地址不同。如果点位配置错读到的值会是0或极大异常值。验证方法用Modbus Poll工具直连PLC确认地址和数据类型匹配。5.6 插件卸载残留删除插件后场景仍显示旧逻辑山海鲸不会自动清除插件注入的全局事件监听器。例如scene.on(click, handler)未off卸载插件后点击事件仍触发。必须在插件destroy生命周期中清理export default function (context) { const { scene } context let clickHandler scene.on(loaded, () { clickHandler () console.log(clicked) scene.on(click, clickHandler) }) // 必须提供destroy方法 return { destroy() { if (clickHandler) scene.off(click, clickHandler) } } }5.7 时间戳精度new Date().getTime()在IE11下返回毫秒级但山海鲸平台时间服务用微秒某次做历史数据回放发现时间轴偏移3秒。查证发现平台API返回的时间戳是微秒级16位数字而JSDate只支持毫秒级13位。修复new Date(timestamp / 1000)。5.8 跨域Cookie登录态无法传递到插件API请求山海鲸平台用withCredentials: true发送请求但插件调用api.xxx()时默认不带Cookie。解决方案在shanjing-plugin.json中加credentials: include字段。5.9 内存泄漏setInterval未清除导致CPU飙升插件未提供destroy方法时setInterval定时器持续运行。某次客户服务器CPU长期95%排查发现是未销毁的监控定时器。教训所有setInterval必须配对clearInterval且在destroy中执行。5.10 模型LOD高模在低端显卡上卡顿但平台不自动降级山海鲸不支持自动LODLevel of Detail。必须手动为同一模型准备多个精度版本如valve_high.fbx,valve_low.fbx在scene.loadModel()时根据scene.getPerformanceLevel()返回值选择加载。5.11 日志分级console.log在生产环境被屏蔽但api.log可输出到平台日志调试时用console.log上线后必须替换为api.log(info, Valve open: percent)否则日志不可追溯。5.12 版本锁死SDK v3.8.2与平台v3.8.0不兼容山海鲸采用“平台主版本SDK补丁版本”匹配策略。v3.8.0平台只能用v3.8.0~v3.8.2 SDK。若强行用v3.8.3scene.setModelVisible()会静默失败。验证方法在平台管理后台 → 系统信息 → 查看平台版本再执行npm list shanjing-sdk核对。最后分享一个小技巧我把所有项目通用的调试工具函数封装成debug-utils.js放在src/lib/下内容包括logSceneTree(scene)递归打印场景所有模型ID和层级checkDeviceConnection(deviceId)测试设备连通性并返回延迟dumpApiMethods(api)列出API所有可用方法及参数签名每个项目都引入它调试效率提升至少50%。这些不是黑魔法只是把重复劳动标准化——而真正的二次开发本就该如此务实。
返回列表