diff --git a/src/codegen/bundle-modules.ts b/src/codegen/bundle-modules.ts index 8cb8c59986b8f4..b98828c5e5b8b0 100644 --- a/src/codegen/bundle-modules.ts +++ b/src/codegen/bundle-modules.ts @@ -81,6 +81,16 @@ for (let i = 0; i < moduleList.length; i++) { try { let input = fs.readFileSync(path.join(BASE, moduleList[i]), "utf8"); + // NOTE: internal modules are parsed as functions. They must use ESM to export and require to import. + // TODO: Bother @paperdave and have him check for module.exports, and create/return a module object if detected. + if (!/\bexport\s+(?:function|class|const|default|{)/.test(input)) { + if (input.includes("module.exports")) { + throw new Error("Cannot use CommonJS module.exports in ESM modules. Use `export default { ... }` instead."); + } else { + throw new Error("Internal modules must have an `export default` statement."); + } + } + const scannedImports = t.scanImports(input); for (const imp of scannedImports) { if (imp.kind === "import-statement") { @@ -407,7 +417,7 @@ writeIfNotChanged( // In this enum are represented as \`(1 << 9) & id\` InternalModuleRegistryFlag = 1 << 9, ${moduleList.map((id, n) => ` ${idToEnumName(id)} = ${(1 << 9) | n},`).join("\n")} - + // Native modules run through the same system, but with different underlying initializers. // They also have bit 10 set to differentiate them from JS builtins. NativeModuleFlag = (1 << 10) | (1 << 9), diff --git a/src/codegen/internal-module-registry-scanner.ts b/src/codegen/internal-module-registry-scanner.ts index 71458fd2e27c11..019040eed676be 100644 --- a/src/codegen/internal-module-registry-scanner.ts +++ b/src/codegen/internal-module-registry-scanner.ts @@ -74,7 +74,7 @@ export function createInternalModuleRegistry(basedir: string) { const found = moduleList.indexOf(path.relative(basedir, relativeMatch).replaceAll("\\", "/")); if (found === -1) { throw new Error( - `Builtin Bundler: "${specifier}" cannot be imported here because it doesn't get a module ID. Only files in "src/js" besides "src/js/builtins" can be used here. Note that the 'node:' or 'bun:' prefix is required here. `, + `Builtin Bundler: "${specifier}" cannot be imported from "${from}" because it doesn't get a module ID. Only files in "src/js" besides "src/js/builtins" can be used here. Note that the 'node:' or 'bun:' prefix is required here. `, ); } return codegenRequireId(`${found}/*${path.relative(basedir, relativeMatch)}*/`);