Skip to content

Commit

Permalink
Less Modules in react-scripts test (#83)
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
fanck0605 and kamronbatman authored Apr 21, 2022
1 parent 129d630 commit 2d4b5ab
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 12 deletions.
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ yarn-error.log
.vscode
coverage
lib/*.test.js
lib/test-utils.js
yarn.lock
craco-less-*.tgz
.github/
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ you should use the [`craco-antd`](https://github.com/DocSpring/craco-antd) plugi

## Installation

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`.
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`.

Then install `craco-less`:

Expand Down
56 changes: 45 additions & 11 deletions lib/craco-less.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
const path = require("path");
const { deepClone, styleRuleByName } = require("./utils");
const { loaderByName, throwUnexpectedConfigError } = require("@craco/craco");

const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;

const overrideWebpackConfig = ({ context, webpackConfig, pluginOptions }) => {
const { loaderByName, throwUnexpectedConfigError } = require("@craco/craco");
const throwError = (message, githubIssueQuery) =>
throwUnexpectedConfigError({
packageName: "craco-less",
githubRepo: "DocSpring/craco-less",
message,
githubIssueQuery,
});

const overrideWebpackConfig = ({ context, webpackConfig, pluginOptions }) => {
// This is mocked in Windows tests
const pathSep = module.exports.pathSep;

const throwError = (message, githubIssueQuery) =>
throwUnexpectedConfigError({
packageName: "craco-less",
githubRepo: "DocSpring/craco-less",
message,
githubIssueQuery,
});

pluginOptions = pluginOptions || {};

const createLessRule = ({ baseRule, overrideRule }) => {
Expand Down Expand Up @@ -174,8 +172,44 @@ const overrideWebpackConfig = ({ context, webpackConfig, pluginOptions }) => {
return webpackConfig;
};

const overrideJestConfig = ({ context, jestConfig }) => {
const moduleNameMapper = jestConfig.moduleNameMapper;
const cssModulesPattern = Object.keys(moduleNameMapper).find((p) =>
p.match(/\\\.module\\\.\(.*?css.*?\)/)
);

if (!cssModulesPattern) {
throwError(
`Can't find CSS Modules pattern under moduleNameMapper in the ${context.env} jest config!`,
"jest+moduleNameMapper+css"
);
}

moduleNameMapper[cssModulesPattern.replace("css", "css|less")] =
moduleNameMapper[cssModulesPattern];
delete moduleNameMapper[cssModulesPattern];

const transformIgnorePatterns = jestConfig.transformIgnorePatterns;
const cssModulesPatternIndex = transformIgnorePatterns.findIndex((p) =>
p.match(/\\\.module\\\.\(.*?css.*?\)/)
);
if (cssModulesPatternIndex === -1) {
throwError(
`Can't find CSS Modules pattern under transformIgnorePatterns in the ${context.env} jest config!`,
"jest+transformIgnorePatterns+css"
);
}

transformIgnorePatterns[cssModulesPatternIndex] = transformIgnorePatterns[
cssModulesPatternIndex
].replace("css", "css|less");

return jestConfig;
};

// pathSep is mocked in Windows tests
module.exports = {
overrideWebpackConfig,
overrideJestConfig,
pathSep: path.sep,
};
86 changes: 86 additions & 0 deletions lib/craco-less.test.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
const { createJestConfig } = require("@craco/craco");
const { processCracoConfig } = require("@craco/craco/lib/config");
const { applyJestConfigPlugins } = require("@craco/craco/lib/features/plugins");
const clone = require("clone");
const CracoLessPlugin = require("./craco-less");
const { getCracoContext } = require("./test-utils");

process.env.NODE_ENV = "test";

const baseCracoConfig = {};
const cracoContext = getCracoContext(baseCracoConfig);
const originalJestConfig = createJestConfig(baseCracoConfig);

const overrideJestConfig = (callerCracoConfig, jestConfig) => {
return applyJestConfigPlugins(
processCracoConfig({
...baseCracoConfig,
...callerCracoConfig,
}),
jestConfig,
cracoContext
);
};

let jestConfig;
beforeEach(() => {
// deep clone the object before each test.
jestConfig = clone(originalJestConfig);
});

test("the jest config is modified correctly", () => {
jestConfig = overrideJestConfig(
{
plugins: [{ plugin: CracoLessPlugin }],
},
jestConfig
);

const moduleNameMapper = jestConfig.moduleNameMapper;
expect(moduleNameMapper["^.+\\.module\\.(css|sass|scss)$"]).toBeUndefined();
expect(moduleNameMapper["^.+\\.module\\.(css|less|sass|scss)$"]).toEqual(
"identity-obj-proxy"
);

const transformIgnorePatterns = jestConfig.transformIgnorePatterns;
expect(transformIgnorePatterns[1]).toEqual(
"^.+\\.module\\.(css|less|sass|scss)$"
);
});

test("throws an error when we can't find CSS Modules pattern under moduleNameMapper in the jest config", () => {
delete jestConfig.moduleNameMapper["^.+\\.module\\.(css|sass|scss)$"];

const runTest = () => {
overrideJestConfig(
{
plugins: [{ plugin: CracoLessPlugin }],
},
jestConfig
);
};

expect(runTest).toThrowError(
/^Can't find CSS Modules pattern under moduleNameMapper in the test jest config!/
);
});

test("throws an error when we can't find CSS Modules pattern under transformIgnorePatterns in the jest config", () => {
jestConfig.transformIgnorePatterns =
jestConfig.transformIgnorePatterns.filter(
(e) => e !== "^.+\\.module\\.(css|sass|scss)$"
);

const runTest = () => {
overrideJestConfig(
{
plugins: [{ plugin: CracoLessPlugin }],
},
jestConfig
);
};

expect(runTest).toThrowError(
/^Can't find CSS Modules pattern under transformIgnorePatterns in the test jest config!/
);
});
13 changes: 13 additions & 0 deletions lib/test-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const { processCracoConfig } = require("@craco/craco/lib/config");
const { getCraPaths } = require("@craco/craco/lib/cra");

const getCracoContext = (callerCracoConfig, env = process.env.NODE_ENV) => {
const context = { env };
const cracoConfig = processCracoConfig(callerCracoConfig, { env });
context.paths = getCraPaths(cracoConfig);
return context;
};

module.exports = {
getCracoContext,
};

0 comments on commit 2d4b5ab

Please sign in to comment.