|
1 | 1 | import type { HardhatUserConfig } from "../types/config.js";
|
2 | 2 |
|
| 3 | +import path from "node:path"; |
3 | 4 | import { fileURLToPath, pathToFileURL } from "node:url";
|
4 | 5 |
|
5 | 6 | import { HardhatError } from "@nomicfoundation/hardhat-errors";
|
@@ -140,29 +141,56 @@ async function normalizeConfigPath(configPath: string): Promise<string> {
|
140 | 141 | */
|
141 | 142 | async function importConfigFileWithTsxFallback(configPath: string) {
|
142 | 143 | try {
|
143 |
| - return await import(configPath); |
144 |
| - } catch (error) { |
145 |
| - ensureError(error); |
| 144 | + try { |
| 145 | + return await import(configPath); |
| 146 | + } catch (error) { |
| 147 | + ensureError(error); |
146 | 148 |
|
147 |
| - if ( |
148 |
| - "code" in error && |
149 |
| - error.code === "ERR_UNKNOWN_FILE_EXTENSION" && |
150 |
| - configPath.endsWith(".ts") |
151 |
| - ) { |
152 |
| - const realPath = await getRealPath(fileURLToPath(configPath)); |
| 149 | + if ( |
| 150 | + "code" in error && |
| 151 | + error.code === "ERR_UNKNOWN_FILE_EXTENSION" && |
| 152 | + configPath.endsWith(".ts") |
| 153 | + ) { |
| 154 | + const realPath = await getRealPath(fileURLToPath(configPath)); |
153 | 155 |
|
154 |
| - if (compiledConfigFile.has(realPath)) { |
155 |
| - return compiledConfigFile.get(realPath); |
156 |
| - } |
| 156 | + if (compiledConfigFile.has(realPath)) { |
| 157 | + return compiledConfigFile.get(realPath); |
| 158 | + } |
| 159 | + |
| 160 | + const { tsImport } = await import("tsx/esm/api"); |
| 161 | + const config = await tsImport(configPath, import.meta.url); |
157 | 162 |
|
158 |
| - const { tsImport } = await import("tsx/esm/api"); |
159 |
| - const config = tsImport(configPath, import.meta.url); |
| 163 | + compiledConfigFile.set(realPath, config); |
160 | 164 |
|
161 |
| - compiledConfigFile.set(realPath, config); |
| 165 | + return config; |
| 166 | + } |
162 | 167 |
|
163 |
| - return config; |
| 168 | + throw error; |
164 | 169 | }
|
| 170 | + } catch (error) { |
| 171 | + ensureError(error); |
165 | 172 |
|
166 |
| - throw error; |
| 173 | + switch (error.name) { |
| 174 | + case "TransformError": |
| 175 | + const errors = error.message |
| 176 | + .split("\n") |
| 177 | + .filter((line) => line.includes(path.basename(configPath))) |
| 178 | + // For example: /.../hardhat.config.ts:86:5: ERROR: Expected "}" but found "\"community-plugin\"" |
| 179 | + .map((line) => line.split(":")) |
| 180 | + .map( |
| 181 | + ([_path, line, _char, _code, ...message]) => |
| 182 | + `* Syntax error in line ${line}: ${message.join(":").trim()}`, |
| 183 | + ); |
| 184 | + |
| 185 | + throw new HardhatError( |
| 186 | + HardhatError.ERRORS.CORE.GENERAL.INVALID_CONFIG_FILE, |
| 187 | + { |
| 188 | + configPath, |
| 189 | + errors: `\t${errors.join("\n\t")}`, |
| 190 | + }, |
| 191 | + ); |
| 192 | + default: |
| 193 | + throw error; |
| 194 | + } |
167 | 195 | }
|
168 | 196 | }
|
0 commit comments