Skip to content

Instantly share code, notes, and snippets.

@fabysdev
Created September 19, 2019 10:02
Show Gist options
  • Save fabysdev/918efc4b233a1f3a42f10ec7ba5296f5 to your computer and use it in GitHub Desktop.
Save fabysdev/918efc4b233a1f3a42f10ec7ba5296f5 to your computer and use it in GitHub Desktop.
const loaderUtils = require("loader-utils");
const path = require("path");
const ruleChildren = loader =>
loader.use ||
loader.oneOf ||
(Array.isArray(loader.loader) && loader.loader) ||
[];
const findIndexAndRules = (rulesSource, ruleMatcher) => {
let result = undefined;
const rules = Array.isArray(rulesSource)
? rulesSource
: ruleChildren(rulesSource);
rules.some(
(rule, index) =>
(result = ruleMatcher(rule)
? { index, rules }
: findIndexAndRules(ruleChildren(rule), ruleMatcher))
);
return result;
};
const findRule = (rulesSource, ruleMatcher) => {
const { index, rules } = findIndexAndRules(rulesSource, ruleMatcher);
return rules[index];
};
const cssRuleMatcher = rule =>
rule.test && String(rule.test) === String(/\.module\.(scss|sass)$/);
const getLocalIdent = env => (context, localIdentName, localName, options) => {
// Use the filename or folder name, based on some uses the index.js / index.module.(css|scss|sass) project style
const fileNameOrFolder = context.resourcePath.match(
/index\.module\.(css|scss|sass)$/
)
? "[folder]"
: "[name]";
// Create a hash based on a the file location and class name. Will be unique across a project, and close to globally unique.
let hash = "";
do {
hash = loaderUtils.getHashDigest(
path.posix.relative(context.rootContext, context.resourcePath) +
localName +
hash,
"md5",
"base64",
5
);
} while (!isNaN(hash[0]));
// Use loaderUtils to find the file or folder name
let className = loaderUtils.interpolateName(
context,
env === "development"
? hash.replace("-", "")
: fileNameOrFolder + "_" + localName + "__" + hash,
options
);
// remove the .module that appears in every classname when based on the file.
return className.replace(".module_", "_");
};
module.exports = (config, env) => {
const cssRule = findRule(config.module.rules, cssRuleMatcher);
cssRule.use.forEach(u => {
if (!u.options) {
return;
}
if (u.options.getLocalIdent) {
u.options.getLocalIdent = getLocalIdent(env);
}
});
return config;
};
"react-app-rewired"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment