Skip to content

Commit 701fd43

Browse files
committed
Less Modules in react-scripts test
We need to modify the jest config so that the Less Modules can be tested properly. https://jestjs.io/docs/webpack#mocking-css-modules ```diff const jestConfig = { moduleNameMapper: { - "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy", + "^.+\\.module\\.(css|less|sass|scss)$": "identity-obj-proxy", }, transformIgnorePatterns: [ - "^.+\\.module\\.(css|sass|scss)$", + "^.+\\.module\\.(css|less|sass|scss)$", ], }; ```
1 parent a4c93b1 commit 701fd43

File tree

5 files changed

+172
-12
lines changed

5 files changed

+172
-12
lines changed

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ yarn-error.log
99
.vscode
1010
coverage
1111
lib/*.test.js
12+
lib/test-utils.js
1213
yarn.lock
1314
craco-less-*.tgz
1415
.github/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ you should use the [`craco-antd`](https://github.com/DocSpring/craco-antd) plugi
6363

6464
## Installation
6565

66-
First, follow the [`craco` Installation Instructions](https://github.com/sharegate/craco/blob/master/packages/craco/README.md##installation) to install the `craco` package, create a `craco.config.js` file, and modify the scripts in your `package.json`.
66+
First, follow the [`craco` Installation Instructions](https://github.com/gsoft-inc/craco/blob/master/packages/craco/README.md#installation) to install the `craco` package, create a `craco.config.js` file, and modify the scripts in your `package.json`.
6767

6868
Then install `craco-less`:
6969

lib/craco-less.js

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
const path = require("path");
22
const { deepClone, styleRuleByName } = require("./utils");
3+
const { loaderByName, throwUnexpectedConfigError } = require("@craco/craco");
34

45
const lessRegex = /\.less$/;
56
const lessModuleRegex = /\.module\.less$/;
67

7-
const overrideWebpackConfig = ({ context, webpackConfig, pluginOptions }) => {
8-
const { loaderByName, throwUnexpectedConfigError } = require("@craco/craco");
8+
const throwError = (message, githubIssueQuery) =>
9+
throwUnexpectedConfigError({
10+
packageName: "craco-less",
11+
githubRepo: "DocSpring/craco-less",
12+
message,
13+
githubIssueQuery,
14+
});
915

16+
const overrideWebpackConfig = ({ context, webpackConfig, pluginOptions }) => {
1017
// This is mocked in Windows tests
1118
const pathSep = module.exports.pathSep;
12-
13-
const throwError = (message, githubIssueQuery) =>
14-
throwUnexpectedConfigError({
15-
packageName: "craco-less",
16-
githubRepo: "DocSpring/craco-less",
17-
message,
18-
githubIssueQuery,
19-
});
20-
2119
pluginOptions = pluginOptions || {};
2220

2321
const createLessRule = ({ baseRule, overrideRule }) => {
@@ -173,8 +171,44 @@ const overrideWebpackConfig = ({ context, webpackConfig, pluginOptions }) => {
173171
return webpackConfig;
174172
};
175173

174+
const overrideJestConfig = ({ context, jestConfig }) => {
175+
const moduleNameMapper = jestConfig.moduleNameMapper;
176+
const cssModulesPattern = Object.keys(moduleNameMapper).find((p) =>
177+
p.match(/\\\.module\\\.\(.*?css.*?\)/)
178+
);
179+
180+
if (!cssModulesPattern) {
181+
throwError(
182+
`Can't find CSS Modules pattern under moduleNameMapper in the ${context.env} jest config!`,
183+
"jest+moduleNameMapper+css"
184+
);
185+
}
186+
187+
moduleNameMapper[cssModulesPattern.replace("css", "css|less")] =
188+
moduleNameMapper[cssModulesPattern];
189+
delete moduleNameMapper[cssModulesPattern];
190+
191+
const transformIgnorePatterns = jestConfig.transformIgnorePatterns;
192+
const cssModulesPatternIndex = transformIgnorePatterns.findIndex((p) =>
193+
p.match(/\\\.module\\\.\(.*?css.*?\)/)
194+
);
195+
if (cssModulesPatternIndex === -1) {
196+
throwError(
197+
`Can't find CSS Modules pattern under transformIgnorePatterns in the ${context.env} jest config!`,
198+
"jest+transformIgnorePatterns+css"
199+
);
200+
}
201+
202+
transformIgnorePatterns[cssModulesPatternIndex] = transformIgnorePatterns[
203+
cssModulesPatternIndex
204+
].replace("css", "css|less");
205+
206+
return jestConfig;
207+
};
208+
176209
// pathSep is mocked in Windows tests
177210
module.exports = {
178211
overrideWebpackConfig,
212+
overrideJestConfig,
179213
pathSep: path.sep,
180214
};

lib/craco-less.test.test.js

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
const { createJestConfig } = require("@craco/craco");
2+
const { processCracoConfig } = require("@craco/craco/lib/config");
3+
const { applyJestConfigPlugins } = require("@craco/craco/lib/features/plugins");
4+
const clone = require("clone");
5+
const CracoLessPlugin = require("./craco-less");
6+
const { getCracoContext } = require("./test-utils");
7+
8+
process.env.NODE_ENV = "test";
9+
10+
const baseCracoConfig = {};
11+
const cracoContext = getCracoContext(baseCracoConfig);
12+
const originalJestConfig = createJestConfig(baseCracoConfig);
13+
14+
const overrideJestConfig = (callerCracoConfig, jestConfig) => {
15+
return applyJestConfigPlugins(
16+
processCracoConfig({
17+
...baseCracoConfig,
18+
...callerCracoConfig,
19+
}),
20+
jestConfig,
21+
cracoContext
22+
);
23+
};
24+
25+
let jestConfig;
26+
beforeEach(() => {
27+
// deep clone the object before each test.
28+
jestConfig = clone(originalJestConfig);
29+
});
30+
31+
test("the jest config is modified correctly", () => {
32+
jestConfig = overrideJestConfig(
33+
{
34+
plugins: [{ plugin: CracoLessPlugin }],
35+
},
36+
jestConfig
37+
);
38+
39+
const moduleNameMapper = jestConfig.moduleNameMapper;
40+
expect(moduleNameMapper["^.+\\.module\\.(css|sass|scss)$"]).toBeUndefined();
41+
expect(moduleNameMapper["^.+\\.module\\.(css|less|sass|scss)$"]).toEqual(
42+
"identity-obj-proxy"
43+
);
44+
45+
const transformIgnorePatterns = jestConfig.transformIgnorePatterns;
46+
expect(transformIgnorePatterns[1]).toEqual(
47+
"^.+\\.module\\.(css|less|sass|scss)$"
48+
);
49+
});
50+
51+
test("throws an error when we can't find CSS Modules pattern under moduleNameMapper in the jest config", () => {
52+
delete jestConfig.moduleNameMapper["^.+\\.module\\.(css|sass|scss)$"];
53+
54+
const runTest = () => {
55+
overrideJestConfig(
56+
{
57+
plugins: [{ plugin: CracoLessPlugin }],
58+
},
59+
jestConfig
60+
);
61+
};
62+
63+
expect(runTest).toThrowError(
64+
"Can't find CSS Modules pattern under moduleNameMapper in the test jest config!\n\n" +
65+
"This error probably occurred because you updated react-scripts or craco. " +
66+
"Please try updating craco-less to the latest version:\n\n" +
67+
" $ yarn upgrade craco-less\n\n" +
68+
"Or:\n\n" +
69+
" $ npm update craco-less\n\n" +
70+
"If that doesn't work, craco-less needs to be fixed to support the latest version.\n" +
71+
"Please check to see if there's already an issue in the DocSpring/craco-less repo:\n\n" +
72+
" * https://github.com/DocSpring/craco-less/issues?q=is%3Aissue+jest+moduleNameMapper+css\n\n" +
73+
"If not, please open an issue and we'll take a look. (Or you can send a PR!)\n\n" +
74+
"You might also want to look for related issues in the " +
75+
"craco and create-react-app repos:\n\n" +
76+
" * https://github.com/sharegate/craco/issues?q=is%3Aissue+jest+moduleNameMapper+css\n" +
77+
" * https://github.com/facebook/create-react-app/issues?q=is%3Aissue+jest+moduleNameMapper+css\n"
78+
);
79+
});
80+
81+
test("throws an error when we can't find CSS Modules pattern under transformIgnorePatterns in the jest config", () => {
82+
jestConfig.transformIgnorePatterns =
83+
jestConfig.transformIgnorePatterns.filter(
84+
(e) => e !== "^.+\\.module\\.(css|sass|scss)$"
85+
);
86+
87+
const runTest = () => {
88+
overrideJestConfig(
89+
{
90+
plugins: [{ plugin: CracoLessPlugin }],
91+
},
92+
jestConfig
93+
);
94+
};
95+
96+
expect(runTest).toThrowError(
97+
"Can't find CSS Modules pattern under transformIgnorePatterns in the test jest config!\n\n" +
98+
"This error probably occurred because you updated react-scripts or craco. " +
99+
"Please try updating craco-less to the latest version:\n\n" +
100+
" $ yarn upgrade craco-less\n\n" +
101+
"Or:\n\n" +
102+
" $ npm update craco-less\n\n" +
103+
"If that doesn't work, craco-less needs to be fixed to support the latest version.\n" +
104+
"Please check to see if there's already an issue in the DocSpring/craco-less repo:\n\n" +
105+
" * https://github.com/DocSpring/craco-less/issues?q=is%3Aissue+jest+transformIgnorePatterns+css\n\n" +
106+
"If not, please open an issue and we'll take a look. (Or you can send a PR!)\n\n" +
107+
"You might also want to look for related issues in the " +
108+
"craco and create-react-app repos:\n\n" +
109+
" * https://github.com/sharegate/craco/issues?q=is%3Aissue+jest+transformIgnorePatterns+css\n" +
110+
" * https://github.com/facebook/create-react-app/issues?q=is%3Aissue+jest+transformIgnorePatterns+css\n"
111+
);
112+
});

lib/test-utils.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const { processCracoConfig } = require("@craco/craco/lib/config");
2+
const { getCraPaths } = require("@craco/craco/lib/cra");
3+
4+
const getCracoContext = (callerCracoConfig, env = process.env.NODE_ENV) => {
5+
const context = { env };
6+
const cracoConfig = processCracoConfig(callerCracoConfig, { env });
7+
context.paths = getCraPaths(cracoConfig);
8+
return context;
9+
};
10+
11+
module.exports = {
12+
getCracoContext,
13+
};

0 commit comments

Comments
 (0)