Skip to content

Commit

Permalink
perf(modules): simpler internal implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Anidetrix committed Jun 17, 2020
1 parent e68c1b3 commit c1f92e1
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 40 deletions.
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default (options: Options = {}): Plugin => {
name: "styles",

buildStart(opts) {
preserveModules = Boolean(opts.preserveModules);
preserveModules = opts.preserveModules;
},

async transform(code, id) {
Expand Down
14 changes: 5 additions & 9 deletions src/loaders/postcss/icss/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import postcss from "postcss";
import { extractICSS, replaceSymbols, replaceValueSymbols } from "icss-utils";
import { ModulesOptions } from "../modules";
import loadDefault, { Load } from "./load";
import resolve from "./resolve";

Expand All @@ -9,7 +8,6 @@ const extensionsDefault = [".css", ".pcss", ".postcss", ".sss"];

export interface InteroperableCSSOptions {
load?: Load;
getReplacements?: ModulesOptions["getReplacements"];
extensions?: string[];
}

Expand Down Expand Up @@ -38,15 +36,13 @@ const plugin: postcss.Plugin<InteroperableCSSOptions> = postcss.plugin(

replaceSymbols(css, imports);

const exports: Record<string, string> = {};
for (const [k, v] of Object.entries(icssExports)) {
exports[k] = replaceValueSymbols(v, imports);
res.messages.push({
plugin: name,
type: "icss",
export: { [k]: replaceValueSymbols(v, imports) },
});
}

res.messages.push({ plugin: name, type: "icss", exports });

if (typeof options.getReplacements === "function")
options.getReplacements(css.source.input.file, exports, opts.to);
},
);

Expand Down
2 changes: 1 addition & 1 deletion src/loaders/postcss/icss/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const load: Load = async (url, file, extensions, processor, opts) => {
const exports: Record<string, string> = {};
for (const msg of messages) {
if (msg.type !== "icss") continue;
Object.assign(exports, msg.exports as Record<string, string>);
Object.assign(exports, msg.export as Record<string, string>);
}

return exports;
Expand Down
48 changes: 21 additions & 27 deletions src/loaders/postcss/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const loader: Loader<PostCSSLoaderOptions> = {
const plugins: (postcss.Transformer | postcss.Processor)[] = [];
const autoModules = ensureAutoModules(options.autoModules, this.id);
const supportModules = Boolean(options.modules || autoModules);
const modulesExports: Record<string, Record<string, string>> = {};
const modulesExports: Record<string, string> = {};

const postcssOpts: PostCSSOptions = {
...config.options,
Expand Down Expand Up @@ -99,18 +99,7 @@ const loader: Loader<PostCSSLoaderOptions> = {
failOnWrongOrder: true,
...modulesOptions,
}),
postcssICSS({
extensions: options.extensions,
getReplacements(file, replacements, out) {
modulesExports[file] = replacements;
if (
typeof options.modules === "object" &&
typeof options.modules.getReplacements === "function"
) {
return options.modules.getReplacements(file, replacements, out);
}
},
}),
postcssICSS({ extensions: options.extensions }),
);
}

Expand All @@ -122,14 +111,21 @@ const loader: Loader<PostCSSLoaderOptions> = {

const res = await postcss(plugins).process(code, postcssOpts);

for (const warning of res.warnings())
this.warn({ name: warning.plugin, message: warning.text });

const deps = res.messages.filter(msg => msg.type === "dependency");
for (const dep of deps) this.deps.add(normalizePath(dep.file));

const assets = res.messages.filter(msg => msg.type === "asset");
for (const asset of assets) this.assets.set(asset.to, asset.source);
for (const msg of res.messages)
switch (msg.type) {
case "warning":
this.warn({ name: msg.plugin, message: msg.text as string });
break;
case "icss":
Object.assign(modulesExports, msg.export as Record<string, string>);
break;
case "dependency":
this.deps.add(normalizePath(msg.file));
break;
case "asset":
this.assets.set(msg.to, msg.source);
break;
}

map = mm((res.map?.toJSON() as unknown) as RawSourceMap)
.resolve(path.dirname(postcssOpts.to))
Expand All @@ -149,26 +145,24 @@ const loader: Loader<PostCSSLoaderOptions> = {

const output = [
`const ${cssVarName} = ${JSON.stringify(res.css)}`,
`const ${modulesVarName} = ${JSON.stringify(modulesExports[this.id] ?? {})}`,
`const ${modulesVarName} = ${JSON.stringify(modulesExports)}`,
`export const css = ${cssVarName}`,
`export default ${supportModules ? modulesVarName : cssVarName}`,
];

if (options.namedExports) {
const json = modulesExports[this.id];

const getClassName =
typeof options.namedExports === "function" ? options.namedExports : getClassNameDefault;

for (const name in json) {
for (const name in modulesExports) {
const newName = getClassName(name);

if (name !== newName)
this.warn(`Exported \`${name}\` as \`${newName}\` in ${humanlizePath(this.id)}`);

if (!json[newName]) json[newName] = json[name];
if (!modulesExports[newName]) modulesExports[newName] = modulesExports[name];

output.push(`export const ${newName} = ${JSON.stringify(json[name])}`);
output.push(`export const ${newName} = ${JSON.stringify(modulesExports[name])}`);
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/loaders/postcss/modules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ export interface ModulesOptions {
* @default "[name]_[local]__[hash:8]"
*/
generateScopedName?: string | ((name: string, file: string, css: string) => string);
/** Function for resulting replacements extraction */
getReplacements?: (file: string, replacements: Record<string, string>, out?: string) => void;
}

export default (options: ModulesOptions): (postcss.Transformer | postcss.Processor)[] => {
Expand Down

0 comments on commit c1f92e1

Please sign in to comment.