Skip to content

Commit c16111d

Browse files
committed
refa: move node-specific logic to cli package
1 parent c9f5a98 commit c16111d

File tree

8 files changed

+42
-86
lines changed

8 files changed

+42
-86
lines changed

packages/cordis/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"@cordisjs/plugin-logger": "^1.0.1",
7171
"cac": "^6.7.14",
7272
"cosmokit": "^1.8.0",
73+
"dotenv": "^16.4.7",
7374
"kleur": "^4.1.5",
7475
"schemastery": "^3.15.0"
7576
}

packages/cordis/src/worker/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { Context } from 'cordis'
33
import Loader from '@cordisjs/plugin-loader'
44
import Logger from '@cordisjs/plugin-logger'
55
import * as daemon from './daemon.ts'
6+
import * as dotenv from 'dotenv'
7+
import { readFile } from 'node:fs/promises'
8+
import { join } from 'node:path'
69

710
export interface Options extends Loader.Config {
811
execArgv?: string[]
@@ -11,6 +14,19 @@ export interface Options extends Loader.Config {
1114
}
1215

1316
export async function start(options: Options) {
17+
// load .env files
18+
const override = {}
19+
const envFiles = ['.env', '.env.local']
20+
for (const filename of envFiles) {
21+
try {
22+
const raw = await readFile(join(process.cwd(), filename), 'utf8')
23+
Object.assign(override, dotenv.parse(raw))
24+
} catch {}
25+
}
26+
for (const key in override) {
27+
process.env[key] = override[key]
28+
}
29+
1430
const ctx = new Context()
1531
if (options.logger) await ctx.plugin(Logger, options.logger)
1632
if (options.daemon) await ctx.plugin(daemon, options.daemon)

packages/loader/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
},
4949
"dependencies": {
5050
"cosmokit": "^1.8.0",
51-
"dotenv": "^16.4.7",
5251
"js-yaml": "^4.1.0"
5352
}
5453
}

packages/loader/src/config/file.ts renamed to packages/loader/src/file.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { access, constants, readFile, rename, writeFile } from 'node:fs/promises
22
import { pathToFileURL } from 'node:url'
33
import { remove } from 'cosmokit'
44
import * as yaml from 'js-yaml'
5-
import { EntryOptions } from './entry.ts'
5+
import { EntryOptions } from './config/entry.ts'
6+
import { JsExpr } from './config/utils.ts'
67
import { ImportTree } from './import.ts'
7-
import { JsExpr } from './utils.ts'
88
import { dirname } from 'node:path'
99

1010
export const schema = yaml.JSON_SCHEMA.extend(JsExpr)

packages/loader/src/config/import.ts renamed to packages/loader/src/import.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { Context, Service } from '@cordisjs/core'
22
import { dirname, extname, resolve } from 'node:path'
33
import { readdir, stat } from 'node:fs/promises'
44
import { fileURLToPath } from 'node:url'
5-
import { EntryTree } from './tree.ts'
5+
import { EntryTree } from './config/tree.ts'
66
import { LoaderFile } from './file.ts'
7-
import Loader from '../loader.ts'
7+
import Loader from './loader.ts'
88

99
export class ImportTree<C extends Context = Context> extends EntryTree<C> {
1010
public file!: LoaderFile

packages/loader/src/index.ts

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +0,0 @@
1-
import { Module } from 'node:module'
2-
import { pathToFileURL } from 'node:url'
3-
import { readFile } from 'node:fs/promises'
4-
import { join } from 'node:path'
5-
import { Service } from '@cordisjs/core'
6-
import { Loader } from './loader.ts'
7-
import * as dotenv from 'dotenv'
8-
import { ModuleLoader } from './internal.ts'
9-
10-
export * from './internal.ts'
11-
export * from './loader.ts'
12-
13-
type ModuleLoad = (request: string, parent: Module, isMain: boolean) => any
14-
15-
namespace NodeLoader {
16-
export interface Config extends Loader.Config {}
17-
}
18-
19-
class NodeLoader extends Loader {
20-
static readonly exitCode = 51
21-
22-
public internal = ModuleLoader.fromInternal()
23-
24-
async* [Service.init]() {
25-
const originalLoad: ModuleLoad = Module['_load']
26-
Module['_load'] = ((request, parent, isMain) => {
27-
try {
28-
return originalLoad(request, parent, isMain)
29-
} catch (e: any) {
30-
if (e.code !== 'ERR_REQUIRE_ESM' || !this.internal) throw e
31-
try {
32-
// TODO support hmr for cjs-esm interop
33-
const result = this.internal.resolveSync(request, pathToFileURL(parent.filename).href, {})
34-
const job = result?.format === 'module'
35-
? this.internal.loadCache.get(result.url)
36-
: undefined
37-
if (job) return job?.module?.getNamespace()
38-
} catch {
39-
throw e
40-
}
41-
}
42-
}) as ModuleLoad
43-
44-
// load .env files
45-
const override = {}
46-
const envFiles = ['.env', '.env.local']
47-
for (const filename of envFiles) {
48-
try {
49-
const raw = await readFile(join(process.cwd(), filename), 'utf8')
50-
Object.assign(override, dotenv.parse(raw))
51-
} catch {}
52-
}
53-
for (const key in override) {
54-
process.env[key] = override[key]
55-
}
56-
57-
yield* super[Service.init]()
58-
}
59-
60-
exit(code = NodeLoader.exitCode) {
61-
const body = JSON.stringify(this.envData)
62-
process.send?.({ type: 'shared', body }, (err: any) => {
63-
if (err) this.ctx.emit(this.ctx, 'internal/error', 'failed to send shared data')
64-
this.ctx.root.logger?.('loader').info('trigger full reload')
65-
process.exit(code)
66-
})
67-
}
68-
}
69-
70-
export default NodeLoader

packages/loader/src/internal.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,15 @@ export namespace ModuleLoader {
5757
(require) => require('internal/process/esm_loader').esmLoader,
5858
]
5959

60+
let _cachedLoader: ModuleLoader | undefined
61+
6062
export function fromInternal() {
6163
if (!process.execArgv.includes('--expose-internals')) return
64+
if (_cachedLoader) return _cachedLoader
6265
const require = createRequire(import.meta.url)
6366
for (const loader of internalLoaders) {
6467
try {
65-
return loader(require)
68+
return _cachedLoader = loader(require)
6669
} catch {}
6770
}
6871
}

packages/loader/src/loader.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ import type {} from '@cordisjs/plugin-logger'
33
import { defineProperty, Dict, isNullable } from 'cosmokit'
44
import { ModuleLoader } from './internal.ts'
55
import { Entry, EntryOptions } from './config/entry.ts'
6-
import { LoaderFile } from './config/file.ts'
7-
import { ImportTree } from './config/import.ts'
6+
import { EntryTree } from './config/tree.ts'
87
import isolate from './config/isolate.ts'
8+
import { LoaderFile } from './loader.ts'
99

1010
export * from './config/entry.ts'
11-
export * from './config/file.ts'
1211
export * from './config/group.ts'
13-
export * from './config/import.ts'
1412
export * from './config/isolate.ts'
1513
export * from './config/tree.ts'
14+
export * from './file.ts'
15+
export * from './import.ts'
1616

1717
declare module '@cordisjs/core' {
1818
interface Events {
@@ -49,7 +49,7 @@ export namespace Loader {
4949
}
5050
}
5151

52-
export abstract class Loader<C extends Context = Context> extends ImportTree<C> {
52+
export abstract class Loader<C extends Context = Context> extends EntryTree<C> {
5353
declare [Service.config]: Loader.Intercept
5454

5555
public envData = process.env.CORDIS_SHARED
@@ -126,10 +126,10 @@ export abstract class Loader<C extends Context = Context> extends ImportTree<C>
126126
ctx.plugin(isolate)
127127
}
128128

129-
async* [Service.init]() {
130-
await this.init(process.cwd(), this.config)
131-
yield* super[Service.init]()
132-
}
129+
// async* [Service.init]() {
130+
// await this.init(process.cwd(), this.config)
131+
// yield* super[Service.init]()
132+
// }
133133

134134
[Service.check]() {
135135
const config: Loader.Intercept = Service.prototype[Service.resolveConfig].call(this)
@@ -151,7 +151,14 @@ export abstract class Loader<C extends Context = Context> extends ImportTree<C>
151151
}
152152
}
153153

154-
exit() {}
154+
exit() {
155+
// const body = JSON.stringify(this.envData)
156+
// process.send?.({ type: 'shared', body }, (err: any) => {
157+
// if (err) this.ctx.emit(this.ctx, 'internal/error', 'failed to send shared data')
158+
// this.ctx.root.logger?.('loader').info('trigger full reload')
159+
// process.exit(code)
160+
// })
161+
}
155162

156163
unwrapExports(exports: any) {
157164
if (isNullable(exports)) return exports

0 commit comments

Comments
 (0)