| 57 | * @returns {Promise<Map<number, string[]>>} internal-error messages keyed by entry index |
| 58 | */ |
| 59 | const buildBatch = (inputs, mode) => |
| 60 | new Promise((resolve) => { |
| 61 | const mfs = createFsFromVolume(new Volume()); |
| 62 | mfs.mkdirSync("/src", { recursive: true }); |
| 63 | /** @type {Record<string, string>} */ |
| 64 | const entry = {}; |
| 65 | for (const [i, input] of inputs.entries()) { |
| 66 | mfs.writeFileSync(`/src/c${i}.css`, input); |
| 67 | entry[`c${i}`] = `./c${i}.css`; |
| 68 | } |
| 69 | const compiler = webpack({ |
| 70 | context: "/src", |
| 71 | mode, |
| 72 | entry, |
| 73 | output: { |
| 74 | path: "/out", |
| 75 | filename: "[name].js", |
| 76 | cssFilename: "[name].css" |
| 77 | }, |
| 78 | target: "web", |
| 79 | experiments: { css: true }, |
| 80 | module: { parser: { css: { import: false, url: false } } } |
| 81 | }); |
| 82 | compiler.inputFileSystem = mfs; |
| 83 | compiler.outputFileSystem = mfs; |
| 84 | compiler.run((err, stats) => { |
| 85 | /** @type {Map<number, string[]>} */ |
| 86 | const internalByEntry = new Map(); |
| 87 | /** |
| 88 | * @param {number} i entry index |
| 89 | * @param {string} line message |
| 90 | */ |
| 91 | const add = (i, line) => { |
| 92 | if (!internalByEntry.has(i)) internalByEntry.set(i, []); |
| 93 | internalByEntry.get(i).push(line); |
| 94 | }; |
| 95 | if (err) { |
| 96 | // Compiler-level throw can't be attributed to one entry; mark all. |
| 97 | const line = String(err.message).split("\n")[0].slice(0, 160); |
| 98 | for (const i of inputs.keys()) add(i, line); |
| 99 | resolve(internalByEntry); |
| 100 | return; |
| 101 | } |
| 102 | const json = stats.toJson({ errors: true, warnings: true }); |
| 103 | for (const item of [...json.errors, ...json.warnings]) { |
| 104 | if (!INTERNAL.test(item.message)) continue; |
| 105 | const line = item.message.split("\n")[0].slice(0, 160); |
| 106 | const match = /c(\d+)\.css/.exec(item.moduleName || ""); |
| 107 | if (match) add(Number(match[1]), line); |
| 108 | else for (const i of inputs.keys()) add(i, line); |
| 109 | } |
| 110 | compiler.close(() => resolve(internalByEntry)); |
| 111 | }); |
| 112 | }); |
| 113 | |
| 114 | const cases = |
| 115 | fs.existsSync(casesDir) && fs.readdirSync(casesDir).length > 0 |