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 文件夹下
- 自动化测试文件相关(此处不详细说明)