Skip to content

Commit eb1d5f1

Browse files
committed
feat: more helpful errors when using incompatible node modules
1 parent 7d3cccd commit eb1d5f1

File tree

3 files changed

+116
-30
lines changed

3 files changed

+116
-30
lines changed

.changeset/light-tips-hang.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@sveltejs/adapter-cloudflare-workers': minor
3+
'@sveltejs/adapter-cloudflare': minor
4+
---
5+
6+
feat: more helpful errors when using incompatible Node modules

packages/adapter-cloudflare-workers/index.js

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,61 @@ export default function ({ config = 'wrangler.toml' } = {}) {
8282
external.push(...compatible_node_modules.map((id) => `node:${id}`));
8383
}
8484

85-
await esbuild.build({
86-
platform: 'browser',
87-
conditions: ['worker', 'browser'],
88-
sourcemap: 'linked',
89-
target: 'es2022',
90-
entryPoints: [`${tmp}/entry.js`],
91-
outfile: main,
92-
bundle: true,
93-
external,
94-
alias: Object.fromEntries(compatible_node_modules.map((id) => [id, `node:${id}`])),
95-
format: 'esm',
96-
loader: {
97-
'.wasm': 'copy'
85+
try {
86+
const result = await esbuild.build({
87+
platform: 'browser',
88+
conditions: ['worker', 'browser'],
89+
sourcemap: 'linked',
90+
target: 'es2022',
91+
entryPoints: [`${tmp}/entry.js`],
92+
outfile: main,
93+
bundle: true,
94+
external,
95+
alias: Object.fromEntries(compatible_node_modules.map((id) => [id, `node:${id}`])),
96+
format: 'esm',
97+
loader: {
98+
'.wasm': 'copy'
99+
},
100+
logLevel: 'silent'
101+
});
102+
103+
if (result.warnings.length > 0) {
104+
const formatted = await esbuild.formatMessages(result.warnings, {
105+
kind: 'warning',
106+
color: true
107+
});
108+
109+
console.error(formatted.join('\n'));
98110
}
99-
});
111+
} catch (error) {
112+
for (const e of error.errors) {
113+
for (const node of e.notes) {
114+
const match =
115+
/The package "(.+)" wasn't found on the file system but is built into node/.exec(
116+
node.text
117+
);
118+
if (match) {
119+
let id = match[1];
120+
if (!id.startsWith('node:')) id = `node:${id}`;
121+
122+
node.text = `Cannot use "${id}" when deploying to Cloudflare.`;
123+
}
124+
}
125+
}
126+
127+
const formatted = await esbuild.formatMessages(error.errors, {
128+
kind: 'error',
129+
color: true
130+
});
131+
132+
console.error(formatted.join('\n'));
133+
134+
throw new Error(
135+
`Bundling with esbuild failed with ${error.errors.length} ${
136+
error.errors.length === 1 ? 'error' : 'errors'
137+
}`
138+
);
139+
}
100140

101141
builder.log.minor('Copying assets...');
102142
const bucket_dir = `${site.bucket}${builder.config.kit.paths.base}`;

packages/adapter-cloudflare/index.js

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,62 @@ export default function (options = {}) {
7070

7171
const external = ['cloudflare:*', ...compatible_node_modules.map((id) => `node:${id}`)];
7272

73-
await esbuild.build({
74-
platform: 'browser',
75-
conditions: ['worker', 'browser'],
76-
sourcemap: 'linked',
77-
target: 'es2022',
78-
entryPoints: [`${tmp}/_worker.js`],
79-
outfile: `${dest}/_worker.js`,
80-
allowOverwrite: true,
81-
format: 'esm',
82-
bundle: true,
83-
loader: {
84-
'.wasm': 'copy'
85-
},
86-
external,
87-
alias: Object.fromEntries(compatible_node_modules.map((id) => [id, `node:${id}`]))
88-
});
73+
try {
74+
const result = await esbuild.build({
75+
platform: 'browser',
76+
conditions: ['worker', 'browser'],
77+
sourcemap: 'linked',
78+
target: 'es2022',
79+
entryPoints: [`${tmp}/_worker.js`],
80+
outfile: `${dest}/_worker.js`,
81+
allowOverwrite: true,
82+
format: 'esm',
83+
bundle: true,
84+
loader: {
85+
'.wasm': 'copy'
86+
},
87+
external,
88+
alias: Object.fromEntries(compatible_node_modules.map((id) => [id, `node:${id}`])),
89+
logLevel: 'silent'
90+
});
91+
92+
if (result.warnings.length > 0) {
93+
const formatted = await esbuild.formatMessages(result.warnings, {
94+
kind: 'warning',
95+
color: true
96+
});
97+
98+
console.error(formatted.join('\n'));
99+
}
100+
} catch (error) {
101+
for (const e of error.errors) {
102+
for (const node of e.notes) {
103+
const match =
104+
/The package "(.+)" wasn't found on the file system but is built into node/.exec(
105+
node.text
106+
);
107+
if (match) {
108+
let id = match[1];
109+
if (!id.startsWith('node:')) id = `node:${id}`;
110+
111+
node.text = `Cannot use "${id}" when deploying to Cloudflare.`;
112+
}
113+
}
114+
}
115+
116+
const formatted = await esbuild.formatMessages(error.errors, {
117+
kind: 'error',
118+
color: true
119+
});
120+
121+
console.error(formatted.join('\n'));
122+
123+
throw new Error(
124+
`Bundling with esbuild failed with ${error.errors.length} ${
125+
error.errors.length === 1 ? 'error' : 'errors'
126+
}`
127+
);
128+
}
89129
}
90130
};
91131
}

0 commit comments

Comments
 (0)