11diff --git a/node_modules/@greenwood/plugin-css-modules/src/index.js b/node_modules/@greenwood/plugin-css-modules/src/index.js
2- index e2f5928..075a350 100644
2+ index e2f5928..56ff4f2 100644
33--- a/node_modules/@greenwood/plugin-css-modules/src/index.js
44+++ b/node_modules/@greenwood/plugin-css-modules/src/index.js
55@@ -4,6 +4,7 @@
@@ -10,42 +10,33 @@ index e2f5928..075a350 100644
1010 import { parse as hparse } from "node-html-parser";
1111 import { parse, walk } from "css-tree";
1212 import * as acornWalk from "acorn-walk";
13- @@ -11,7 +12,8 @@ import * as acorn from "acorn";
13+ @@ -11,24 +12,7 @@ import * as acorn from "acorn";
1414 import { hashString } from "@greenwood/cli/src/lib/hashing-utils.js";
1515 import { ACORN_OPTIONS } from "@greenwood/cli/src/lib/parsing-utils.js";
1616
1717- const MODULES_MAP_FILENAME = "__css-modules-map.json";
18- + const MODULES_MAP_DIR_NAME = "__css-modules-map";
19- + // const MODULES_MAP_FILENAME = "__css-modules-map.json";
20- /*
21- * we have to write the modules map to a file to preserve the state between static and SSR / prerendering
22- * since if we try and do something like `globalThis.cssModulesMap = globalThis.cssModulesMap ?? {}`
23- @@ -19,16 +21,16 @@ const MODULES_MAP_FILENAME = "__css-modules-map.json";
24- *
25- * https://github.com/ProjectEvergreen/greenwood/discussions/1117
26- */
18+ - /*
19+ - * we have to write the modules map to a file to preserve the state between static and SSR / prerendering
20+ - * since if we try and do something like `globalThis.cssModulesMap = globalThis.cssModulesMap ?? {}`
21+ - * it won't persist across Worker threads. Maybe if we find a solution to this, we would handle this all in memory.
22+ - *
23+ - * https://github.com/ProjectEvergreen/greenwood/discussions/1117
24+ - */
2725- function getCssModulesMap(compilation) {
2826- const locationUrl = new URL(`./${MODULES_MAP_FILENAME}`, compilation.context.scratchDir);
2927- let cssModulesMap = {};
30- + // function getCssModulesMap(compilation) {
31- + // const locationUrl = new URL(`./${MODULES_MAP_FILENAME}`, compilation.context.scratchDir);
32- + // let cssModulesMap = {};
33-
28+ -
3429- if (fs.existsSync(locationUrl)) {
3530- cssModulesMap = JSON.parse(fs.readFileSync(locationUrl, "utf-8"));
3631- }
37- + // if (fs.existsSync(locationUrl)) {
38- + // cssModulesMap = JSON.parse(fs.readFileSync(locationUrl, "utf-8"));
39- + // }
40-
32+ -
4133- return cssModulesMap;
4234- }
43- + // return cssModulesMap;
44- + // }
35+ + const MODULES_MAP_DIR_NAME = "__css-modules-map";
4536
4637 async function getTransformedScriptContents(scriptUrl, compilation) {
4738 const resourcePlugins = compilation.config.plugins
48- @@ -74,7 +76 ,7 @@ async function getTransformedScriptContents(scriptUrl, compilation) {
39+ @@ -74,7 +58 ,7 @@ async function getTransformedScriptContents(scriptUrl, compilation) {
4940 return await response.text();
5041 }
5142
@@ -54,80 +45,53 @@ index e2f5928..075a350 100644
5445 const scriptContents = await getTransformedScriptContents(scriptUrl, compilation);
5546 const additionalScripts = [];
5647
57- @@ -140,20 +142,63 @@ async function walkAllImportsForCssModules(scriptUrl, sheets, compilation) {
48+ @@ -140,19 +124,34 @@ async function walkAllImportsForCssModules(scriptUrl, sheets, compilation) {
5849 },
5950 });
6051
6152- const cssModulesMap = getCssModulesMap(compilation);
62- + // TODO better truncate name
63- + const ouputPathUrl = new URL(`./${MODULES_MAP_DIR_NAME}${scriptUrl.pathname}.json`, compilation.context.scratchDir);
53+ + const outputPathUrl = new URL(
54+ + `./${MODULES_MAP_DIR_NAME}/${hashString(scriptUrl.pathname)}.map.json`,
55+ + compilation.context.scratchDir,
56+ + );
6457+
65- + // console.log({ ouputPathUrl })
66- + if (!fs.existsSync(ouputPathUrl)) {
67- + fs.mkdirSync(path.dirname(ouputPathUrl.pathname), { recursive: true });
58+ + if (!fs.existsSync(outputPathUrl)) {
59+ + fs.mkdirSync(path.dirname(scriptUrl.pathname), { recursive: true });
6860+ }
6961+
70- + cssModulesMap[ouputPathUrl] = {
62+ + const moduleContents = {
7163+ module: classNameMap,
7264+ contents: scopedCssContents,
7365+ importer: scriptUrl,
7466+ identifier,
75- + }
67+ + };
68+ +
69+ + cssModulesMap[outputPathUrl] = moduleContents;
70+ +
71+ + // output one file for transforming imports from CSS -> ESM
72+ + fs.writeFileSync(outputPathUrl, JSON.stringify(moduleContents));
7673
74+ + // output one file for SSR / prerendering handling in loaders as ESM
7775 fs.writeFileSync(
7876- new URL(`./${MODULES_MAP_FILENAME}`, compilation.context.scratchDir),
79- + new URL(`./${MODULES_MAP_DIR_NAME}${cssModuleUrl.pathname}.json`, compilation.context.scratchDir),
80- JSON.stringify({
77+ - JSON.stringify({
8178- ...cssModulesMap,
8279- [`${cssModuleUrl.href}`]: {
8380- module: classNameMap,
8481- contents: scopedCssContents,
8582- importer: scriptUrl,
8683- identifier,
8784- },
88- + module: classNameMap,
89- + contents: scopedCssContents,
90- + importer: scriptUrl,
91- + identifier,
92- + }),
93- + )
94- +
95- + fs.writeFileSync(
96- + ouputPathUrl,
97- + JSON.stringify({
98- + module: classNameMap,
99- + contents: scopedCssContents,
100- + importer: scriptUrl,
101- + identifier,
102- }),
85+ - }),
86+ + new URL(
87+ + `./${MODULES_MAP_DIR_NAME}/${hashString(cssModuleUrl.pathname)}.module.json`,
88+ + compilation.context.scratchDir,
89+ + ),
90+ + JSON.stringify(moduleContents),
10391 );
104- +
105- + fs.writeFileSync(
106- + ouputPathUrl,
107- + JSON.stringify({
108- + module: classNameMap,
109- + contents: scopedCssContents,
110- + importer: scriptUrl,
111- + identifier,
112- + }),
113- + );
114- +
115- + // fs.writeFileSync(
116- + // new URL(`./${MODULES_MAP_FILENAME}`, compilation.context.scratchDir),
117- + // JSON.stringify({
118- + // ...cssModulesMap,
119- + // [`${cssModuleUrl.href}`]: {
120- + // module: classNameMap,
121- + // contents: scopedCssContents,
122- + // importer: scriptUrl,
123- + // identifier,
124- + // },
125- + // }),
126- + // );
12792 } else {
12893 const recursiveScriptUrl = new URL(value, scriptUrl);
129-
130- @@ -165,8 +210,10 @@ async function walkAllImportsForCssModules(scriptUrl, sheets, compilation) {
94+ @@ -165,8 +164,10 @@ async function walkAllImportsForCssModules(scriptUrl, sheets, compilation) {
13195 });
13296
13397 for (const script of additionalScripts) {
@@ -139,46 +103,36 @@ index e2f5928..075a350 100644
139103 }
140104
141105 // this happens 'first' as the HTML is returned, to find viable references to CSS Modules
142- @@ -179,34 +226,40 @@ class ScanForCssModulesResource {
106+ @@ -178,35 +179,28 @@ class ScanForCssModulesResource {
107+ this.contentType = "text/javascript";
143108 const { scratchDir } = this.compilation.context;
144109
145- if (
110+ - if (
146111- fs.existsSync(scratchDir) &&
147112- !fs.existsSync(new URL(`./${MODULES_MAP_FILENAME}`, scratchDir))
148- + !fs.existsSync(new URL(`./${MODULES_MAP_DIR_NAME}/`, scratchDir))
149- ) {
113+ - ) {
150114- fs.writeFileSync(new URL(`./${MODULES_MAP_FILENAME}`, scratchDir), JSON.stringify({}));
115+ + if (!fs.existsSync(new URL(`./${MODULES_MAP_DIR_NAME}/`, scratchDir))) {
151116+ fs.mkdirSync(new URL(`./${MODULES_MAP_DIR_NAME}/`, scratchDir), { recursive: true });
152117 }
153- + // if (
154- + // fs.existsSync(scratchDir) &&
155- + // !fs.existsSync(new URL(`./${MODULES_MAP_FILENAME}`, scratchDir))
156- + // ) {
157- + // fs.writeFileSync(new URL(`./${MODULES_MAP_FILENAME}`, scratchDir), JSON.stringify({}));
158- + // }
159118 }
160119
161120 async shouldIntercept(url) {
162121 const { pathname, protocol } = url;
163122- const mapKey = `${protocol}//${pathname}`;
164123- const cssModulesMap = getCssModulesMap(this.compilation);
165- + // const mapKey = `${protocol}//${pathname}`;
166- + // const cssModulesMap = getCssModulesMap(this.compilation);
167124
168125 return (
169126- url.pathname.endsWith("/") ||
170127- (protocol === "file:" && pathname.endsWith(this.extensions[0]) && cssModulesMap[mapKey])
171- + url.pathname.endsWith("/")
172- + || (protocol === "file:" && pathname.endsWith(this.extensions[0]))
128+ + url.pathname.endsWith("/") || (protocol === "file:" && pathname.endsWith(this.extensions[0]))
173129 );
174130 }
175131
176132 async intercept(url, request, response) {
177133 const { pathname, protocol } = url;
178134- const mapKey = `${protocol}//${pathname}`;
179135- const cssModulesMap = getCssModulesMap(this.compilation);
180- + // const mapKey = `${protocol}//${pathname}`;
181- + // const cssModulesMap = getCssModulesMap(this.compilation);
182136
183137 if (url.pathname.endsWith("/")) {
184138 const body = await response.text();
@@ -189,100 +143,110 @@ index e2f5928..075a350 100644
189143
190144 for (const script of scripts) {
191145 const type = script.getAttribute("type") ?? "";
192- @@ -219,12 +272,13 @@ class ScanForCssModulesResource {
146+ @@ -219,12 +213,15 @@ class ScanForCssModulesResource {
193147 this.compilation.context.userWorkspace,
194148 );
195149
196150- await walkAllImportsForCssModules(scriptUrl, sheets, this.compilation);
197- + cssModulesMap = await walkAllImportsForCssModules(cssModulesMap, scriptUrl, sheets, this.compilation);
151+ + cssModulesMap = await walkAllImportsForCssModules(
152+ + cssModulesMap,
153+ + scriptUrl,
154+ + sheets,
155+ + this.compilation,
156+ + );
198157 }
199158 }
200159
201160- const cssModulesMap = getCssModulesMap(this.compilation);
202- + // const cssModulesMap = getCssModulesMap(this.compilation);
203-
204- + // console.log('&&&&&', { cssModulesMap });
161+ -
205162 Object.keys(cssModulesMap).forEach((key) => {
206163 sheets.push(cssModulesMap[key].contents);
207164 });
208- @@ -242,11 +296,14 @@ class ScanForCssModulesResource {
165+ @@ -240,13 +237,18 @@ class ScanForCssModulesResource {
166+ );
167+
209168 return new Response(newBody);
210- } else if (
211- protocol === "file:" &&
169+ - } else if (
170+ - protocol === "file:" &&
212171- pathname.endsWith(this.extensions[0]) &&
213172- cssModulesMap[mapKey]
214- + pathname.endsWith(this.extensions[0])
215- ) {
216- + console.log('herehehre?')
217- + const cssModulesMap = JSON.parse(fs.readFileSync(new URL(`./${MODULES_MAP_DIR_NAME}${url.pathname}.json`, this.compilation.context.scratchDir)));
218- + const { identifier, module } = cssModulesMap
219- +
173+ - ) {
174+ + } else if (protocol === "file:" && pathname.endsWith(this.extensions[0])) {
220175 // handle this primarily for SSR / prerendering use case
221176- const cssModule = `export default ${JSON.stringify(cssModulesMap[mapKey].module)}`;
177+ + const cssModulesMap = JSON.parse(
178+ + fs.readFileSync(
179+ + new URL(
180+ + `./${MODULES_MAP_DIR_NAME}/${hashString(url.pathname)}.module.json`,
181+ + this.compilation.context.scratchDir,
182+ + ),
183+ + ),
184+ + );
185+ + const { module } = cssModulesMap;
222186+ const cssModule = `export default ${JSON.stringify(module)}`;
223187
224188 return new Response(cssModule, {
225189 headers: {
226- @@ -267,16 +324,21 @@ class StripCssModulesResource {
190+ @@ -267,13 +269,9 @@ class StripCssModulesResource {
227191 }
228192
229193 async shouldIntercept(url) {
230194- const cssModulesMap = getCssModulesMap(this.compilation);
231- + // console.log('StripCssModulesResource intercept url => ??? ', { url });
232- + // console.log('??', new URL(`./${MODULES_MAP_DIR_NAME}${url.pathname}.json`, this.compilation.context.scratchDir));
233-
195+ -
234196- for (const [, value] of Object.entries(cssModulesMap)) {
235197- if (url.href === value.importer) {
236198- return true;
237199- }
238200- }
239- + return fs.existsSync(new URL(`./${MODULES_MAP_DIR_NAME}${url.pathname}.json`, this.compilation.context.scratchDir));
240- + // const cssModulesMap = getCssModulesMap(this.compilation);
241- +
242- + // for (const [, value] of Object.entries(cssModulesMap)) {
243- + // if (url.href === value.importer) {
244- + // return true;
245- + // }
246- + // }
201+ + return fs.existsSync(
202+ + new URL(`./${MODULES_MAP_DIR_NAME}/${hashString(url.pathname)}.map.json`, this.compilation.context.scratchDir),
203+ + );
247204 }
248205
249206 async intercept(url, request, response) {
250- + // console.log('StripCssModulesResource intercept url $$$$ => ', url.pathname);
251- const { context } = this.compilation;
252- let contents = await response.text();
253-
254- @@ -287,12 +349,13 @@ class StripCssModulesResource {
207+ @@ -287,26 +285,25 @@ class StripCssModulesResource {
255208
256209 if (value.endsWith(".module.css") && specifiers.length === 1) {
257210 contents = `${contents.slice(0, start)} \n ${contents.slice(end)}`;
258211- const cssModulesMap = getCssModulesMap({ context });
259212-
260213- Object.values(cssModulesMap).forEach((value) => {
261214- const { importer, module, identifier } = value;
262- + const cssModulesMap = JSON.parse(fs.readFileSync(new URL(`./${MODULES_MAP_DIR_NAME}${url.pathname}.json`, context.scratchDir)));
263- + const { identifier, module } = cssModulesMap
264- + // console.log({cssModulesMap})
265- + // Object.values(cssModulesMap).forEach((value) => {
266- + // const { importer, module, identifier } = value;
267-
215+ -
268216- if (importer === url.href) {
269- + // if (importer === url.href) {
270- Object.keys(module).forEach((key) => {
271- const literalUsageRegex = new RegExp(String.raw`\$\{${identifier}.${key}\}`, "g");
272- // https://stackoverflow.com/a/20851557/417806
273- @@ -307,12 +370,13 @@ class StripCssModulesResource {
274- contents = contents.replace(expressionUsageRegex, `'${module[key]}'`);
275- }
276- });
277- - }
278- - });
279- + // }
280- + // });
217+ - Object.keys(module).forEach((key) => {
218+ - const literalUsageRegex = new RegExp(String.raw`\$\{${identifier}.${key}\}`, "g");
219+ - // https://stackoverflow.com/a/20851557/417806
220+ - const expressionUsageRegex = new RegExp(
221+ - String.raw`(((?<![-\w\d\W])|(?<=[> \n\r\b]))${identifier}\.${key}((?![-\w\d\W])|(?=[ <.,:;!?\n\r\b])))`,
222+ - "g",
223+ - );
224+ -
225+ - if (literalUsageRegex.test(contents)) {
226+ - contents = contents.replace(literalUsageRegex, module[key]);
227+ - } else if (expressionUsageRegex.test(contents)) {
228+ - contents = contents.replace(expressionUsageRegex, `'${module[key]}'`);
229+ - }
230+ - });
231+ + const cssModulesMap = JSON.parse(
232+ + fs.readFileSync(
233+ + new URL(`./${MODULES_MAP_DIR_NAME}/${hashString(url.pathname)}.map.json`, context.scratchDir),
234+ + ),
235+ + );
236+ + const { identifier, module } = cssModulesMap;
237+ +
238+ + Object.keys(module).forEach((key) => {
239+ + const literalUsageRegex = new RegExp(String.raw`\$\{${identifier}.${key}\}`, "g");
240+ + // https://stackoverflow.com/a/20851557/417806
241+ + const expressionUsageRegex = new RegExp(
242+ + String.raw`(((?<![-\w\d\W])|(?<=[> \n\r\b]))${identifier}\.${key}((?![-\w\d\W])|(?=[ <.,:;!?\n\r\b])))`,
243+ + "g",
244+ + );
245+ +
246+ + if (literalUsageRegex.test(contents)) {
247+ + contents = contents.replace(literalUsageRegex, module[key]);
248+ + } else if (expressionUsageRegex.test(contents)) {
249+ + contents = contents.replace(expressionUsageRegex, `'${module[key]}'`);
250+ }
251+ });
281252 }
282- },
283- });
284-
285- + // console.log('CONTENTS!!!!', { contents });
286- return new Response(contents);
287- }
288- }
0 commit comments