Skip to content
This repository has been archived by the owner on Mar 6, 2024. It is now read-only.

Commit

Permalink
Add config options for LESS
Browse files Browse the repository at this point in the history
  • Loading branch information
Shaun Lloyd committed Apr 24, 2023
1 parent 759f55b commit 4c042fb
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 9 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"@storybook/theming": "^7.0.2",
"@storybook/types": "^7.0.2",
"css-loader": "^6.7.3",
"less-loader": "^11.1.0",
"postcss-loader": "^7.2.4",
"resolve-url-loader": "^5.0.0",
"sass-loader": "^13.2.2",
Expand Down
99 changes: 99 additions & 0 deletions src/webpack/less/webpack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import type { RuleSetRule, Configuration as WebpackConfig } from "webpack";
import type { AddonStylingOptions } from "../types";

const isRuleForLESS = (rule: RuleSetRule) =>
typeof rule !== "string" &&
rule.test instanceof RegExp &&
rule.test.test("test.less");

const buildStyleLoader = (options: AddonStylingOptions) => ({
loader: require.resolve("style-loader"),
});

const buildCssLoader = ({ cssModules, postCss }: AddonStylingOptions) => {
const importSettings = { importLoaders: postCss ? 2 : 1 };
const moduleSettings = cssModules ? { modules: { auto: true } } : {};

return {
loader: require.resolve("css-loader"),
options: {
...importSettings,
...moduleSettings,
},
};
};

const buildPostCssLoader = ({ postCss }: AddonStylingOptions) => {
const implementationOptions =
typeof postCss === "object" ? { ...postCss } : {};

return {
loader: require.resolve("postcss-loader"),
options: {
...implementationOptions,
},
};
};

const buildLessLoader = ({ less }: AddonStylingOptions) => {
const implementationOptions =
typeof less === "object" && less.hasOwnProperty("implementation")
? { implementation: less.implementation }
: {};

const additionalData =
typeof less === "object" && less.hasOwnProperty("additionalData")
? { additionalData: less.additionalData }
: {};

return {
loader: require.resolve("less-loader"),
options: {
sourceMap: true,
lessOptions: less.lessOptions ?? {},
...implementationOptions,
...additionalData,
},
};
};

const LESS_FILE_REGEX = /\.less$/i;
const buildLessRule = (options: AddonStylingOptions): RuleSetRule => {
if (options.scssBuildRule) return options.scssBuildRule;

const buildRule = [
buildStyleLoader(options),
buildCssLoader(options),
...(options.postCss ? [buildPostCssLoader(options)] : []),
buildLessLoader(options),
];
return {
test: LESS_FILE_REGEX,
use: buildRule,
sideEffects: true,
};
};

export const patchOrAddLessRule = (
config: WebpackConfig,
options: AddonStylingOptions
): void => {
// If the user doesn't want to patch webpack for postcss or css modules
if (!options.less && !options.lessBuildRule) {
// return without adjusting config
return;
}

const rules = config.module?.rules;

const rule = buildLessRule(options);
const ruleIndex = rules?.findIndex(isRuleForLESS);

if (ruleIndex === -1) {
// If no existing css rule, add it
rules?.push(rule);
} else {
// If existing css rule, replace it
rules[ruleIndex] = rule;
}
};
7 changes: 1 addition & 6 deletions src/webpack/scss/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,7 @@ export const patchOrAddScssRule = (
options: AddonStylingOptions
): void => {
// If the user doesn't want to patch webpack for postcss or css modules
if (
!options.cssModules &&
!options.postCss &&
!options.sass &&
!options.scssBuildRule
) {
if (!options.sass && !options.scssBuildRule) {
// return without adjusting config
return;
}
Expand Down
12 changes: 10 additions & 2 deletions src/webpack/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import type { RuleSetRule } from "webpack";

interface LessConfig {
lessOptions?: Record<string, any>;
implementation?: string;
additionalData?: unknown;
}

export interface AddonStylingOptions {
cssBuildRule?: RuleSetRule;
cssModules?: boolean;
less?: LessConfig;
lessBuildRule?: RuleSetRule;
postCss?: boolean | object;
sass?: boolean | object;
cssModules?: boolean;
cssBuildRule?: RuleSetRule;
scssBuildRule?: RuleSetRule;
}
2 changes: 2 additions & 0 deletions src/webpack/webpackFinal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import type { AddonStylingOptions } from "./types";

import { patchOrAddCssRule } from "./css/webpack";
import { patchOrAddScssRule } from "./scss/webpack";
import { patchOrAddLessRule } from "./less/webpack";

export function webpackFinal(
config: WebpackConfig,
options: AddonStylingOptions = {}
) {
patchOrAddCssRule(config, options);
patchOrAddScssRule(config, options);
patchOrAddLessRule(config, options);

return config;
}
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7006,7 +7006,7 @@ kleur@^3.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==

klona@^2.0.6:
klona@^2.0.4, klona@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22"
integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==
Expand All @@ -7020,6 +7020,13 @@ lazy-universal-dotenv@^4.0.0:
dotenv "^16.0.0"
dotenv-expand "^10.0.0"

less-loader@^11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-11.1.0.tgz#a452384259bdf8e4f6d5fdcc39543609e6313f82"
integrity sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==
dependencies:
klona "^2.0.4"

leven@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
Expand Down

0 comments on commit 4c042fb

Please sign in to comment.