-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: esbuild plugin for specifying node protocol import (#7)
## Why? Apply the node specifier to avoid conflicts with user imported polyfills. ## How? - Plugin to apply `node:` specifier to the imports - Pugin to stub unsupported modules ## Tickets? - [PLAT-955](https://linear.app/fleekxyz/issue/PLAT-955/investigate-user-issues-with-bundling) ## Contribution checklist? - [x] The commit messages are detailed - [x] The `build` command runs locally - [x] Assets or static content are linked and stored in the project - [x] You have manually tested - [x] You have provided tests ## Security checklist? - [x] Sensitive data has been identified and is being protected properly - [x] Injection has been prevented (parameterized queries, no eval or system calls) ## Preview? Optionally, provide the preview url here --------- Co-authored-by: Helder Oliveira <[email protected]>
- Loading branch information
1 parent
ffb4189
commit 19780f6
Showing
9 changed files
with
259 additions
and
152 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
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
File renamed without changes.
60 changes: 60 additions & 0 deletions
60
src/commands/functions/plugins/nodeProtocolImportSpecifier.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,60 @@ | ||
import { PluginBuild } from 'esbuild'; | ||
import fs from 'fs'; | ||
|
||
import { supportedRuntimeModules, unsupportedRuntimeModules } from '../runtimeModules'; | ||
|
||
const replaceLineByMatchRegExpr = ({ contents, moduleName }: { contents: string; moduleName: string }) => { | ||
const reImportSyntax = new RegExp(`import\\s*[\\w\\W]*?\\s*from\\s+["']${moduleName}["']`, 'g'); | ||
const reModuleName = new RegExp(`["']${moduleName}["']`, 'g'); | ||
const convention = `"node:${moduleName}"`; | ||
const lns = contents.split('\n'); | ||
const res = lns.map((ln) => { | ||
const shouldReplace = reImportSyntax.test(ln); | ||
|
||
if (!shouldReplace) { | ||
return ln; | ||
} | ||
|
||
return ln.replace(reModuleName, convention); | ||
}); | ||
|
||
return res.join('\n'); | ||
}; | ||
|
||
const applyNodeProtocolConvention = async ({ path }: { path: string }) => { | ||
const buffer = await fs.promises.readFile(path, 'utf8'); | ||
const contents = buffer.toString(); | ||
|
||
const output = [...supportedRuntimeModules, ...unsupportedRuntimeModules].reduce((acc, moduleName) => { | ||
return replaceLineByMatchRegExpr({ | ||
contents: acc, | ||
moduleName, | ||
}); | ||
}, contents); | ||
|
||
return { | ||
contents: output, | ||
}; | ||
}; | ||
|
||
export const nodeProtocolImportSpecifier = ({ onError }: { onError: () => void }) => ({ | ||
name: 'nodeProtocolImportSpecifier', | ||
setup(build: PluginBuild) { | ||
build.onLoad({ filter: /\.js$/ }, async ({ path }) => { | ||
try { | ||
const output = await applyNodeProtocolConvention({ | ||
path, | ||
}); | ||
|
||
return output; | ||
} catch (err) { | ||
onError(); | ||
} | ||
}); | ||
|
||
build.onResolve({ filter: /^node:/ }, (args) => ({ | ||
path: args.path, | ||
external: true, | ||
})); | ||
}, | ||
}); |
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,42 @@ | ||
import { OnResolveArgs, Plugin, PluginBuild } from 'esbuild'; | ||
|
||
import { unsupportedRuntimeModules } from '../runtimeModules'; | ||
|
||
const unsupportedModules = unsupportedRuntimeModules.map((it) => `node:${it}`); | ||
|
||
type ModuleCheckerArgs = { | ||
unsupportedModulesUsed: Set<string>; | ||
}; | ||
|
||
export const moduleChecker: (args: ModuleCheckerArgs) => Plugin = (args) => { | ||
const { unsupportedModulesUsed } = args; | ||
|
||
return { | ||
name: 'moduleChecker', | ||
setup: (build: PluginBuild) => { | ||
build.onLoad({ filter: /.*/, namespace: 'unsupported' }, (args) => { | ||
console.log('unsupported', args); | ||
|
||
return { | ||
contents: ` | ||
throw new Error('Unsupported module: ${args.path}'); | ||
`, | ||
loader: 'js', | ||
}; | ||
}); | ||
|
||
build.onResolve({ filter: /.*/ }, ({ path }: OnResolveArgs) => { | ||
if (unsupportedModules.includes(path) || unsupportedModules.includes(`node:${path}`)) { | ||
unsupportedModulesUsed.add(path); | ||
|
||
return { | ||
path, | ||
namespace: 'unsupported', | ||
}; | ||
} | ||
|
||
return null; | ||
}); | ||
}, | ||
}; | ||
}; |
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,55 @@ | ||
// Worker supported modules | ||
// due to environment constraints | ||
// optimized for edge computing | ||
export const supportedRuntimeModules = [ | ||
'buffer', | ||
'crypto', | ||
'domain', | ||
'events', | ||
'http', | ||
'https', | ||
'path', | ||
'punycode', | ||
'stream', | ||
'string_decoder', | ||
'url', | ||
'util', | ||
'zlib', | ||
]; | ||
|
||
export const unsupportedRuntimeModules = [ | ||
'assert/strict', | ||
'child_process', | ||
'cluster', | ||
'constants', | ||
'dgram', | ||
'diagnostics_channel', | ||
'dns', | ||
'fs', | ||
'fs/promises', | ||
'http2', | ||
'inspector', | ||
'module', | ||
'net', | ||
'os', | ||
'path/posix', | ||
'path/win32', | ||
'perf_hooks', | ||
'process', | ||
'querystring', | ||
'readline', | ||
'repl', | ||
'stream/promises', | ||
'stream/web', | ||
'sys', | ||
'timers', | ||
'timers/promises', | ||
'tls', | ||
'trace_events', | ||
'tty', | ||
'v8', | ||
'vm', | ||
'wasi', | ||
'webcrypto', | ||
'worker_threads', | ||
]; |
Oops, something went wrong.