较新版本Cesium使用本地源码编译打包

0 写作背景

较新版本的Cesium(1.100版本及以后)在代码结构上做了一定的调整,打包方式也随之发生了一些变化。

Starting with version 1.100, CesiumJS will be published alongside two smaller packages @cesium/engine and @cesium/widgets

老版本修改了本地源码,执行 gulp build 即可编译出新的版本库;较新版本默认用 node_modules中从 npm 下载来的Cesium代码打包,因此对本地源码(packages/engine、packages/widgets)做的改动不会出现在打包结果中。

打开 Source/Cesium.js 文件,可以看到引用的是 node_modules 下文件的路径。在打包过程中,会根据这里的路径把所有代码合并到一个大文件中(Build/CesiumUnminified/index.js、Build/CesiumUnminified/Cesium.js 等)

javascript 复制代码
export const VERSION = '1.119';
export { AutomaticUniforms } from '@cesium/engine';
export { Buffer } from '@cesium/engine';
export { BufferUsage } from '@cesium/engine';
export { ClearCommand } from '@cesium/engine';
export { ComputeCommand } from '@cesium/engine';
export { ComputeEngine } from '@cesium/engine';
export { Context } from '@cesium/engine';
export { ContextLimits } from '@cesium/engine';
export { createUniform } from '@cesium/engine';
...

打包使用的索引文件 Source/Cesium.js

1 解决方案

1.1) 按如下代码片段修改 scripts/build.js 的 generateDeclaration 函数

javascript 复制代码
function generateDeclaration(workspace, file) {
  let assignmentName = path.basename(file, path.extname(file));
  let moduleId = file;
  moduleId = filePathToModuleId(moduleId);

  if (moduleId.indexOf("Source/Shaders") > -1) {
    assignmentName = `_shaders${assignmentName}`;
  }
  assignmentName = assignmentName.replace(/(\.|-)/g, "_");
  // return `export { ${assignmentName} } from '@${scope}/${workspace}';`;
  // 用本地源码的路径
  return `export { default as ${assignmentName} } from '../${file}';`;
}

重新执行 gulp build 后,Source/Cesium.js 文件中引用的路径会变成本地路径:

javascript 复制代码
export const VERSION = '1.119';
export { default as AutomaticUniforms } from '../packages/engine/Source/Renderer/AutomaticUniforms.js';
export { default as Buffer } from '../packages/engine/Source/Renderer/Buffer.js';
export { default as BufferUsage } from '../packages/engine/Source/Renderer/BufferUsage.js';
export { default as ClearCommand } from '../packages/engine/Source/Renderer/ClearCommand.js';
export { default as ColorTable } from '../packages/engine/Source/Renderer/ColorTable.js';
export { default as ComputeCommand } from '../packages/engine/Source/Renderer/ComputeCommand.js';
export { default as ComputeEngine } from '../packages/engine/Source/Renderer/ComputeEngine.js';
export { default as Context } from '../packages/engine/Source/Renderer/Context.js';
export { default as ContextLimits } from '../packages/engine/Source/Renderer/ContextLimits.js';
export { default as createUniform } from '../packages/engine/Source/Renderer/createUniform.js';
export { default as createUniformArray } from '../packages/engine/Source/Renderer/createUniformArray.js';
export { default as CubeMap } from '../packages/engine/Source/Renderer/CubeMap.js';
...

修改后的索引文件 Source/Cesium.js

1.2)改完这些还不算,本地源码 packages/widgets/Source 里也有一些地方引用了@cesium/engine。例如下面的形式:

javascript 复制代码
import {
  Clock,
  defined,
  destroyObject,
  EventHelper,
  JulianDate,
} from "@cesium/engine";
import knockout from "./ThirdParty/knockout.js";

本地源码也引用了node_modules下的源码

我们可以很容易在IDE中通过正则表达式替换掉对 @cesium/engine 的引用

根目录下(./packages/widgets/Source/*.js)的替换为 ../../engine/index.js

二级目录下(./packages/widgets/Source/*/*.js)的替换为 ../../../engine/index.js

至此,打包使用的就完全是本地源码了!

2 gulp build 命令解读

打包命令 gulp build 干了什么?gulp build 对应下面的 build 函数

javascript 复制代码
export async function build() {
  // ...
  await buildEngine(buildOptions);
  await buildWidgets(buildOptions);
  await buildCesium(buildOptions);
}

2.1)buildEngine:

  • glsl 文件编译成 js 文件;
  • 把 engine 下所有js文件的导出列表写到 packages/engine/index.js 中
  • 把 engine/Source 文件夹下所有 web worker 文件组织到 packages/engine/Build/Workers 文件夹下
  • 自动化测试文件相关(此处不详细说明)
javascript 复制代码
globalThis.CESIUM_VERSION = "1.119";
export { default as AutomaticUniforms } from './Source/Renderer/AutomaticUniforms.js';
export { default as Buffer } from './Source/Renderer/Buffer.js';
export { default as BufferUsage } from './Source/Renderer/BufferUsage.js';
export { default as ClearCommand } from './Source/Renderer/ClearCommand.js';
export { default as ComputeCommand } from './Source/Renderer/ComputeCommand.js';
export { default as ComputeEngine } from './Source/Renderer/ComputeEngine.js';
export { default as Context } from './Source/Renderer/Context.js';
export { default as ContextLimits } from './Source/Renderer/ContextLimits.js';
...

packages/engine/index.js

2.2)buildWidgets:

  • 把 packages/widgets 下所有 js 文件的导出列表写到 packages/widgets/index.js 中
  • 自动化测试文件相关(此处不详细说明)
javascript 复制代码
globalThis.CESIUM_VERSION = "1.119";
export { default as ClockViewModel } from './Source/ClockViewModel.js';
export { default as Command } from './Source/Command.js';
export { default as createCommand } from './Source/createCommand.js';
export { default as InspectorShared } from './Source/InspectorShared.js';
export { default as subscribeAndEvaluate } from './Source/subscribeAndEvaluate.js';
export { default as SvgPathBindingHandler } from './Source/SvgPathBindingHandler.js';
export { default as ToggleButtonViewModel } from './Source/ToggleButtonViewModel.js';
export { default as Animation } from './Source/Animation/Animation.js';
export { default as AnimationViewModel } from './Source/Animation/AnimationViewModel.js';
...

packages/widgets/index.js

2.3)buildCesium:

  • 在根目录下生成文件清单 Source/Cesium.js,根据该文件合并所有源码到一个大文件
  • 合并CSS文件
  • 组织并生成最终的web worker文件
  • 拷贝图片等静态资源到版本库所在的 Build 文件夹下
  • 自动化测试文件相关(此处不详细说明)
相关推荐
李明卫杭州1 分钟前
CSS BFC 完全指南:从原理到实战,彻底搞懂这个"结界"
前端
Momo__2 分钟前
MDN MCP Server——Mozilla 把 Web 文档接进 AI Agent,从此 LLM 不再瞎编 API
前端·ai编程·mcp
妙码生花2 分钟前
现代前端的极致性能 icon 加载方案(死磕成功版)
前端·vue.js·typescript
掘金者阿豪1 小时前
把业务数据变成共享仪表盘:Metabase可视化与远程访问实践
前端·后端
kyriewen1 小时前
折腾了半年 AI 编程工作流,最后发现效率瓶颈是桌上那块屏幕
前端·javascript·ai编程
蜗牛前端2 小时前
codex 全流程开发上线的高颜值礼簿小程序
前端·微信小程序
大龄秃头程序员2 小时前
我在图文流 App 里落地双层缓存、弱网降级与 OOM 治理
前端
老王以为2 小时前
React Renderer 分离的多平台架构
前端·react native·react.js
hunterandroid2 小时前
Kotlin Coroutines 与 Flow:让异步任务更清晰
前端
Bigger3 小时前
从零搭建 AI 代码审查服务:一份前端也能看懂的 Python 学习笔记
前端·ci/cd·ai编程