Skip to content

Commit

Permalink
feat(modules): customizable autoModules
Browse files Browse the repository at this point in the history
  • Loading branch information
Anidetrix committed May 7, 2020
1 parent 129aff5 commit c3298de
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 13 deletions.
168 changes: 168 additions & 0 deletions __tests__/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,174 @@ console.log(modules_0d0b6254, modules_6130213c, modules_ff4908e7, modules_571860
"
`;

exports[`modules auto-modules-fn: js 1`] = `
"/** @type {HTMLElement[]} */
var containers = [];
/** @type {{prepend:HTMLStyleElement,append:HTMLStyleElement}[]} */
var styleTags = [];
/**
* @param {string} css
* @param {object} [options={}]
* @param {boolean} [options.prepend]
* @param {boolean} [options.singleTag]
* @param {string} [options.container]
* @returns {void}
*/
function injector_f247f96b (css, options) {
if (!css || typeof document === \\"undefined\\") return;
if (typeof options === \\"undefined\\") options = {};
var position = options.prepend === true ? \\"prepend\\" : \\"append\\";
var singleTag = typeof options.singleTag !== \\"undefined\\" ? options.singleTag : false;
var container =
typeof options.container !== \\"undefined\\"
? document.querySelector(options.container)
: document.getElementsByTagName(\\"head\\")[0];
function createStyleTag() {
var styleTag = document.createElement(\\"style\\");
styleTag.setAttribute(\\"type\\", \\"text/css\\");
var pos = position === \\"prepend\\" ? \\"afterbegin\\" : \\"beforeend\\";
container.insertAdjacentElement(pos, styleTag);
return styleTag;
}
/** @type {HTMLStyleElement} */
var styleTag;
if (singleTag) {
var id = containers.indexOf(container);
if (id === -1) {
id = containers.push(container) - 1;
styleTags[id] = {};
}
if (styleTags[id] && styleTags[id][position]) {
styleTag = styleTags[id][position];
} else {
styleTag = styleTags[id][position] = createStyleTag();
}
} else {
styleTag = createStyleTag();
}
// strip potential UTF-8 BOM if css was read from a file
if (css.charCodeAt(0) === 0xfeff) css = css.substring(1);
if (styleTag.styleSheet) {
styleTag.styleSheet.cssText += css;
} else {
styleTag.appendChild(document.createTextNode(css));
}
}
const css_04a4c3e4 = \\".global {\\\\n color: red;\\\\n}\\\\n\\";
injector_f247f96b(css_04a4c3e4);
const css_6c66bb9c = \\".a {\\\\n color: red;\\\\n}\\\\n\\";
injector_f247f96b(css_6c66bb9c);
const css_27de4cbf = \\".b {\\\\n color: red; }\\\\n\\";
injector_f247f96b(css_27de4cbf);
const css_12b0d2db = \\".c_module_c {\\\\n color: red;\\\\n}\\\\n\\";
const modules_ff4908e7 = {\\"c\\":\\"c_module_c\\"};
injector_f247f96b(css_12b0d2db);
const css_dfd0fcc3 = \\".d {\\\\n color: #f00;\\\\n}\\\\n\\";
injector_f247f96b(css_dfd0fcc3);
console.log(css_6c66bb9c, css_27de4cbf, modules_ff4908e7, css_dfd0fcc3);
"
`;

exports[`modules auto-modules-regexp: js 1`] = `
"/** @type {HTMLElement[]} */
var containers = [];
/** @type {{prepend:HTMLStyleElement,append:HTMLStyleElement}[]} */
var styleTags = [];
/**
* @param {string} css
* @param {object} [options={}]
* @param {boolean} [options.prepend]
* @param {boolean} [options.singleTag]
* @param {string} [options.container]
* @returns {void}
*/
function injector_f247f96b (css, options) {
if (!css || typeof document === \\"undefined\\") return;
if (typeof options === \\"undefined\\") options = {};
var position = options.prepend === true ? \\"prepend\\" : \\"append\\";
var singleTag = typeof options.singleTag !== \\"undefined\\" ? options.singleTag : false;
var container =
typeof options.container !== \\"undefined\\"
? document.querySelector(options.container)
: document.getElementsByTagName(\\"head\\")[0];
function createStyleTag() {
var styleTag = document.createElement(\\"style\\");
styleTag.setAttribute(\\"type\\", \\"text/css\\");
var pos = position === \\"prepend\\" ? \\"afterbegin\\" : \\"beforeend\\";
container.insertAdjacentElement(pos, styleTag);
return styleTag;
}
/** @type {HTMLStyleElement} */
var styleTag;
if (singleTag) {
var id = containers.indexOf(container);
if (id === -1) {
id = containers.push(container) - 1;
styleTags[id] = {};
}
if (styleTags[id] && styleTags[id][position]) {
styleTag = styleTags[id][position];
} else {
styleTag = styleTags[id][position] = createStyleTag();
}
} else {
styleTag = createStyleTag();
}
// strip potential UTF-8 BOM if css was read from a file
if (css.charCodeAt(0) === 0xfeff) css = css.substring(1);
if (styleTag.styleSheet) {
styleTag.styleSheet.cssText += css;
} else {
styleTag.appendChild(document.createTextNode(css));
}
}
const css_04a4c3e4 = \\".global {\\\\n color: red;\\\\n}\\\\n\\";
injector_f247f96b(css_04a4c3e4);
const css_6c66bb9c = \\".a {\\\\n color: red;\\\\n}\\\\n\\";
injector_f247f96b(css_6c66bb9c);
const css_27de4cbf = \\".b {\\\\n color: red; }\\\\n\\";
injector_f247f96b(css_27de4cbf);
const css_12b0d2db = \\".c {\\\\n color: red;\\\\n}\\\\n\\";
injector_f247f96b(css_12b0d2db);
const css_dfd0fcc3 = \\".d_module_d {\\\\n color: #f00;\\\\n}\\\\n\\";
const modules_5718608d = {\\"d\\":\\"d_module_d\\"};
injector_f247f96b(css_dfd0fcc3);
console.log(css_6c66bb9c, css_27de4cbf, css_12b0d2db, modules_5718608d);
"
`;

exports[`modules duplication: css 1`] = `
"html {
--color-primary: green;
Expand Down
10 changes: 10 additions & 0 deletions __tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ validateMany("modules", [
input: "auto-modules/index.js",
options: { autoModules: true },
},
{
title: "auto-modules-regexp",
input: "auto-modules/index.js",
options: { autoModules: /(?<!\.module\.)\.styl/ },
},
{
title: "auto-modules-fn",
input: "auto-modules/index.js",
options: { autoModules: (id): boolean => id.endsWith(".less") },
},
{
title: "duplication",
input: "modules-duplication/index.js",
Expand Down
17 changes: 8 additions & 9 deletions src/loaders/postcss/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ async function loadConfig(
});
}

/**
* @param file Filename
* @returns `true` if `file` matches `[name].module.[ext]` format, otherwise `false`
*/
function isModuleFile(file: string): boolean {
return /\.module\.[a-z]+$/i.test(file);
}

const loader: Loader<PostCSSLoaderOptions> = {
name: "postcss",
alwaysProcess: true,
Expand All @@ -72,7 +64,14 @@ const loader: Loader<PostCSSLoaderOptions> = {
...(config.plugins ?? []),
];

const autoModules = options.autoModules && isModuleFile(this.id);
const autoModules =
options.autoModules &&
(typeof options.autoModules === "function"
? options.autoModules(this.id)
: options.autoModules instanceof RegExp
? options.autoModules.test(this.id)
: /\.module\.[A-Za-z]+$/.test(this.id));

const supportModules = Boolean(options.modules || autoModules);

const modulesExports: { [filepath: string]: { [prop: string]: string } } = {};
Expand Down
5 changes: 3 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,11 @@ export interface Options {
* Automatically enable
* [CSS Modules](https://github.com/css-modules/css-modules)
* for files named `[name].module.[ext]`
* - ex.: `foo.module.css`, `bar.module.stylus`, etc...
* (e.g. `foo.module.css`, `bar.module.stylus`),
* or pass your own function or regular expression
* @default false
* */
autoModules?: boolean;
autoModules?: boolean | RegExp | ((id: string) => boolean);
/**
* Use named exports alongside default export.
* You can supply a function to control how exported name is generated.
Expand Down
4 changes: 2 additions & 2 deletions src/utils/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ type Mode = {
export function inferModeOption(mode: Options["mode"]): Mode {
const m = Array.isArray(mode)
? {
inject: mode[0] === "inject" ? mode[1] ?? true : false,
extract: mode[0] === "extract" ? mode[1] ?? true : false,
inject: mode[0] === "inject" && (mode[1] ?? true),
extract: mode[0] === "extract" && (mode[1] ?? true),
emit: mode[0] === "emit",
}
: {
Expand Down

0 comments on commit c3298de

Please sign in to comment.