diff --git a/.gitignore b/.gitignore index d4a9853e..1d7e1191 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ -node_modules/ +node_modules coverage/ test/fixtures/custom-framework-app/node_modules/ test/fixtures/demo-app/node_modules/aliyun-egg/ !test/fixtures/demo-app/node_modules/aliyun-egg/node_modules/ +!test/fixtures/demo-app-esm/node_modules/ test/fixtures/ts/node_modules/aliyun-egg/ !test/fixtures/ts/node_modules/aliyun-egg/node_modules/ diff --git a/package.json b/package.json index 16d8226e..64fbff0f 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@eggjs/utils": "^4.1.2", "@oclif/core": "^4.2.0", "@types/mocha": "^10.0.10", + "@types/supertest": "^6.0.2", "c8": "^10.0.0", "detect-port": "^2.0.0", "egg-ts-helper": "^2.1.0", diff --git a/src/baseCommand.ts b/src/baseCommand.ts index 4e13f898..21205a1a 100644 --- a/src/baseCommand.ts +++ b/src/baseCommand.ts @@ -207,7 +207,7 @@ export abstract class BaseCommand extends Command { findPaths.unshift(flags.base); } flags.tscompiler = flags.tscompiler ?? 'ts-node/register'; - let tsNodeRegister = importResolve(flags.tscompiler, { + const tsNodeRegister = importResolve(flags.tscompiler, { paths: findPaths, }); flags.tscompiler = tsNodeRegister; @@ -215,12 +215,7 @@ export abstract class BaseCommand extends Command { // e.g.: dev command will execute egg loader to find configs and plugins // await importModule(tsNodeRegister); // let child process auto require ts-node too - if (this.isESM) { - tsNodeRegister = pathToFileURL(tsNodeRegister).href; - this.addNodeOptions(`--import ${tsNodeRegister}`); - } else { - this.addNodeOptions(`--require ${tsNodeRegister}`); - } + this.addNodeOptions(this.formatImportModule(tsNodeRegister)); // tell egg loader to load ts file // see https://github.com/eggjs/egg-core/blob/master/lib/loader/egg_loader.js#L443 this.env.EGG_TYPESCRIPT = 'true'; @@ -321,6 +316,13 @@ export abstract class BaseCommand extends Command { return requires; } + protected formatImportModule(modulePath: string) { + if (this.isESM) { + return `--import ${pathToFileURL(modulePath).href}`; + } + return `--require ${modulePath}`; + } + protected addNodeOptions(options: string) { if (this.env.NODE_OPTIONS) { if (!this.env.NODE_OPTIONS.includes(options)) { diff --git a/src/commands/dev.ts b/src/commands/dev.ts index 318edaa3..a7f1a261 100644 --- a/src/commands/dev.ts +++ b/src/commands/dev.ts @@ -1,6 +1,5 @@ import { debuglog } from 'node:util'; import { Flags } from '@oclif/core'; -import { pathToFileURL } from 'node:url'; import { getConfig, getFrameworkPath } from '@eggjs/utils'; import { detect } from 'detect-port'; import { getSourceFilename } from '../utils.js'; @@ -44,13 +43,8 @@ export default class Dev extends BaseCommand { const requires = await this.formatRequires(); const execArgv: string[] = []; for (const r of requires) { - if (this.isESM) { - execArgv.push('--import'); - execArgv.push(pathToFileURL(r).href); - } else { - execArgv.push('--require'); - execArgv.push(r); - } + const imports = this.formatImportModule(r).split(' '); + execArgv.push(...imports); } await this.forkNode(serverBin, args, { execArgv }); } diff --git a/test/commands/dev.test.ts b/test/commands/dev.test.ts index c26d2505..9632e667 100644 --- a/test/commands/dev.test.ts +++ b/test/commands/dev.test.ts @@ -11,7 +11,7 @@ describe('test/commands/dev.test.ts', () => { const eggBin = path.join(getRootDirname(), 'bin/run.js'); const cwd = getFixtures('demo-app'); - it('should startCluster success', () => { + it('should startCluster success on CommonJS', () => { return coffee.fork(eggBin, [ 'dev' ], { cwd, // env: { NODE_DEBUG: 'egg-bin*' }, @@ -25,6 +25,23 @@ describe('test/commands/dev.test.ts', () => { .end(); }); + it('should startCluster success on ESM', () => { + const cwd = getFixtures('demo-app-esm'); + const hook = path.join(cwd, 'hook.js'); + return coffee.fork(eggBin, [ 'dev', '-r', hook ], { + cwd, + }) + // .debug() + .expect('stdout', /start hook success/) + .expect('stdout', /'--import'/) + .expect('stdout', /"workers":1/) + .expect('stdout', /"baseDir":".*?demo-app-esm"/) + .expect('stdout', /"framework":".*?aliyun-egg"/) + .expect('stdout', /NODE_ENV: development/) + .expect('code', 0) + .end(); + }); + it('should dev start with custom NODE_ENV', () => { return coffee.fork(eggBin, [ 'dev' ], { cwd, env: { NODE_ENV: 'prod' } }) .debug() @@ -137,7 +154,7 @@ describe('test/commands/dev.test.ts', () => { it('should support --require', () => { const script = getFixtures('require-script'); return coffee.fork(eggBin, [ 'dev', '--require', script ], { cwd }) - // .debug() + .debug() .expect('stdout', /hey, you require me by --require/) .expect('code', 0) .end(); @@ -147,7 +164,7 @@ describe('test/commands/dev.test.ts', () => { return coffee.fork(eggBin, [ 'dev' ], { cwd: getFixtures('egg-require'), }) - // .debug() + .debug() .expect('stdout', /hey, you require me by --require/) .expect('code', 0) .end(); diff --git a/test/commands/test.test.ts b/test/commands/test.test.ts index 151fec7a..dde6a6e4 100644 --- a/test/commands/test.test.ts +++ b/test/commands/test.test.ts @@ -11,7 +11,7 @@ describe('test/commands/test.test.ts', () => { describe('egg-bin test', () => { it('should success js', () => { return coffee.fork(eggBin, [ 'test' ], { cwd }) - // .debug() + .debug() .expect('stdout', /should success/) .expect('stdout', /a\.test\.js/) .expect('stdout', /b\/b\.test\.js/) @@ -20,6 +20,22 @@ describe('test/commands/test.test.ts', () => { .end(); }); + it('should success when no changed files', () => { + return coffee.fork(eggBin, [ 'test', '-c' ], { cwd }) + // .debug() + .expect('stdout', /No changed test files/) + .expect('code', 0) + .end(); + }); + + it('should fail when baseDir not exists', () => { + return coffee.fork(eggBin, [ 'test', '--base', path.join(cwd, 'not-exists') ], { cwd }) + // .debug() + .expect('stderr', /baseDir: .+ not exists/) + .expect('code', 1) + .end(); + }); + it('should success on ts', async () => { const cwd = getFixtures('example-ts'); await coffee.fork(eggBin, [ 'test' ], { cwd }) diff --git a/test/fixtures/demo-app-esm/hook.js b/test/fixtures/demo-app-esm/hook.js new file mode 100644 index 00000000..c9b05c2d --- /dev/null +++ b/test/fixtures/demo-app-esm/hook.js @@ -0,0 +1 @@ +console.log('start hook success'); diff --git a/test/fixtures/demo-app-esm/node_modules2/aliyun-egg/index.js b/test/fixtures/demo-app-esm/node_modules/aliyun-egg/index.js similarity index 85% rename from test/fixtures/demo-app-esm/node_modules2/aliyun-egg/index.js rename to test/fixtures/demo-app-esm/node_modules/aliyun-egg/index.js index dc41c309..b461d1c5 100644 --- a/test/fixtures/demo-app-esm/node_modules2/aliyun-egg/index.js +++ b/test/fixtures/demo-app-esm/node_modules/aliyun-egg/index.js @@ -1,6 +1,4 @@ -'use strict'; - -exports.startCluster = options => { +export function startCluster(options) { console.log('options: %j', options); if (process.execArgv.length) { console.log('process.execArgv:', process.execArgv); diff --git a/test/fixtures/demo-app-esm/node_modules2/aliyun-egg/package.json b/test/fixtures/demo-app-esm/node_modules/aliyun-egg/package.json similarity index 72% rename from test/fixtures/demo-app-esm/node_modules2/aliyun-egg/package.json rename to test/fixtures/demo-app-esm/node_modules/aliyun-egg/package.json index 4e36e661..1f6c956f 100644 --- a/test/fixtures/demo-app-esm/node_modules2/aliyun-egg/package.json +++ b/test/fixtures/demo-app-esm/node_modules/aliyun-egg/package.json @@ -2,5 +2,6 @@ "name": "aliyun-egg", "dependencies": { "egg": "*" - } + }, + "type": "module" } diff --git a/test/fixtures/demo-app-esm/package.json b/test/fixtures/demo-app-esm/package.json index 0854654a..40f64fd1 100644 --- a/test/fixtures/demo-app-esm/package.json +++ b/test/fixtures/demo-app-esm/package.json @@ -2,5 +2,6 @@ "name": "demo-app", "egg": { "framework": "aliyun-egg" - } + }, + "type": "module" }