diff --git a/.editorconfig b/.editorconfig index 5415e70..90fab26 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,7 @@ end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true +max_line_length = 100 [*.css] indent_size = 4 diff --git a/index.d.ts b/index.d.ts index 487ef66..f723ef1 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,10 +1,6 @@ import type { Plugin } from "postcss"; -declare type GenerateScopedNameFunction = ( - name: string, - filename: string, - css: string -) => string; +declare type GenerateScopedNameFunction = (name: string, filename: string, css: string) => string; declare type LocalsConventionFunction = ( originalClassName: string, @@ -15,21 +11,13 @@ declare type LocalsConventionFunction = ( declare class Loader { constructor(root: string, plugins: Plugin[]); - fetch( - file: string, - relativeTo: string, - depTrace: string - ): Promise<{ [key: string]: string }>; + fetch(file: string, relativeTo: string, depTrace: string): Promise<{ [key: string]: string }>; finalSource?: string | undefined; } declare interface Options { - getJSON?( - cssFilename: string, - json: { [name: string]: string }, - outputFilename?: string - ): void; + getJSON?(cssFilename: string, json: { [name: string]: string }, outputFilename?: string): void; localsConvention?: | "camelCase" @@ -49,10 +37,7 @@ declare interface Options { Loader?: typeof Loader; - resolve?: ( - file: string, - importer: string - ) => string | null | Promise; + resolve?: (file: string, importer: string) => string | null | Promise; } declare interface PostcssModulesPlugin { diff --git a/src/behaviours.js b/src/behaviours.js index 454b070..d48fdd9 100644 --- a/src/behaviours.js +++ b/src/behaviours.js @@ -8,26 +8,12 @@ export const behaviours = { GLOBAL: "global", }; -export function getDefaultPlugins({ - behaviour, - generateScopedName, - exportGlobals, -}) { +export function getDefaultPlugins({ behaviour, generateScopedName, exportGlobals }) { const scope = modulesScope({ generateScopedName, exportGlobals }); const plugins = { - [behaviours.LOCAL]: [ - values, - localByDefault({ mode: "local" }), - extractImports, - scope, - ], - [behaviours.GLOBAL]: [ - values, - localByDefault({ mode: "global" }), - extractImports, - scope, - ], + [behaviours.LOCAL]: [values, localByDefault({ mode: "local" }), extractImports, scope], + [behaviours.GLOBAL]: [values, localByDefault({ mode: "global" }), extractImports, scope], }; return plugins[behaviour]; diff --git a/src/css-loader-core/loader.js b/src/css-loader-core/loader.js index 0bd633d..7a2f800 100644 --- a/src/css-loader-core/loader.js +++ b/src/css-loader-core/loader.js @@ -36,11 +36,13 @@ class Core { const traceKeySorter = (a, b) => { if (a.length < b.length) { return a < b.substring(0, a.length) ? -1 : 1; - } else if (a.length > b.length) { + } + + if (a.length > b.length) { return a.substring(0, b.length) <= b ? -1 : 1; - } else { - return a < b ? -1 : 1; } + + return a < b ? -1 : 1; }; export default class FileSystemLoader { @@ -48,9 +50,7 @@ export default class FileSystemLoader { if (root === "/" && process.platform === "win32") { const cwdDrive = process.cwd().slice(0, 3); if (!/^[A-Za-z]:\\$/.test(cwdDrive)) { - throw new Error( - `Failed to obtain root from "${process.cwd()}".` - ); + throw new Error(`Failed to obtain root from "${process.cwd()}".`); } root = cwdDrive; } @@ -74,26 +74,18 @@ export default class FileSystemLoader { : await Promise.resolve(); if (fileResolvedPath && !path.isAbsolute(fileResolvedPath)) { - throw new Error( - 'The returned path from the "fileResolve" option must be absolute.' - ); + throw new Error('The returned path from the "fileResolve" option must be absolute.'); } const relativeDir = path.dirname(relativeTo); - const rootRelativePath = - fileResolvedPath || path.resolve(relativeDir, newPath); + const rootRelativePath = fileResolvedPath || path.resolve(relativeDir, newPath); let fileRelativePath = - fileResolvedPath || - path.resolve(path.resolve(this.root, relativeDir), newPath); + fileResolvedPath || path.resolve(path.resolve(this.root, relativeDir), newPath); // if the path is not relative or absolute, try to resolve it in node_modules - if ( - !useFileResolve && - newPath[0] !== "." && - !path.isAbsolute(newPath) - ) { + if (!useFileResolve && newPath[0] !== "." && !path.isAbsolute(newPath)) { try { fileRelativePath = require.resolve(newPath); } catch (e) { diff --git a/src/css-loader-core/parser.js b/src/css-loader-core/parser.js index 8304e11..0c959e5 100644 --- a/src/css-loader-core/parser.js +++ b/src/css-loader-core/parser.js @@ -28,13 +28,7 @@ export default class Parser { let imports = []; css.each((node) => { if (node.type == "rule" && node.selector.match(importRegexp)) { - imports.push( - this.fetchImport( - node, - css.source.input.from, - imports.length - ) - ); + imports.push(this.fetchImport(node, css.source.input.from, imports.length)); } }); return imports; @@ -46,8 +40,7 @@ export default class Parser { extractExports(css) { css.each((node) => { - if (node.type == "rule" && node.selector == ":export") - this.handleExport(node); + if (node.type == "rule" && node.selector == ":export") this.handleExport(node); }); } @@ -55,10 +48,7 @@ export default class Parser { exportNode.each((decl) => { if (decl.type == "decl") { Object.keys(this.translations).forEach((translation) => { - decl.value = decl.value.replace( - translation, - this.translations[translation] - ); + decl.value = decl.value.replace(translation, this.translations[translation]); }); this.exportTokens[decl.prop] = decl.value; } diff --git a/src/index.js b/src/index.js index 041a454..ed19e60 100644 --- a/src/index.js +++ b/src/index.js @@ -67,9 +67,7 @@ function isOurPlugin(plugin) { } function dashesCamelCase(string) { - return string.replace(/-+(\w)/g, (_, firstLetter) => - firstLetter.toUpperCase() - ); + return string.replace(/-+(\w)/g, (_, firstLetter) => firstLetter.toUpperCase()); } module.exports = (opts = {}) => { @@ -79,29 +77,21 @@ module.exports = (opts = {}) => { const getJSON = opts.getJSON || saveJSON; const inputFile = css.source.input.file; const pluginList = getDefaultPluginsList(opts, inputFile); - const resultPluginIndex = result.processor.plugins.findIndex( - (plugin) => isOurPlugin(plugin) + const resultPluginIndex = result.processor.plugins.findIndex((plugin) => + isOurPlugin(plugin) ); if (resultPluginIndex === -1) { throw new Error("Plugin missing from options."); } - const earlierPlugins = result.processor.plugins.slice( - 0, - resultPluginIndex - ); + const earlierPlugins = result.processor.plugins.slice(0, resultPluginIndex); const loaderPlugins = [...earlierPlugins, ...pluginList]; const loader = getLoader(opts, loaderPlugins); const fetcher = async (file, relativeTo, depTrace) => { const unquoteFile = unquote(file); - return loader.fetch.call( - loader, - unquoteFile, - relativeTo, - depTrace - ); + return loader.fetch.call(loader, unquoteFile, relativeTo, depTrace); }; const parser = new Parser(fetcher); @@ -115,42 +105,39 @@ module.exports = (opts = {}) => { if (opts.localsConvention) { const isFunc = typeof opts.localsConvention === "function"; - parser.exportTokens = Object.entries( - parser.exportTokens - ).reduce((tokens, [className, value]) => { - if (isFunc) { - const convention = opts.localsConvention( - className, - value, - inputFile - ); - tokens[convention] = value; + parser.exportTokens = Object.entries(parser.exportTokens).reduce( + (tokens, [className, value]) => { + if (isFunc) { + const convention = opts.localsConvention(className, value, inputFile); + tokens[convention] = value; + + return tokens; + } + + switch (opts.localsConvention) { + case "camelCase": + tokens[className] = value; + tokens[camelCase(className)] = value; + break; + + case "camelCaseOnly": + tokens[camelCase(className)] = value; + break; + + case "dashes": + tokens[className] = value; + tokens[dashesCamelCase(className)] = value; + break; + + case "dashesOnly": + tokens[dashesCamelCase(className)] = value; + break; + } return tokens; - } - - switch (opts.localsConvention) { - case "camelCase": - tokens[className] = value; - tokens[camelCase(className)] = value; - break; - - case "camelCaseOnly": - tokens[camelCase(className)] = value; - break; - - case "dashes": - tokens[className] = value; - tokens[dashesCamelCase(className)] = value; - break; - - case "dashesOnly": - tokens[dashesCamelCase(className)] = value; - break; - } - - return tokens; - }, {}); + }, + {} + ); } result.messages.push({ @@ -160,11 +147,7 @@ module.exports = (opts = {}) => { }); // getJSON may return a promise - return getJSON( - css.source.input.file, - parser.exportTokens, - result.opts.to - ); + return getJSON(css.source.input.file, parser.exportTokens, result.opts.to); }, }; }; diff --git a/src/saveJSON.js b/src/saveJSON.js index 0b31cd7..950cc8f 100644 --- a/src/saveJSON.js +++ b/src/saveJSON.js @@ -2,8 +2,6 @@ import { writeFile } from "fs"; export default function saveJSON(cssFile, json) { return new Promise((resolve, reject) => { - writeFile(`${cssFile}.json`, JSON.stringify(json), (e) => - e ? reject(e) : resolve(json) - ); + writeFile(`${cssFile}.json`, JSON.stringify(json), (e) => (e ? reject(e) : resolve(json))); }); } diff --git a/test/test.js b/test/test.js index 60fd741..39851a1 100644 --- a/test/test.js +++ b/test/test.js @@ -37,9 +37,7 @@ Object.keys(cases).forEach((name) => { const description = cases[name]; const scopedNameGenerator = - name === "interpolated" - ? "[name]__[local]___[hash:base64:5]" - : generateScopedName; + name === "interpolated" ? "[name]__[local]___[hash:base64:5]" : generateScopedName; const scopeBehaviour = name === behaviours.GLOBAL || name === "globalShorthand" @@ -82,21 +80,11 @@ Object.keys(cases).forEach((name) => { autoprefixer, createPlugin("validator-1", (root) => { if (rootsSeenBeforePlugin.has(root)) { - throw new Error( - "Plugin before ours was called multiple times." - ); + throw new Error("Plugin before ours was called multiple times."); } rootsSeenBeforePlugin.add(root); - root.prepend( - `/* validator-1-start (${path.basename( - root.source.input.file - )}) */` - ); - root.append( - `/* validator-1-end (${path.basename( - root.source.input.file - )}) */` - ); + root.prepend(`/* validator-1-start (${path.basename(root.source.input.file)}) */`); + root.append(`/* validator-1-end (${path.basename(root.source.input.file)}) */`); }), plugin({ scopeBehaviour, @@ -105,21 +93,11 @@ Object.keys(cases).forEach((name) => { }), createPlugin("validator-2", (root) => { if (rootsSeenAfterPlugin.has(root)) { - throw new Error( - "Plugin after ours was called multiple times." - ); + throw new Error("Plugin after ours was called multiple times."); } rootsSeenAfterPlugin.add(root); - root.prepend( - `/* validator-2-start (${path.basename( - root.source.input.file - )}) */` - ); - root.append( - `/* validator-2-end (${path.basename( - root.source.input.file - )}) */` - ); + root.prepend(`/* validator-2-start (${path.basename(root.source.input.file)}) */`); + root.append(`/* validator-2-end (${path.basename(root.source.input.file)}) */`); }), ]; @@ -127,9 +105,7 @@ Object.keys(cases).forEach((name) => { from: sourceFile, }); - expect(result.css).toMatchSnapshot( - `plugins once - ${description} - CSS` - ); + expect(result.css).toMatchSnapshot(`plugins once - ${description} - CSS`); }); }); @@ -194,9 +170,9 @@ it("processes localsConvention with camelCase option", async () => { if (fs.existsSync(jsonFile)) fs.unlinkSync(jsonFile); - await postcss([ - plugin({ generateScopedName, localsConvention: "camelCase" }), - ]).process(source, { from: sourceFile }); + await postcss([plugin({ generateScopedName, localsConvention: "camelCase" })]).process(source, { + from: sourceFile, + }); const json = fs.readFileSync(jsonFile).toString(); fs.unlinkSync(jsonFile); @@ -239,9 +215,9 @@ it("processes localsConvention with dashes option", async () => { if (fs.existsSync(jsonFile)) fs.unlinkSync(jsonFile); - await postcss([ - plugin({ generateScopedName, localsConvention: "dashes" }), - ]).process(source, { from: sourceFile }); + await postcss([plugin({ generateScopedName, localsConvention: "dashes" })]).process(source, { + from: sourceFile, + }); const json = fs.readFileSync(jsonFile).toString(); fs.unlinkSync(jsonFile); @@ -262,9 +238,9 @@ it("processes localsConvention with dashes option", async () => { if (fs.existsSync(jsonFile)) fs.unlinkSync(jsonFile); - await postcss([ - plugin({ generateScopedName, localsConvention: "dashes" }), - ]).process(source, { from: sourceFile }); + await postcss([plugin({ generateScopedName, localsConvention: "dashes" })]).process(source, { + from: sourceFile, + }); const json = fs.readFileSync(jsonFile).toString(); fs.unlinkSync(jsonFile); @@ -383,9 +359,7 @@ it("exposes export tokens for other plugins", async () => { from: sourceFile, }); - expect(result.messages).toMatchSnapshot( - "exposes export tokens for other plugins" - ); + expect(result.messages).toMatchSnapshot("exposes export tokens for other plugins"); }); it("processes exportGlobals option", async () => {