Skip to content

Commit 6e3ef52

Browse files
committed
merge node and browser apis, throw errors instead
1 parent 92cfbd1 commit 6e3ef52

File tree

5 files changed

+85
-34
lines changed

5 files changed

+85
-34
lines changed

docs/js-api.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ Example usage:
8989
```ts
9090
(async () => {
9191
// Start the esbuild web worker once
92-
const { startService } = require('esbuild-wasm/lib/browser')
92+
const { startService } = require('esbuild-wasm')
9393
const wasmURL = 'node_modules/esbuild-wasm/esbuild.wasm'
9494
const service = await startService({ wasmURL })
9595

lib/browser.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,25 @@ import * as common from "./common"
33

44
declare let WEB_WORKER_SOURCE_CODE: string
55

6-
export let startService = (options: types.BrowserServiceOptions): Promise<types.Service> => {
6+
let build: typeof types.build = options => {
7+
throw new Error(`The "build" API only works in node`);
8+
};
9+
10+
let transform: typeof types.transform = (input, options) => {
11+
throw new Error(`The "transform" API only works in node`);
12+
};
13+
14+
let buildSync: typeof types.buildSync = options => {
15+
throw new Error(`The "buildSync" API only works in node`);
16+
};
17+
18+
let transformSync: typeof types.transformSync = (input, options) => {
19+
throw new Error(`The "transformSync" API only works in node`);
20+
};
21+
22+
let startService: typeof types.startService = options => {
23+
if (!options) throw new Error('Must provide an options object to "startService"');
24+
if (!options.wasmURL) throw new Error('Must provide the "wasmURL" option');
725
return fetch(options.wasmURL).then(r => r.arrayBuffer()).then(wasm => {
826
let code = `{` +
927
`let global={};` +
@@ -45,7 +63,7 @@ export let startService = (options: types.BrowserServiceOptions): Promise<types.
4563

4664
return {
4765
build(options) {
48-
throw new Error('Not implemented yet')
66+
throw new Error(`The "build" API only works in node`)
4967
},
5068
transform: (input, options) =>
5169
new Promise((resolve, reject) =>
@@ -58,3 +76,13 @@ export let startService = (options: types.BrowserServiceOptions): Promise<types.
5876
}
5977
})
6078
}
79+
80+
let api: typeof types = {
81+
build,
82+
buildSync,
83+
transform,
84+
transformSync,
85+
startService,
86+
};
87+
88+
module.exports = api;

lib/node.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,23 @@ let esbuildCommandAndArgs = (): [string, string[]] => {
2323
// Return true if stderr is a TTY
2424
let isTTY = () => isatty(2);
2525

26-
export let build: typeof types.build = options => {
26+
let build: typeof types.build = options => {
2727
return startService().then(service => {
2828
let promise = service.build(options);
2929
promise.then(service.stop, service.stop); // Kill the service afterwards
3030
return promise;
3131
});
3232
};
3333

34-
export let transform: typeof types.transform = (input, options) => {
34+
let transform: typeof types.transform = (input, options) => {
3535
return startService().then(service => {
3636
let promise = service.transform(input, options);
3737
promise.then(service.stop, service.stop); // Kill the service afterwards
3838
return promise;
3939
});
4040
};
4141

42-
export let buildSync: typeof types.buildSync = options => {
42+
let buildSync: typeof types.buildSync = options => {
4343
let result: types.BuildResult;
4444
runServiceSync(service => service.build(options, isTTY(), (err, res) => {
4545
if (err) throw err;
@@ -48,7 +48,7 @@ export let buildSync: typeof types.buildSync = options => {
4848
return result!;
4949
};
5050

51-
export let transformSync: typeof types.transformSync = (input, options) => {
51+
let transformSync: typeof types.transformSync = (input, options) => {
5252
let result: types.TransformResult;
5353
runServiceSync(service => service.transform(input, options, isTTY(), (err, res) => {
5454
if (err) throw err;
@@ -57,7 +57,11 @@ export let transformSync: typeof types.transformSync = (input, options) => {
5757
return result!;
5858
};
5959

60-
export let startService = (): Promise<types.Service> => {
60+
let startService: typeof types.startService = options => {
61+
if (options) {
62+
if (options.wasmURL) throw new Error(`The "wasmURL" option only works in the browser`)
63+
if (options.worker) throw new Error(`The "worker" option only works in the browser`)
64+
}
6165
let [command, args] = esbuildCommandAndArgs();
6266
let child = child_process.spawn(command, args.concat('--service'), {
6367
cwd: process.cwd(),
@@ -110,3 +114,13 @@ let runServiceSync = (callback: (service: common.StreamService) => void): void =
110114
readFromStdout(stdout);
111115
afterClose();
112116
};
117+
118+
let api: typeof types = {
119+
build,
120+
buildSync,
121+
transform,
122+
transformSync,
123+
startService,
124+
};
125+
126+
module.exports = api;

lib/types.ts

+28-12
Original file line numberDiff line numberDiff line change
@@ -127,34 +127,50 @@ export interface Service {
127127
stop(): void;
128128
}
129129

130-
////////////////////////////////////////////////////////////////////////////////
131-
// Node API
132-
133130
// This function invokes the "esbuild" command-line tool for you. It returns a
134131
// promise that either resolves with a "BuildResult" object or rejects with a
135132
// "BuildFailure" object.
133+
//
134+
// Works in node: yes
135+
// Works in browser: no
136136
export declare function build(options: BuildOptions): Promise<BuildResult>;
137137

138138
// This function transforms a single JavaScript file. It can be used to minify
139139
// JavaScript, convert TypeScript/JSX to JavaScript, or convert newer JavaScript
140140
// to older JavaScript. It returns a promise that is either resolved with a
141141
// "TransformResult" object or rejected with a "TransformFailure" object.
142+
//
143+
// Works in node: yes
144+
// Works in browser: no
142145
export declare function transform(input: string, options: TransformOptions): Promise<TransformResult>;
143146

147+
// A synchronous version of "build".
148+
//
149+
// Works in node: yes
150+
// Works in browser: no
144151
export declare function buildSync(options: BuildOptions): BuildResult;
152+
153+
// A synchronous version of "transform".
154+
//
155+
// Works in node: yes
156+
// Works in browser: no
145157
export declare function transformSync(input: string, options: TransformOptions): TransformResult;
146158

147159
// This starts "esbuild" as a long-lived child process that is then reused, so
148160
// you can call methods on the service many times without the overhead of
149161
// starting up a new child process each time.
150-
export declare function startService(): Promise<Service>;
151-
152-
////////////////////////////////////////////////////////////////////////////////
153-
// Browser API
154-
155-
export interface BrowserServiceOptions {
156-
wasmURL: string
162+
//
163+
// Works in node: yes
164+
// Works in browser: yes ("options" is required)
165+
export declare function startService(options?: ServiceOptions): Promise<Service>;
166+
167+
export interface ServiceOptions {
168+
// The URL of the "esbuild.wasm" file. This must be provided when running
169+
// esbuild in the browser.
170+
wasmURL?: string
171+
172+
// By default esbuild runs the WebAssembly-based browser API in a web worker
173+
// to avoid blocking the UI thread. This can be disabled by setting "worker"
174+
// to false.
157175
worker?: boolean
158176
}
159-
160-
export declare function startService(options: BrowserServiceOptions): Promise<Service>;

scripts/esbuild.js

+7-14
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,6 @@ const fs = require('fs')
66
const repoDir = path.dirname(__dirname)
77
const npmDir = path.join(repoDir, 'npm', 'esbuild')
88

9-
function buildTypeDefinitions(isBrowser) {
10-
const types_ts = fs.readFileSync(path.join(repoDir, 'lib', 'types.ts'), 'utf8')
11-
const nodeAPI = /\/+\r?\n\/\/ Node API/.exec(types_ts).index
12-
const browserAPI = /\/+\r?\n\/\/ Browser API/.exec(types_ts).index
13-
const common = types_ts.slice(0, Math.min(browserAPI, nodeAPI));
14-
if (isBrowser) return common + types_ts.slice(browserAPI, nodeAPI > browserAPI ? nodeAPI : types_ts.length);
15-
else return common + types_ts.slice(nodeAPI, browserAPI > nodeAPI ? browserAPI : types_ts.length);
16-
}
17-
189
function buildNativeLib(esbuildPath) {
1910
const libDir = path.join(npmDir, 'lib')
2011
try {
@@ -33,7 +24,8 @@ function buildNativeLib(esbuildPath) {
3324
], { cwd: repoDir })
3425

3526
// Generate "npm/esbuild/lib/main.d.ts"
36-
fs.writeFileSync(path.join(libDir, 'main.d.ts'), buildTypeDefinitions(false))
27+
const types_ts = fs.readFileSync(path.join(repoDir, 'lib', 'types.ts'), 'utf8')
28+
fs.writeFileSync(path.join(libDir, 'main.d.ts'), types_ts)
3729
}
3830

3931
function buildWasmLib(esbuildPath) {
@@ -55,8 +47,9 @@ function buildWasmLib(esbuildPath) {
5547
], { cwd: repoDir })
5648

5749
// Generate "npm/esbuild-wasm/lib/main.d.ts" and "npm/esbuild-wasm/lib/browser.d.ts"
58-
fs.writeFileSync(path.join(libDir, 'main.d.ts'), buildTypeDefinitions(false))
59-
fs.writeFileSync(path.join(libDir, 'browser.d.ts'), buildTypeDefinitions(true))
50+
const types_ts = fs.readFileSync(path.join(repoDir, 'lib', 'types.ts'), 'utf8')
51+
fs.writeFileSync(path.join(libDir, 'main.d.ts'), types_ts)
52+
fs.writeFileSync(path.join(libDir, 'browser.d.ts'), types_ts)
6053

6154
// Minify "npm/esbuild-wasm/wasm_exec.js"
6255
const wasm_exec_js = path.join(npmWasmDir, 'wasm_exec.js')
@@ -75,8 +68,8 @@ function buildWasmLib(esbuildPath) {
7568
], { cwd: repoDir }).toString().trim()
7669

7770
// Generate "npm/esbuild-wasm/browser.js"
78-
const umdPrefix = `(exports=>{`
79-
const umdSuffix = `})(typeof exports==="object"?exports:(typeof self!=="undefined"?self:this).esbuild={});\n`
71+
const umdPrefix = `Object.assign(typeof exports==="object"?exports:(typeof self!=="undefined"?self:this).esbuild={},(module=>{`
72+
const umdSuffix = `return module})({}).exports);\n`
8073
const browserJs = childProcess.execFileSync(esbuildPath, [
8174
path.join(repoDir, 'lib', 'browser.ts'),
8275
'--bundle',

0 commit comments

Comments
 (0)