Skip to content

Commit 0009dd9

Browse files
committed
fix: remove getJSON: true option in favor of only callback
1 parent e97b4c3 commit 0009dd9

File tree

6 files changed

+209
-86
lines changed

6 files changed

+209
-86
lines changed

README.md

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,7 @@ type modules =
327327
| "dashesOnly"
328328
| ((name: string) => string);
329329
exportOnlyLocals: boolean;
330-
getJSON:
331-
| string
332-
| ((resourcePath: string, json: object, outputPath: string) => any);
330+
getJSON: (resourcePath: string, json: object) => any;
333331
};
334332
```
335333

@@ -595,7 +593,7 @@ module.exports = {
595593
namedExport: true,
596594
exportLocalsConvention: "camelCase",
597595
exportOnlyLocals: false,
598-
getJSON: false,
596+
getJSON: (resourcePath, json) => {},
599597
},
600598
},
601599
},
@@ -1381,25 +1379,41 @@ module.exports = {
13811379
Type:
13821380

13831381
```ts
1384-
type getJSON =
1385-
| boolean
1386-
| ((resourcePath: string, json: object, outputPath: string) => any);
1382+
type getJSON = (resourcePath: string, json: object) => any;
13871383
```
13881384

13891385
Default: `undefined`
13901386

1391-
Enables the outputting of the CSS modules mapping JSON. This can be omitted or set to a falsy value to disable any output.
1387+
Enables a callback to output the CSS modules mapping JSON. The callback is invoked with two arguments:
13921388

1393-
###### `boolean`
1389+
- `resourcePath`: the absolutely path of the original resource, e.g., /foo/bar/baz.css
1390+
- `json`: the CSS modules map object, e.g.,
13941391

1395-
Possible values:
1392+
```
1393+
/* baz.css */
13961394
1397-
- `true` - writes a JSON file next located in the same directory as the loaded resource file. For example, given a resource file located at /foo/bar/baz.css, this would write the CSS modules mapping JSON to /foo/bar/baz.css.json
1398-
- `false` - disables CSS modules mapping JSON output
1395+
.a {
1396+
background-color: aliceblue;
1397+
}
1398+
1399+
.b {
1400+
background-color: burlywood;
1401+
}
1402+
```
1403+
1404+
`json` will be something like the following (depending on your other `modules` settings):
1405+
1406+
```
1407+
{
1408+
"a": "a__uRkh1",
1409+
"b": "b__pjFcy"
1410+
}
1411+
```
13991412

14001413
**webpack.config.js**
14011414

14021415
```js
1416+
// supports a synchronous callback
14031417
module.exports = {
14041418
module: {
14051419
rules: [
@@ -1408,22 +1422,24 @@ module.exports = {
14081422
loader: "css-loader",
14091423
options: {
14101424
modules: {
1411-
getJSON: true,
1425+
getJSON: (resourcePath, json) => {
1426+
// synchronously write a .json mapping file in the same directory as the resource
1427+
const outputPath = path.resolve(
1428+
path.dirname(resourcePath),
1429+
`${path.basename(resourcePath)}.json`
1430+
);
1431+
1432+
const fs = require("fs");
1433+
fs.writeFileSync(outputPath, JSON.stringify(json));
1434+
},
14121435
},
14131436
},
14141437
},
14151438
],
14161439
},
14171440
};
1418-
```
1419-
1420-
###### `function`
1421-
1422-
Enables custom handling of the CSS modules mapping JSON output. The return value of the function is not used for anything internally and is only intended to customize output.
14231441

1424-
**webpack.config.js**
1425-
1426-
```js
1442+
// same as above, just asynchronous
14271443
module.exports = {
14281444
module: {
14291445
rules: [
@@ -1432,10 +1448,14 @@ module.exports = {
14321448
loader: "css-loader",
14331449
options: {
14341450
modules: {
1435-
getJSON: (resourcePath, json, outputPath) => {
1436-
// `resourcePath` is the original resource file path, e.g., /foo/bar/baz.css
1437-
// `json` is the CSS modules map
1438-
// `outputPath` is the expected output file path, e.g., /foo/bar/baz.css.json
1451+
getJSON: async (resourcePath, json) => {
1452+
const outputPath = path.resolve(
1453+
path.dirname(resourcePath),
1454+
`${path.basename(resourcePath)}.json`
1455+
);
1456+
1457+
const fsp = require("fs/promises");
1458+
await fsp.writeFile(outputPath, JSON.stringify(json));
14391459
},
14401460
},
14411461
},

src/index.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
stringifyRequest,
2828
warningFactory,
2929
syntaxErrorFactory,
30-
writeModulesMap,
3130
} from "./utils";
3231

3332
export default async function loader(content, map, meta) {
@@ -275,15 +274,19 @@ export default async function loader(content, map, meta) {
275274
isTemplateLiteralSupported
276275
);
277276

278-
try {
279-
const { getJSON } = options.modules;
280-
if (getJSON) {
281-
await writeModulesMap(getJSON, resourcePath, exports);
282-
}
283-
} catch (error) {
284-
callback(error);
277+
const { getJSON } = options.modules;
278+
if (typeof getJSON === "function") {
279+
try {
280+
const json = exports.reduce((acc, { name, value }) => {
281+
return { ...acc, [name]: value };
282+
}, {});
285283

286-
return;
284+
await getJSON(resourcePath, json);
285+
} catch (error) {
286+
callback(error);
287+
288+
return;
289+
}
287290
}
288291

289292
callback(null, `${importCode}${moduleCode}${exportCode}`);

src/options.json

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,9 @@
171171
"type": "boolean"
172172
},
173173
"getJSON": {
174-
"description": "Output CSS modules mapping to a JSON file or through a callback.",
174+
"description": "Output CSS modules mapping through a callback.",
175175
"link": "https://github.com/webpack-contrib/css-loader#getJSON",
176-
"anyOf": [
177-
{
178-
"type": "boolean"
179-
},
180-
{
181-
"instanceof": "Function"
182-
}
183-
]
176+
"instanceof": "Function"
184177
}
185178
}
186179
}

src/utils.js

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
import { fileURLToPath } from "url";
66
import path from "path";
7-
import fsp from "fs/promises";
87

98
import modulesValues from "postcss-modules-values";
109
import localByDefault from "postcss-modules-local-by-default";
@@ -1413,26 +1412,6 @@ function syntaxErrorFactory(error) {
14131412
return obj;
14141413
}
14151414

1416-
async function writeModulesMap(getJSON, resourcePath, exports) {
1417-
const json = exports.reduce((acc, { name, value }) => {
1418-
return { ...acc, [name]: value };
1419-
}, {});
1420-
1421-
const outputPath = path.resolve(
1422-
path.dirname(resourcePath),
1423-
`${path.basename(resourcePath)}.json`
1424-
);
1425-
1426-
if (getJSON === true) {
1427-
// If true, output a JSON CSS modules mapping file in the same directory as the resource
1428-
await fsp.writeFile(outputPath, JSON.stringify(json));
1429-
} else if (typeof getJSON === "function") {
1430-
// If function, call function with call getJSON with similar args as postcss-modules#getJSON
1431-
// https://github.com/madyankin/postcss-modules/tree/master?tab=readme-ov-file#saving-exported-classes
1432-
getJSON(resourcePath, json, outputPath);
1433-
}
1434-
}
1435-
14361415
export {
14371416
normalizeOptions,
14381417
shouldUseModulesPlugins,
@@ -1460,5 +1439,4 @@ export {
14601439
defaultGetLocalIdent,
14611440
warningFactory,
14621441
syntaxErrorFactory,
1463-
writeModulesMap,
14641442
};

test/__snapshots__/modules-option.test.js.snap

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,144 @@ Array [
11911191

11921192
exports[`"modules" option should invoke the custom getJSON function with getJSON as a function: warnings 1`] = `Array []`;
11931193

1194+
exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: errors 1`] = `Array []`;
1195+
1196+
exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: mapping 1`] = `
1197+
Object {
1198+
"a": "RT7ktT7mB7tfBR25sJDZ",
1199+
"b": "IZmhTnK9CIeu6ww6Zjbv",
1200+
"c": "PV11nPFlF7mzEgCXkQw4",
1201+
}
1202+
`;
1203+
1204+
exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: module 1`] = `
1205+
"// Imports
1206+
import ___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___ from \\"../../../../src/runtime/noSourceMaps.js\\";
1207+
import ___CSS_LOADER_API_IMPORT___ from \\"../../../../src/runtime/api.js\\";
1208+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___);
1209+
// Module
1210+
___CSS_LOADER_EXPORT___.push([module.id, \`.RT7ktT7mB7tfBR25sJDZ {
1211+
background-color: aliceblue;
1212+
}
1213+
1214+
.IZmhTnK9CIeu6ww6Zjbv {
1215+
background-color: burlywood;
1216+
}
1217+
1218+
.PV11nPFlF7mzEgCXkQw4 {
1219+
background-color: chartreuse;
1220+
}
1221+
1222+
.d {
1223+
background-color: darkgoldenrod
1224+
}
1225+
\`, \\"\\"]);
1226+
// Exports
1227+
___CSS_LOADER_EXPORT___.locals = {
1228+
\\"a\\": \`RT7ktT7mB7tfBR25sJDZ\`,
1229+
\\"b\\": \`IZmhTnK9CIeu6ww6Zjbv\`,
1230+
\\"c\\": \`PV11nPFlF7mzEgCXkQw4\`
1231+
};
1232+
export default ___CSS_LOADER_EXPORT___;
1233+
"
1234+
`;
1235+
1236+
exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: result 1`] = `
1237+
Array [
1238+
Array [
1239+
"./modules/getJSON/source.css",
1240+
".RT7ktT7mB7tfBR25sJDZ {
1241+
background-color: aliceblue;
1242+
}
1243+
1244+
.IZmhTnK9CIeu6ww6Zjbv {
1245+
background-color: burlywood;
1246+
}
1247+
1248+
.PV11nPFlF7mzEgCXkQw4 {
1249+
background-color: chartreuse;
1250+
}
1251+
1252+
.d {
1253+
background-color: darkgoldenrod
1254+
}
1255+
",
1256+
"",
1257+
],
1258+
]
1259+
`;
1260+
1261+
exports[`"modules" option should invoke the custom getJSON function with getJSON as a synchronous function: warnings 1`] = `Array []`;
1262+
1263+
exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: errors 1`] = `Array []`;
1264+
1265+
exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: mapping 1`] = `
1266+
Object {
1267+
"a": "RT7ktT7mB7tfBR25sJDZ",
1268+
"b": "IZmhTnK9CIeu6ww6Zjbv",
1269+
"c": "PV11nPFlF7mzEgCXkQw4",
1270+
}
1271+
`;
1272+
1273+
exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: module 1`] = `
1274+
"// Imports
1275+
import ___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___ from \\"../../../../src/runtime/noSourceMaps.js\\";
1276+
import ___CSS_LOADER_API_IMPORT___ from \\"../../../../src/runtime/api.js\\";
1277+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___);
1278+
// Module
1279+
___CSS_LOADER_EXPORT___.push([module.id, \`.RT7ktT7mB7tfBR25sJDZ {
1280+
background-color: aliceblue;
1281+
}
1282+
1283+
.IZmhTnK9CIeu6ww6Zjbv {
1284+
background-color: burlywood;
1285+
}
1286+
1287+
.PV11nPFlF7mzEgCXkQw4 {
1288+
background-color: chartreuse;
1289+
}
1290+
1291+
.d {
1292+
background-color: darkgoldenrod
1293+
}
1294+
\`, \\"\\"]);
1295+
// Exports
1296+
___CSS_LOADER_EXPORT___.locals = {
1297+
\\"a\\": \`RT7ktT7mB7tfBR25sJDZ\`,
1298+
\\"b\\": \`IZmhTnK9CIeu6ww6Zjbv\`,
1299+
\\"c\\": \`PV11nPFlF7mzEgCXkQw4\`
1300+
};
1301+
export default ___CSS_LOADER_EXPORT___;
1302+
"
1303+
`;
1304+
1305+
exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: result 1`] = `
1306+
Array [
1307+
Array [
1308+
"./modules/getJSON/source.css",
1309+
".RT7ktT7mB7tfBR25sJDZ {
1310+
background-color: aliceblue;
1311+
}
1312+
1313+
.IZmhTnK9CIeu6ww6Zjbv {
1314+
background-color: burlywood;
1315+
}
1316+
1317+
.PV11nPFlF7mzEgCXkQw4 {
1318+
background-color: chartreuse;
1319+
}
1320+
1321+
.d {
1322+
background-color: darkgoldenrod
1323+
}
1324+
",
1325+
"",
1326+
],
1327+
]
1328+
`;
1329+
1330+
exports[`"modules" option should invoke the custom getJSON function with getJSON as an asynchronous function: warnings 1`] = `Array []`;
1331+
11941332
exports[`"modules" option should keep order: errors 1`] = `Array []`;
11951333

11961334
exports[`"modules" option should keep order: module 1`] = `

0 commit comments

Comments
 (0)