-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: inline optional dependencies when bundling the server (#325)
Co-authored-by: James Anderson <james@eli.cx>
- Loading branch information
1 parent
da7f8d8
commit 0892679
Showing
9 changed files
with
80 additions
and
217 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@opennextjs/cloudflare": patch | ||
--- | ||
|
||
fix: inline optional dependencies when bundling the server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
153 changes: 0 additions & 153 deletions
153
packages/cloudflare/src/cli/build/patches/ast/optional-deps.spec.ts
This file was deleted.
Oops, something went wrong.
48 changes: 0 additions & 48 deletions
48
packages/cloudflare/src/cli/build/patches/ast/optional-deps.ts
This file was deleted.
Oops, something went wrong.
63 changes: 63 additions & 0 deletions
63
packages/cloudflare/src/cli/build/patches/plugins/optional-deps.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
/** | ||
* ESBuild plugin to handle optional dependencies. | ||
* | ||
* Optional dependencies might be installed by the application to support optional features. | ||
* | ||
* When an optional dependency is installed, it must be inlined in the bundle. | ||
* When it is not installed, the plugin swaps it for a throwing implementation. | ||
* | ||
* The plugin uses ESBuild built-in resolution to check if the dependency is installed. | ||
*/ | ||
|
||
import type { OnResolveResult, PluginBuild } from "esbuild"; | ||
|
||
export function handleOptionalDependencies(dependencies: string[]) { | ||
// Regex matching either a full module ("module") or a prefix ("module/...") | ||
const filter = new RegExp( | ||
`^(${dependencies.flatMap((name) => [`${name}$`, String.raw`${name}/`]).join("|")})` | ||
); | ||
|
||
const name = "optional-deps"; | ||
const marker = {}; | ||
const nsMissingDependency = `${name}-missing-dependency`; | ||
|
||
return { | ||
name, | ||
|
||
setup: async (build: PluginBuild) => { | ||
build.onResolve({ filter }, async ({ path, pluginData, ...options }): Promise<OnResolveResult> => { | ||
// Use ESBuild to resolve the dependency. | ||
// Because the plugin asks ESBuild to resolve the path we just received, | ||
// ESBuild will ask this plugin again. | ||
// We use a marker in the pluginData to break the loop. | ||
if (pluginData === marker) { | ||
return {}; | ||
} | ||
const result = await build.resolve(path, { | ||
...options, | ||
pluginData: marker, | ||
}); | ||
|
||
// ESBuild reports error when the dependency is not installed. | ||
// In such a case the OnLoad hook will inline a throwing implementation. | ||
if (result.errors.length > 0) { | ||
return { | ||
path: `/${path}`, | ||
namespace: nsMissingDependency, | ||
pluginData: { name: path }, | ||
}; | ||
} | ||
|
||
// Returns ESBuild resolution information when the dependency is installed. | ||
return result; | ||
}); | ||
|
||
// Replaces missing dependency with a throwing implementation. | ||
build.onLoad({ filter: /.*/, namespace: nsMissingDependency }, ({ pluginData }) => { | ||
return { | ||
contents: `throw new Error('Missing optional dependency "${pluginData.name}"')`, | ||
}; | ||
}); | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters