diff --git a/.gitignore b/.gitignore index e3f1a82b7fc..0df77e94361 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,14 @@ .DS_Store +.idea/ +.vscode/ /bench/ /demo/ /deno/ /esbuild /github/ +/npm/esbuild-android-64/esbuild.wasm +/npm/esbuild-android-64/exit0.js +/npm/esbuild-android-64/wasm_exec.js /npm/esbuild-wasm/browser.js /npm/esbuild-wasm/esbuild.wasm /npm/esbuild-wasm/esm/ @@ -18,5 +23,3 @@ bin esbuild.exe node_modules/ -.vscode/ -.idea/ diff --git a/Makefile b/Makefile index 1413b558082..f70acf4bac1 100644 --- a/Makefile +++ b/Makefile @@ -231,6 +231,7 @@ wasm-napi-exit0-windows: platform-all: @$(MAKE) --no-print-directory -j4 \ + platform-android \ platform-android-arm64 \ platform-darwin \ platform-darwin-arm64 \ @@ -273,6 +274,9 @@ platform-unixlike: cmd/esbuild/version.go node scripts/esbuild.js "$(NPMDIR)/package.json" --version CGO_ENABLED=0 GOOS="$(GOOS)" GOARCH="$(GOARCH)" go build $(GO_FLAGS) -o "$(NPMDIR)/bin/esbuild" ./cmd/esbuild +platform-android: platform-wasm + node scripts/esbuild.js npm/esbuild-android-64/package.json --version + platform-android-arm64: @$(MAKE) --no-print-directory GOOS=android GOARCH=arm64 NPMDIR=npm/esbuild-android-arm64 platform-unixlike @@ -358,7 +362,8 @@ publish-all: check-go-version @read OTP && OTP="$$OTP" $(MAKE) --no-print-directory -j4 \ publish-windows \ publish-windows-32 \ - publish-windows-arm64 + publish-windows-arm64 \ + publish-sunos @echo Enter one-time password: @read OTP && OTP="$$OTP" $(MAKE) --no-print-directory -j4 \ @@ -369,10 +374,10 @@ publish-all: check-go-version @echo Enter one-time password: @read OTP && OTP="$$OTP" $(MAKE) --no-print-directory -j4 \ + publish-android \ publish-android-arm64 \ publish-darwin \ - publish-darwin-arm64 \ - publish-sunos + publish-darwin-arm64 @echo Enter one-time password: @read OTP && OTP="$$OTP" $(MAKE) --no-print-directory -j4 \ @@ -406,6 +411,9 @@ publish-windows-32: platform-windows-32 publish-windows-arm64: platform-windows-arm64 test -n "$(OTP)" && cd npm/esbuild-windows-arm64 && npm publish --otp="$(OTP)" +publish-android: platform-android + test -n "$(OTP)" && cd npm/esbuild-android-64 && npm publish --otp="$(OTP)" + publish-android-arm64: platform-android-arm64 test -n "$(OTP)" && cd npm/esbuild-android-arm64 && npm publish --otp="$(OTP)" @@ -473,6 +481,8 @@ clean: rm -f npm/esbuild-windows-32/esbuild.exe rm -f npm/esbuild-windows-64/esbuild.exe rm -f npm/esbuild-windows-arm64/esbuild.exe + rm -rf npm/esbuild-android-64/bin + rm -rf npm/esbuild-android-64/esbuild.wasm npm/esbuild-android-64/wasm_exec.js npm/esbuild-android-64/exit0.js rm -rf npm/esbuild-android-arm64/bin rm -rf npm/esbuild-darwin-64/bin rm -rf npm/esbuild-darwin-arm64/bin @@ -489,8 +499,11 @@ clean: rm -rf npm/esbuild-netbsd-64/bin rm -rf npm/esbuild-openbsd-64/bin rm -rf npm/esbuild-sunos-64/bin - rm -f npm/esbuild-wasm/esbuild.wasm npm/esbuild-wasm/wasm_exec.js + rm -rf npm/esbuild/bin + rm -f npm/esbuild-wasm/esbuild.wasm npm/esbuild-wasm/wasm_exec.js npm/esbuild-wasm/exit0.js + rm -r npm/esbuild/install.js rm -rf npm/esbuild/lib + rm -rf npm/esbuild-wasm/esm rm -rf npm/esbuild-wasm/lib rm -rf require/*/bench/ rm -rf require/*/demo/ diff --git a/lib/npm/node-platform.ts b/lib/npm/node-platform.ts index b3d2273919d..2a00690a61a 100644 --- a/lib/npm/node-platform.ts +++ b/lib/npm/node-platform.ts @@ -32,9 +32,14 @@ export const knownUnixlikePackages: Record = { 'sunos x64 LE': 'esbuild-sunos-64', }; -export function pkgAndSubpathForCurrentPlatform(): { pkg: string, subpath: string } { +export const knownWebAssemblyFallbackPackages: Record = { + 'android x64 LE': 'esbuild-android-64', +}; + +export function pkgAndSubpathForCurrentPlatform(): { pkg: string, subpath: string, isWASM: boolean } { let pkg: string; let subpath: string; + let isWASM = false; let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`; if (platformKey in knownWindowsPackages) { @@ -47,11 +52,17 @@ export function pkgAndSubpathForCurrentPlatform(): { pkg: string, subpath: strin subpath = 'bin/esbuild'; } + else if (platformKey in knownWebAssemblyFallbackPackages) { + pkg = knownWebAssemblyFallbackPackages[platformKey]; + subpath = 'bin/esbuild'; + isWASM = true; + } + else { throw new Error(`Unsupported platform: ${platformKey}`); } - return { pkg, subpath }; + return { pkg, subpath, isWASM }; } function pkgForSomeOtherPlatform(): string | null { @@ -84,15 +95,15 @@ export function downloadedBinPath(pkg: string, subpath: string): string { return path.join(esbuildLibDir, `downloaded-${pkg}-${path.basename(subpath)}`); } -export function generateBinPath(): string { +export function generateBinPath(): { binPath: string, isWASM: boolean } { // This feature was added to give external code a way to modify the binary // path without modifying the code itself. Do not remove this because // external code relies on this (in addition to esbuild's own test suite). if (ESBUILD_BINARY_PATH) { - return ESBUILD_BINARY_PATH; + return { binPath: ESBUILD_BINARY_PATH, isWASM: false }; } - const { pkg, subpath } = pkgAndSubpathForCurrentPlatform(); + const { pkg, subpath, isWASM } = pkgAndSubpathForCurrentPlatform(); let binPath: string; try { @@ -180,8 +191,8 @@ by esbuild to install the correct binary executable for your current platform.`) fs.copyFileSync(binPath, binTargetPath); fs.chmodSync(binTargetPath, 0o755); } - return binTargetPath; + return { binPath: binTargetPath, isWASM }; } - return binPath; + return { binPath, isWASM }; } diff --git a/lib/npm/node-shim.ts b/lib/npm/node-shim.ts index 72bc65c21ea..bde1e66c929 100644 --- a/lib/npm/node-shim.ts +++ b/lib/npm/node-shim.ts @@ -1,4 +1,9 @@ #!/usr/bin/env node import { generateBinPath } from "./node-platform"; -require('child_process').execFileSync(generateBinPath(), process.argv.slice(2), { stdio: 'inherit' }); +const { binPath, isWASM } = generateBinPath() +if (isWASM) { + require('child_process').execFileSync('node', [binPath].concat(process.argv.slice(2)), { stdio: 'inherit' }); +} else { + require('child_process').execFileSync(binPath, process.argv.slice(2), { stdio: 'inherit' }); +} diff --git a/lib/npm/node.ts b/lib/npm/node.ts index f604e7125f1..09b028a3dca 100644 --- a/lib/npm/node.ts +++ b/lib/npm/node.ts @@ -68,7 +68,12 @@ let esbuildCommandAndArgs = (): [string, string[]] => { return ['node', [path.join(__dirname, '..', 'bin', 'esbuild')]]; } - return [generateBinPath(), []]; + const { binPath, isWASM } = generateBinPath() + if (isWASM) { + return ['node', [binPath]] + } else { + return [binPath, []]; + } }; // Return true if stderr is a TTY diff --git a/npm/esbuild-android-64/README.md b/npm/esbuild-android-64/README.md new file mode 100644 index 00000000000..3c8508e44ca --- /dev/null +++ b/npm/esbuild-android-64/README.md @@ -0,0 +1,3 @@ +# esbuild + +This is a WebAssembly shim for esbuild on Android x64. See https://github.com/evanw/esbuild for details. diff --git a/npm/esbuild-android-64/package.json b/npm/esbuild-android-64/package.json new file mode 100644 index 00000000000..eb1f820277b --- /dev/null +++ b/npm/esbuild-android-64/package.json @@ -0,0 +1,17 @@ +{ + "name": "esbuild-android-64", + "version": "0.14.23", + "description": "A WebAssembly shim for esbuild on Android x64.", + "repository": "https://github.com/evanw/esbuild", + "license": "MIT", + "preferUnplugged": false, + "engines": { + "node": ">=12" + }, + "os": [ + "android" + ], + "cpu": [ + "x64" + ] +} diff --git a/npm/esbuild/package.json b/npm/esbuild/package.json index 55d1c4afbc9..ea5bbbe1f96 100644 --- a/npm/esbuild/package.json +++ b/npm/esbuild/package.json @@ -15,6 +15,7 @@ "esbuild": "bin/esbuild" }, "optionalDependencies": { + "esbuild-android-64": "0.14.23", "esbuild-android-arm64": "0.14.23", "esbuild-darwin-64": "0.14.23", "esbuild-darwin-arm64": "0.14.23", diff --git a/scripts/esbuild.js b/scripts/esbuild.js index 0010c564bb2..5375b42fe51 100644 --- a/scripts/esbuild.js +++ b/scripts/esbuild.js @@ -71,6 +71,7 @@ const buildNeutralLib = (esbuildPath) => { const optionalDependencies = Object.fromEntries(Object.values({ ...platforms.exports.knownWindowsPackages, ...platforms.exports.knownUnixlikePackages, + ...platforms.exports.knownWebAssemblyFallbackPackages, }).sort().map(x => [x, version])) // Update "npm/esbuild/package.json" @@ -81,6 +82,10 @@ const buildNeutralLib = (esbuildPath) => { } exports.buildWasmLib = async (esbuildPath) => { + const npmWasmShimDirs = [ + path.join(repoDir, 'npm', 'esbuild-android-64'), + ] + // Asynchronously start building the WebAssembly module const npmWasmDir = path.join(repoDir, 'npm', 'esbuild-wasm') const goBuildPromise = new Promise((resolve, reject) => childProcess.execFile('go', @@ -223,17 +228,27 @@ exports.buildWasmLib = async (esbuildPath) => { exit0Map[entry] = compressed.toString('base64'); } } - fs.writeFileSync(path.join(npmWasmDir, 'exit0.js'), ` + const exit0Code = ` // Each of these is a native module that calls "exit(0)". This is a workaround // for https://github.com/nodejs/node/issues/36616. These native modules are // stored in a string both to make them smaller and to hide them from Yarn 2, // since they make Yarn 2 unzip this package. module.exports = ${JSON.stringify(exit0Map, null, 2)}; -`); +`; + fs.writeFileSync(path.join(npmWasmDir, 'exit0.js'), exit0Code); // Join with the asynchronous WebAssembly build await goBuildPromise; + + // Also copy this into the WebAssembly shim directories + for (const dir of npmWasmShimDirs) { + fs.mkdirSync(path.join(dir, 'bin'), { recursive: true }) + fs.writeFileSync(path.join(dir, 'wasm_exec.js'), wasm_exec_js); + fs.writeFileSync(path.join(dir, 'exit0.js'), exit0Code); + fs.copyFileSync(path.join(npmWasmDir, 'bin', 'esbuild'), path.join(dir, 'bin', 'esbuild')); + fs.copyFileSync(path.join(npmWasmDir, 'esbuild.wasm'), path.join(dir, 'esbuild.wasm')); + } } const buildDenoLib = (esbuildPath) => {