bundle-assets.py (2316B)
1 #!/usr/bin/env python3 2 """Bundle production entrypoints while preserving their import.meta.url bases.""" 3 import argparse 4 import json 5 from pathlib import Path 6 import shutil 7 import subprocess 8 9 ENTRIES = ['dist/app.js', 'dist/wasm-worker.js', 'dist/local-module-worker.js', 10 'dist/zig-helpers.js', 'runtime/zig/site-session.mjs', 11 'runtime/haskell/client.mjs', 'runtime/haskell/worker.mjs'] 12 13 14 def bundle(root, probe): 15 root = root.resolve() 16 support = root / 'nix-support' 17 support.mkdir(exist_ok=True) 18 shutil.copyfile(root / 'runtime/haskell/pins.mjs', support / 'haskell-pins.mjs') 19 shutil.copyfile(probe, root / 'dist/probe-api.js') 20 graphs = {} 21 for entry in [*ENTRIES, 'dist/probe-api.js']: 22 output = 'bundled/' + entry 23 subprocess.run(['esbuild', entry, '--bundle', '--format=esm', 24 '--platform=browser', '--target=es2020', 25 '--legal-comments=inline', '--outfile=' + output, 26 '--metafile=graph.json'], cwd=root, check=True) 27 graph = json.loads((root / 'graph.json').read_text()) 28 # Computed URL imports retain explicit lazy runtime boundaries. All 29 # statically resolved imports must be contained in their entrypoint. 30 assert all(not row['imports'] for row in graph['outputs'].values()) 31 graphs[entry] = graph 32 (support / 'bundle-graphs.json').write_text(json.dumps(graphs, indent=2) + '\n') 33 (root / 'graph.json').unlink() 34 for name in ['dist', 'runtime']: 35 for path in (root / name).rglob('*'): 36 if path.suffix in ['.js', '.mjs']: 37 path.unlink() 38 for entry in ENTRIES: 39 shutil.move(root / 'bundled' / entry, root / entry) 40 shutil.move(root / 'bundled/dist/probe-api.js', support / 'probe-api.js') 41 shutil.rmtree(root / 'bundled') 42 # Empty module directories would otherwise imply unshipped entrypoints. 43 for path in sorted((root / 'runtime').rglob('*'), reverse=True): 44 if path.is_dir() and not any(path.iterdir()): 45 path.rmdir() 46 47 48 if __name__ == '__main__': 49 parser = argparse.ArgumentParser(description=__doc__) 50 parser.add_argument('root', type=Path) 51 parser.add_argument('probe', type=Path) 52 args = parser.parse_args() 53 bundle(args.root, args.probe)