Skip to content

Commit 2d4b5ab

Browse files
Less Modules in react-scripts test (#83)
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)$", ], }; ``` Co-authored-by: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
1 parent 129d630 commit 2d4b5ab

File tree

5 files changed

+146
-12
lines changed

5 files changed

+146
-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 }) => {
@@ -174,8 +172,44 @@ const overrideWebpackConfig = ({ context, webpackConfig, pluginOptions }) => {
174172
return webpackConfig;
175173
};
176174

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

lib/craco-less.test.test.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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!/
65+
);
66+
});
67+
68+
test("throws an error when we can't find CSS Modules pattern under transformIgnorePatterns in the jest config", () => {
69+
jestConfig.transformIgnorePatterns =
70+
jestConfig.transformIgnorePatterns.filter(
71+
(e) => e !== "^.+\\.module\\.(css|sass|scss)$"
72+
);
73+
74+
const runTest = () => {
75+
overrideJestConfig(
76+
{
77+
plugins: [{ plugin: CracoLessPlugin }],
78+
},
79+
jestConfig
80+
);
81+
};
82+
83+
expect(runTest).toThrowError(
84+
/^Can't find CSS Modules pattern under transformIgnorePatterns in the test jest config!/
85+
);
86+
});

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)