|
| 1 | +import fs from 'node:fs'; |
| 2 | +import path from 'node:path'; |
1 | 3 | import url from 'node:url'; |
2 | 4 | import type { Configuration, ConfigurationObject } from '../../types.js'; |
3 | 5 |
|
| 6 | +// logic based on crossImport from `rspack-cli` |
| 7 | +// reference: https://github.com/web-infra-dev/rspack/blob/b16a723d974231eb5a39fcbfd3258b283be8b3c9/packages/rspack-cli/src/utils/crossImport.ts |
| 8 | + |
| 9 | +const readPackageUp = (cwd: string) => { |
| 10 | + let currentDir = path.resolve(cwd); |
| 11 | + let packageJsonPath = path.join(currentDir, 'package.json'); |
| 12 | + |
| 13 | + while (!fs.existsSync(packageJsonPath)) { |
| 14 | + const parentDir = path.dirname(currentDir); |
| 15 | + if (parentDir === currentDir) return null; |
| 16 | + currentDir = parentDir; |
| 17 | + packageJsonPath = path.join(currentDir, 'package.json'); |
| 18 | + } |
| 19 | + |
| 20 | + try { |
| 21 | + const packageJson = fs.readFileSync(packageJsonPath, 'utf8'); |
| 22 | + return JSON.parse(packageJson) as { type?: 'module' }; |
| 23 | + } catch { |
| 24 | + return null; |
| 25 | + } |
| 26 | +}; |
| 27 | + |
| 28 | +const isEsmFile = (filePath: string) => { |
| 29 | + if (filePath.endsWith('.mjs')) return true; |
| 30 | + if (filePath.endsWith('.cjs')) return false; |
| 31 | + const packageJson = readPackageUp(path.dirname(filePath)); |
| 32 | + return packageJson?.type === 'module'; |
| 33 | +}; |
| 34 | + |
4 | 35 | export async function loadProjectConfig<C extends ConfigurationObject>( |
5 | 36 | configFilePath: string |
6 | 37 | ): Promise<Configuration<C>> { |
7 | 38 | let config: Configuration<C>; |
8 | 39 |
|
9 | | - try { |
| 40 | + if (isEsmFile(configFilePath)) { |
10 | 41 | const { href: fileUrl } = url.pathToFileURL(configFilePath); |
11 | 42 | config = await import(fileUrl); |
12 | | - } catch { |
| 43 | + } else { |
13 | 44 | config = require(configFilePath); |
14 | 45 | } |
15 | 46 |
|
|
0 commit comments