Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
};