Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/css/out/entry.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ body {
color: white;
}

/* postcss:reset.css */
/* postcss:./reset.css */
body {
color: black;
background: white;
Expand Down
23 changes: 1 addition & 22 deletions postcss.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,30 +99,9 @@ describe("css", () => {
describe("modules", () => {
const rootDir = path.resolve("./examples/modules");

it("modules set to false", async () => {
const result = await build("modules", ["./disabled.css"], {
plugins: [postCSSPlugin({ modules: false })],
});
assertObjectMatch(result, {
errors: [],
warnings: [],
});
assertGreaterOrEqual(result.outputFiles.length, 1);
const outFilePath = path.resolve(rootDir, "out/disabled.css");
assertEquals(
result.outputFiles[0].path,
outFilePath,
);
assertEquals(
result.outputFiles[0].text,
await Deno.readTextFile(outFilePath),
);
assertEquals(result.outputFiles.length, 1);
});

it("modules defaults to true", async (t) => {
const result = await build("modules", ["./main.module.css"], {
plugins: [postCSSPlugin({ modules: true })],
plugins: [postCSSPlugin()],
});
assertObjectMatch(result, {
errors: [],
Expand Down
16 changes: 12 additions & 4 deletions postcss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,19 @@ export const postCSSPlugin = (
}

const absolutePath = path.resolve(args.resolveDir, args.path);
const relativePath = path.relative(
build.initialOptions.absWorkingDir ?? Deno.cwd(),
absolutePath,
);
const stylesheetId = Deno.build.os === "windows"
? relativePath.replaceAll("\\", "/")
: relativePath;
const ext = path.extname(absolutePath);
const sourceBaseName = path.basename(absolutePath, ext);
const module = isModule
? isModule(absolutePath)
: sourceBaseName.match(/\.module$/);
const module = modules !== false &&
(isModule
? isModule(absolutePath)
: /\.module$/.test(sourceBaseName));

const fileContent = await Deno.readTextFile(absolutePath);
let css = ext === ".css" ? fileContent : "";
Expand Down Expand Up @@ -287,7 +295,7 @@ export const postCSSPlugin = (

return {
namespace: module ? "postcss-module" : "postcss",
path: args.path,
path: `./${stylesheetId}`,
watchFiles,
pluginData: {
resolveDir: args.resolveDir,
Expand Down
91 changes: 91 additions & 0 deletions resolution.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import {
assertEquals,
assertNotEquals,
assertRejects,
assertStringIncludes,
} from "@std/assert";
import * as path from "@std/path";
import { describe, it } from "@std/testing/bdd";

import { postCSSPlugin } from "./postcss.ts";
import { build } from "./test-utils.ts";

describe("stylesheet identity and module selection", () => {
for (const filename of ["styles.css", "styles.module.css"]) {
it(`keeps both ${filename} imports when they belong to different directories`, async () => {
const root = await Deno.makeTempDir({ prefix: "postcss identity " });
try {
for (
const [directory, color] of [["first", "red"], ["second", "blue"]]
) {
await Deno.mkdir(path.join(root, directory));
await Deno.writeTextFile(
path.join(root, directory, filename),
`.box { color: ${color}; }`,
);
await Deno.writeTextFile(
path.join(root, directory, "index.ts"),
`export * from "./${filename}";`,
);
}
await Deno.writeTextFile(
path.join(root, "main.ts"),
`
import * as first from "./first/index.ts";
import * as second from "./second/index.ts";
export const styles = [first.css, second.css];
${
filename.includes(".module")
? "export const classes = [first.box, second.box];"
: ""
}
`,
);
const result = await build("", ["main.ts"], {
absWorkingDir: root,
bundle: true,
plugins: [postCSSPlugin()],
});
const output = await import(
`data:application/javascript,${
encodeURIComponent(result.outputFiles[0].text)
}`
);
assertStringIncludes(output.styles[0], "red");
assertStringIncludes(output.styles[1], "blue");
if (filename.includes(".module")) {
assertNotEquals(output.classes[0], output.classes[1]);
}
} finally {
await Deno.remove(root, { recursive: true });
}
});
}

for (const customSelector of [false, true]) {
it(`disables module rewriting and JSON output with ${customSelector ? "a custom selector" : "the filename convention"}`, async () => {
const root = await Deno.makeTempDir({ prefix: "postcss disabled " });
try {
const file = path.join(root, "styles.module.css");
await Deno.writeTextFile(file, ".original { color: red; }");
const result = await build("", [file], {
absWorkingDir: root,
plugins: [
postCSSPlugin({
modules: false,
...(customSelector ? { isModule: () => true } : {}),
}),
],
});
assertStringIncludes(result.outputFiles[0].text, ".original {");
assertEquals(result.errors, []);
await assertRejects(
() => Deno.stat(`${file}.json`),
Deno.errors.NotFound,
);
} finally {
await Deno.remove(root, { recursive: true });
}
});
}
});
Loading