Last active
February 27, 2022 22:43
-
-
Save JonatasAmaral/ca1e3d667215a8febc219b3e97277a79 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file Script de alteração dos loaders do laravel-mix, para importar cssModules apenas nos arquivos pertinentes | |
* adaptado do pacote [laravel-mix-react-css-modules](https://www.npmjs.com/package/laravel-mix-react-css-modules) | |
* | |
* @author Jonatas Amaral | |
*/ | |
const mix = require("laravel-mix"); | |
/** | |
* Makes a full copy of an Array/Object | |
* | |
* @template ToClone | |
* @param { ToClone } items | |
* @return { ToClone } | |
*/ | |
function deepClone(items) { | |
if (Array.isArray(items)) { | |
return items.map(item => deepClone(item)) | |
} | |
if (items instanceof RegExp) return items | |
if (typeof items === 'object' && items !== null) { | |
let copyObj = {} | |
for (let k in items) { | |
copyObj[k] = deepClone(items[k]) | |
} | |
return copyObj | |
} | |
return items | |
} | |
/** | |
* Concatenate two regular expressions | |
* [credits](https://masteringjs.io/tutorials/fundamentals/concat-regexp) | |
* @param {RegExp} reg | |
* @param {RegExp} exp | |
* @returns RegExp | |
*/ | |
function concatRegexp(reg, exp) { | |
let flags = reg.flags + exp.flags; | |
flags = Array.from(new Set(flags.split(''))).join(); | |
return new RegExp(reg.source + exp.source, flags); | |
} | |
class ImportCssModules { | |
static name = "cssModules"; | |
constructor() { | |
// default configurations | |
// className pattern if not set on usage | |
this.classNamePattern = "[path]__[local]___[id]-[hash:base64:8]"; | |
// enable sourceMaps by default | |
this.sourceMap = true | |
} | |
register(args = {}) { | |
// optional configuration parameters | |
const { classNamePattern, sourceMap } = args; | |
if (classNamePattern) { | |
this.classNamePattern = classNamePattern; | |
} | |
if (sourceMap) { | |
this.sourceMap = sourceMap; | |
} | |
} | |
webpackConfig(config) { | |
config.module.rules = config.module.rules.map(rule => { | |
/** | |
* If it's a styles rule | |
* (has `css-modules` in the loaders array) | |
* */ | |
if (Array.isArray(rule.loaders) && ( | |
rule.loaders.some( | |
loader => loader === "css-loader" || | |
loader.loader === "css-loader" | |
) | |
)) { | |
// does a deep clone of rules, and turns it into cssModules rules | |
let cssModulesLoader = deepClone(rule.loaders).map(loader => { | |
// if it is a string css-loader, turns it into an objet | |
if (loader === "css-loader" || loader === "sass-loader") { | |
loader = { loader, options: {} } | |
} | |
// if it's an 'css-loader' object | |
if (loader.loader === "css-loader") { | |
loader.options.modules = true | |
loader.options.localIdentName = this.classNamePattern | |
loader.options.sourceMap = this.sourceMap | |
loader.options.url = true // enables aliases solving | |
} | |
// if it's not css-loader, does nothing | |
return loader; | |
}); | |
// use oneOf, on following order | |
// 1 .module.css | .modules.css | |
// 2 .css?module | .css?modules | |
// 3 .css | |
return { | |
oneOf: [ | |
{ | |
...rule, | |
loaders: cssModulesLoader, | |
test: concatRegexp(/\.modules?/, RegExp(rule.test)) // garante que o test é um RegExp | |
}, | |
{ ...rule, loaders: cssModulesLoader, resourceQuery: /modules?/ }, | |
rule | |
] | |
} | |
} | |
// if it's not a loader rule, does nothing | |
return rule; | |
}) | |
} | |
} | |
mix.extend(ImportCssModules.name, new ImportCssModules()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment