From 6a924660ac2cc37e98fac896cd1f675061d2aba0 Mon Sep 17 00:00:00 2001 From: Jacob Mischka Date: Wed, 29 Mar 2023 13:32:15 -0500 Subject: [PATCH] Undo "node16" module resolution, manually attempt both with import_ This basically will attempt CJS with `require()` and ESM with `import()` separately instead of doing both with `import()`. While `import()` does support both, it gets more complicated when trying to load TS files with ts-node, which requires specific loader config instead of working out of the box. --- package.json | 3 +- src/classes/IntervalClient.ts | 4 +- src/utils/fileActionLoader.ts | 80 ++++++++++++++++++++++------------- tsconfig.json | 1 - 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index bbb0ff3..d30b874 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@interval/sdk", - "version": "1.0.0-dev0", + "version": "1.0.0-dev1", "description": "The frontendless framework for high growth companies. Interval automatically generates apps by inlining the UI in your backend code. It's a faster and more maintainable way to build internal tools, rapid prototypes, and more.", "homepage": "https://interval.com", "repository": { @@ -24,6 +24,7 @@ "dev": "run(){ yarn build:envoy && nodemon --watch src -e ts src/examples/${1:-basic}/index.ts; }; run" }, "dependencies": { + "@brillout/import": "^0.2.2", "cross-fetch": "^3.1.5", "evt": "^2.4.10", "superjson": "^1.9.1", diff --git a/src/classes/IntervalClient.ts b/src/classes/IntervalClient.ts index 255162b..4867948 100644 --- a/src/classes/IntervalClient.ts +++ b/src/classes/IntervalClient.ts @@ -226,7 +226,7 @@ export default class IntervalClient { if (typeof window === 'undefined' && this.#config.routesDirectory) { try { const { loadRoutesFromFileSystem } = await import( - '../utils/fileActionLoader.js' + '../utils/fileActionLoader' ) fileSystemRoutes = await loadRoutesFromFileSystem( this.#config.routesDirectory, @@ -826,7 +826,7 @@ export default class IntervalClient { switch (inputs.type) { case 'offer': { const { DataChannelConnection } = await import( - './DataChannelConnection.js' + './DataChannelConnection' ) const iceConfig = await this.#interval.fetchIceConfig() diff --git a/src/utils/fileActionLoader.ts b/src/utils/fileActionLoader.ts index bb1b5da..2bf5313 100644 --- a/src/utils/fileActionLoader.ts +++ b/src/utils/fileActionLoader.ts @@ -3,6 +3,7 @@ */ import path from 'path' import fsRoot from 'fs' +import { import_ } from '@brillout/import' import Action from '../classes/Action' import Page from '../classes/Page' @@ -28,43 +29,62 @@ async function loadFolder(currentDirectory: string, logger: Logger) { const ext = path.extname(file) const slug = path.basename(file, ext || undefined) + + const attemptLoadRoute = (fileExports: any) => { + if (slug === 'index') { + if ('default' in fileExports) { + let defaultExport = fileExports.default + if ('default' in defaultExport) { + defaultExport = defaultExport.default + } + + if (defaultExport instanceof Page) { + Object.assign(defaultExport.routes, router.routes) + router = defaultExport + } else { + logger.warn( + `Default export of ${fullPath} is not a Page class instance, skipping.` + ) + } + } + } else { + if ('default' in fileExports) { + let defaultExport = fileExports.default + if ('default' in defaultExport) { + defaultExport = defaultExport.default + } + + if ( + defaultExport instanceof Page || + defaultExport instanceof Action + ) { + router.routes[slug] = defaultExport + } else { + logger.warn( + `Default export of ${fullPath} is not a Page or Action class instance, skipping.` + ) + } + } + } + } + if ((await fs.stat(fullPath)).isDirectory()) { const group = await loadFolder(path.join(currentDirectory, slug), logger) router.routes[slug] = group - } else if (ext === '.ts' || ext === '.js') { + } else if (ext === '.ts' || ext === '.js' || ext === '.mjs') { try { - const fileExports = await import(fullPath) - - if (slug === 'index') { - if ('default' in fileExports) { - if (fileExports.default instanceof Page) { - Object.assign(fileExports.default.routes, router.routes) - router = fileExports.default - } else { - logger.warn( - `Default export of ${fullPath} is not a Page class instance, skipping.` - ) - } - } - } else { - if ('default' in fileExports) { - if ( - fileExports.default instanceof Page || - fileExports.default instanceof Action - ) { - router.routes[slug] = fileExports.default - } else { - logger.warn( - `Default export of ${fullPath} is not a Page or Action class instance, skipping.` - ) - } - } - } + attemptLoadRoute(await import(fullPath)) } catch (err) { - logger.warn( - `Failed loading file at ${fullPath} as module, skipping.`, + logger.debug( + `Failed loading file at ${fullPath} as CommonJS, trying again as module.`, err ) + + try { + attemptLoadRoute(await import_(fullPath)) + } catch (err) { + logger.debug(`Failed loading file at ${fullPath}, skipping.`, err) + } } } } diff --git a/tsconfig.json b/tsconfig.json index 105bea0..3333f64 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,6 @@ "target": "ES2019", "declaration": true, "esModuleInterop": true, - "moduleResolution": "Node16", "strict": true, "strictNullChecks": true, "rootDir": "./src"