Description
@php-wasm/web
and @php-wasm/node
now ship an additional static file called icudt74l.dat
. Our existing build setup struggles to preserve it throughout the supply chain steps without errors. Running builds or tests won't throw errors, however, downstream builds will, since they are using Vite.
✘ [ERROR] No loader is configured for ".dat" files: node_modules/@php-wasm/web/shared/icudt74l.dat
node_modules/@php-wasm/web/shared/icudt74l.js:1:25:
1 │ import dataFilename from './icudt74l.dat';
/Users/mho/intl/template/node_modules/esbuild/lib/main.js:1463
let error = new Error(text);
And this is because, by default, Vite (via ESBuild) tries to statically analyze and bundle all imports, even in node_modules
.
This will certainly happen for other static files in the future if we don't implement a feature to that matter.
Let's resolve this challenge once and for all and come up with a canonical solution we can use across the Playground codebase. We need to support quite a few scenarios:
- Ship
.wasm
files,.dat
files, and more file types - ...in CommonJS and ESM
- ...for Node.js and web browser
- ...in reusable npm packages and in user-facing apps (playground.wordpress.net, Playground CLI)
- ...via Vite (esbuild + rollup) and standalone esbuild
- ...provide a way of loading them (fs.readFile vs fetch)
- ...preserve the files as they are without base64-encoding them
Let's:
- Figure out if Vite can support our use-case across the board. Let's go deep, consider access to private APIs etc.
- If not, consider another build system. Maintaining Vite config that includes esbuild and Rollup conf and plugins is a burden
- Explore a build-time or runtime utility for
function loadMyStaticFile() { if(node) { fs.readFileSync(path); } else { await fetch(url); }}
Links:
Testing instructions:
Create the three files and run run npm install && npm run dev
:
package.json
{
"type" : "module",
"dependencies" : {
"@php-wasm/universal" : "^1.1.4",
"@php-wasm/web" : "^1.1.4",
"vite" : "^6.2.5"
},
"scripts" : {
"dev" : "vite"
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<script type="module" src="web.js"></script>
</head>
<body>
<div id="app" />
</body>
</html>
web.js
import { PHP } from '@php-wasm/universal';
import { loadWebRuntime } from '@php-wasm/web';
new PHP( await loadWebRuntime( '8.4' ) )