mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 15:52:21 +00:00
build: reach Navara only through import() and ship its worker wasm
The import-direction check now tells dynamic imports apart
(analyzeModule(source, { dynamic: true })) and rejects any static import
or re-export of src/globe/navara/** from outside that directory, so the
Navara engine can only be a lazily loaded chunk of the app.
Navara's prebuilt workers load their wasm by file name next to
themselves, which the bundler cannot see; a build-only Rollup plugin
copies the missing ones (draco decoder, font worker) into assets/ when
the bundle includes Navara, and adds nothing to a build without it.
This commit is contained in:
1 parent
72fec292d4
commit
306e3e9467
8 files changed
+179
-7
No files matched your search
@@ -241,6 +241,44 @@ for (const [name, files, pattern] of [
|
||||
});
|
||||
}
|
||||
|
||||
test('module analysis can tell dynamic imports from static ones', () => {
|
||||
assert.deepEqual(
|
||||
analyzeModule(
|
||||
"import a from 'one'; export * from 'two'; import('three'); const x = () => import('four');",
|
||||
{ dynamic: true },
|
||||
),
|
||||
{
|
||||
imports: ['one', 'two', 'three', 'four'],
|
||||
browser: [],
|
||||
dynamicImports: ['three', 'four'],
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('the app reaches the Navara engine only through a dynamic import', (t) => {
|
||||
const { root, write } = fixture(t);
|
||||
write('src/globe/navara/index.js', "import './engine.js';");
|
||||
write('src/globe/navara/engine.js', '');
|
||||
write(
|
||||
'src/app/scene.js',
|
||||
"export const load = () => import('../globe/navara/index.js');",
|
||||
);
|
||||
assert.doesNotThrow(() => checkImportDirections(root));
|
||||
write('src/app/scene.js', "import '../globe/navara/index.js';");
|
||||
assert.throws(
|
||||
() => checkImportDirections(root),
|
||||
/src\/app\/scene\.js: The Navara engine loads only through a dynamic import\(\): src\/globe\/navara\/index\.js/,
|
||||
);
|
||||
write(
|
||||
'src/app/scene.js',
|
||||
"export { createNavaraGlobe } from '../globe/navara/index.js';",
|
||||
);
|
||||
assert.throws(
|
||||
() => checkImportDirections(root),
|
||||
/only through a dynamic import/,
|
||||
);
|
||||
});
|
||||
|
||||
test('geo modules may import each other, and its tests may import cesium', (t) => {
|
||||
const { root, write } = fixture(t);
|
||||
write('src/geo/math.js', 'export const half = (value) => value / 2;');
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { navaraWorkerAssets } from '../../build/navaraAssets.js';
|
||||
import { createBrowserViteConfig } from '../../build/vite.js';
|
||||
|
||||
test('the build copies the wasm files Navara workers load by name next to them', (t) => {
|
||||
const dir = mkdtempSync(path.join(os.tmpdir(), 'gev-navara-assets-'));
|
||||
t.after(() => rmSync(dir, { recursive: true, force: true }));
|
||||
writeFileSync(path.join(dir, 'draco_decoder-AAAA.wasm'), 'draco');
|
||||
writeFileSync(path.join(dir, 'navara_wasm_worker_bg-BBBB.wasm'), 'worker');
|
||||
writeFileSync(path.join(dir, 'fontWorker-CCCC.js'), 'not wasm');
|
||||
const plugin = navaraWorkerAssets({ assetsDir: dir });
|
||||
const emitted = [];
|
||||
const bundle = {
|
||||
// Rollup already emitted this one under the same name.
|
||||
'assets/navara_wasm_worker_bg-BBBB.wasm': { type: 'asset' },
|
||||
// A Navara worker chunk shows the build includes Navara.
|
||||
'assets/index-DDDD.js': { type: 'chunk', code: 'navara_wasm_worker_bg' },
|
||||
};
|
||||
plugin.generateBundle.call(
|
||||
{ emitFile: (file) => emitted.push(file) },
|
||||
{},
|
||||
bundle,
|
||||
);
|
||||
assert.deepEqual(
|
||||
emitted.map(({ fileName, type }) => [fileName, type]),
|
||||
[['assets/draco_decoder-AAAA.wasm', 'asset']],
|
||||
);
|
||||
assert.equal(String(emitted[0].source), 'draco');
|
||||
});
|
||||
|
||||
test('a build without Navara gets no Navara wasm', (t) => {
|
||||
const dir = mkdtempSync(path.join(os.tmpdir(), 'gev-navara-assets-'));
|
||||
t.after(() => rmSync(dir, { recursive: true, force: true }));
|
||||
writeFileSync(path.join(dir, 'draco_decoder-AAAA.wasm'), 'draco');
|
||||
const plugin = navaraWorkerAssets({ assetsDir: dir });
|
||||
const emitted = [];
|
||||
plugin.generateBundle.call(
|
||||
{ emitFile: (file) => emitted.push(file) },
|
||||
{},
|
||||
{ 'assets/index-EEEE.js': { type: 'chunk', code: 'cesium only' } },
|
||||
);
|
||||
assert.deepEqual(emitted, []);
|
||||
});
|
||||
|
||||
test('the browser build runs the Navara asset copy as a Rollup plugin', () => {
|
||||
const { build } = createBrowserViteConfig({});
|
||||
assert.deepEqual(
|
||||
build.rollupOptions.plugins.map(({ name }) => name),
|
||||
['navara-worker-assets'],
|
||||
);
|
||||
assert.equal(build.chunkSizeWarningLimit, 1500);
|
||||
});
|
||||
Reference in new issue
Block a user