Skip to content

Commit

Permalink
php-wasm/node: Ship as ESM and CJS (#1585)
Browse files Browse the repository at this point in the history
The `@php-wasm/node` package used to be CommonJS only. This created
tricky dependency identity problems in ESM applications, e.g. in #1577
the main script imports the ESM version of `@php-wasm/universal`, but
`@php-wasm/node` imports the CJS version of it.

This PR ensures `@php-wasm/node` has an ESM version available.

This is first step towards solving
#1583

Closes #1579
Closes #1577

 ## Testing instructions

Run `npm run build`, copy the built packages from
`dist/packages/php-wasm` to node_modules in another directory, create a
test.js script with the following contents:

```
import { PHP } from '@php-wasm/universal';
import { loadNodeRuntime, useHostFilesystem } from '@php-wasm/node';

const php = new PHP(await loadNodeRuntime('8.0'));
console.log("Hey");
console.log(await php.run({ code: 'echo "Hello, World!";' }));
```

Then create a package.json file with `{"type":"module"}` and confirm
that running test.js works. Then create test.cjs file as follows:

```js
const { PHP } = require('@php-wasm/universal');
const { loadNodeRuntime } = require('@php-wasm/node');

async function main() {
    const runtimeId = await loadNodeRuntime('8.0');
    console.log({runtimeId})
    const php = new PHP(runtimeId);

    console.log(php);
}
main();
```

And confirm this one works, too.
  • Loading branch information
adamziel authored Jul 8, 2024
1 parent d915634 commit 8aed120
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 55 deletions.
97 changes: 97 additions & 0 deletions packages/php-wasm/node/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import esbuild from 'esbuild';
import fs from 'fs';
import path from 'path';

try {
fs.mkdirSync('dist/packages/php-wasm/node', { recursive: true });
} catch (e) {
// Ignore
}

async function build() {
await esbuild.build({
entryPoints: [
'packages/php-wasm/node/src/index.ts',
'packages/php-wasm/node/src/noop.ts',
],
supported: {
'dynamic-import': false,
},
outExtension: { '.js': '.cjs' },
outdir: 'dist/packages/php-wasm/node',
platform: 'node',
assetNames: '[name]',
chunkNames: '[name]',
logOverride: {
'commonjs-variable-in-esm': 'silent',
},
format: 'cjs',
bundle: true,
tsconfig: 'packages/php-wasm/node/tsconfig.json',
external: ['@php-wasm/*', '@wp-playground/*', 'ws'],
loader: {
'.php': 'text',
'.ini': 'file',
'.wasm': 'file',
},
});

const nodeModules = new RegExp(/^(?:.*[\\/])?node_modules(?:[\\/].*)?$/);
await esbuild.build({
entryPoints: [
'packages/php-wasm/node/src/index.ts',
'packages/php-wasm/node/src/noop.ts',
],
banner: {
js: "import { createRequire as topLevelCreateRequire } from 'module';\n const require = topLevelCreateRequire(import.meta.url);",
},
plugins: [
{
name: 'Support __dirname in ESM',
setup(build) {
build.onLoad({ filter: /.*/ }, ({ path: filePath }) => {
if (!filePath.match(nodeModules)) {
let contents = fs.readFileSync(filePath, 'utf8');
const loader = path.extname(filePath).substring(1);
const dirname = path.dirname(filePath);
contents = contents
.replaceAll('__dirname', `"${dirname}"`)
.replaceAll('__filename', `"${filePath}"`);
return {
contents,
loader,
};
}
});
},
},
],
outdir: 'dist/packages/php-wasm/node',
platform: 'node',
assetNames: '[name]',
chunkNames: '[name]',
logOverride: {
'commonjs-variable-in-esm': 'silent',
},
packages: 'external',
bundle: true,
tsconfig: 'packages/php-wasm/node/tsconfig.json',
external: ['@php-wasm/*', '@wp-playground/*', 'ws', 'fs', 'path'],
supported: {
'dynamic-import': true,
'top-level-await': true,
},
format: 'esm',
loader: {
'.php': 'text',
'.ini': 'file',
'.wasm': 'file',
},
});

fs.copyFileSync(
'packages/php-wasm/node/README.md',
'dist/packages/php-wasm/node/README.md'
);
}
build();
28 changes: 0 additions & 28 deletions packages/php-wasm/node/esbuild.js

This file was deleted.

11 changes: 10 additions & 1 deletion packages/php-wasm/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
"url": "https://github.com/adamziel"
}
],
"exports": {
".": {
"import": "./index.js",
"require": "./index.cjs"
},
"./package.json": "./package.json"
},
"type": "module",
"main": "./index.cjs",
"module": "./index.js",
"typedoc": {
"entryPoint": "./src/index.ts",
"readmeFile": "./README.md",
Expand All @@ -26,7 +36,6 @@
"directory": "../../../dist/packages/php-wasm/node"
},
"license": "GPL-2.0-or-later",
"main": "index.cjs",
"types": "index.d.ts",
"gitHead": "2f8d8f3cea548fbd75111e8659a92f601cddc593",
"engines": {
Expand Down
30 changes: 4 additions & 26 deletions packages/php-wasm/node/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,33 +51,11 @@
},
"build:bundle": {
"executor": "@nx/esbuild:esbuild",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"outputs": ["dist/packages/php-wasm/node"],
"executor": "nx:run-commands",
"options": {
"main": "packages/php-wasm/node/src/index.ts",
"outputPath": "dist/packages/php-wasm/node",
"additionalEntryPoints": ["packages/php-wasm/node/src/noop.ts"],
"tsConfig": "packages/php-wasm/node/tsconfig.lib.json",
"project": "packages/php-wasm/node/package.json",
"assets": [
{
"glob": "packages/php-wasm/node/README.md",
"input": ".",
"output": "."
}
],
"bundle": true,
"format": ["cjs"],
"esbuildConfig": "packages/php-wasm/node/esbuild.js",
"thirdParty": true
},
"configurations": {
"development": {
"minify": false
},
"production": {
"minify": false
}
"command": "node packages/php-wasm/node/build.js",
"parallel": false
}
},
"recompile-php": {
Expand Down

0 comments on commit 8aed120

Please sign in to comment.