@@ -17,13 +17,12 @@ const {
17
17
} = require ( './utils.js' ) ;
18
18
const cssHandler = require ( '@parcel/css' ) ;
19
19
const camelCase = require ( 'lodash/camelCase' ) ;
20
- const { v4 } = require ( 'uuid' ) ;
21
- const cache = require ( './cache.js' ) ;
20
+ const BuildCache = require ( './cache.js' ) ;
22
21
23
22
/**
24
23
* buildCssModulesJs
25
24
* @param {{fullPath: string; options: import('..').Options; digest: string; build: import('..').Build} } params
26
- * @returns {Promise<{resolveDir: string; js: string; css: string; exports: Record<string, string>}> }
25
+ * @returns {Promise<{resolveDir: string; js: string; css: string; originCss: string; exports: Record<string, string>}> }
27
26
*/
28
27
const buildCssModulesJs = async ( { fullPath, options, build } ) => {
29
28
const cssFileName = path . basename ( fullPath ) ; // e.g. xxx.module.css?esbuild-css-modules-plugin-building
@@ -93,11 +92,39 @@ export default new Proxy(${classNamesMapString}, {
93
92
return {
94
93
js,
95
94
css : cssWithSourceMap ,
95
+ originCss : originCss . toString ( 'utf8' ) ,
96
96
exports,
97
97
resolveDir
98
98
} ;
99
99
} ;
100
100
101
+ /**
102
+ * prepareBuild
103
+ * @param {import('..').Build } build
104
+ * @param {import('..').Options } options
105
+ * @return {Promise<void> }
106
+ */
107
+ const prepareBuild = async ( build , options ) => {
108
+ const buildId = getBuildId ( build ) ;
109
+ build . initialOptions . metafile = true ;
110
+ const packageRoot = options . root ;
111
+ const buildRoot = getRootDir ( build ) ;
112
+ const log = getLogger ( build ) ;
113
+ const cache = new BuildCache ( log ) ;
114
+ const relative = ( to ) => getRelativePath ( build , to ) ;
115
+
116
+ log ( `root of this build(#${ buildId } ):` , buildRoot ) ;
117
+
118
+ build . context = {
119
+ buildId,
120
+ buildRoot,
121
+ packageRoot,
122
+ log,
123
+ relative,
124
+ cache
125
+ } ;
126
+ } ;
127
+
101
128
/**
102
129
* onResolveModulesCss
103
130
* @description mark module(s).css as sideEffects and add namespace
@@ -146,24 +173,25 @@ const onResolveModulesCss = async (args, build) => {
146
173
*/
147
174
const onLoadModulesCss = async ( build , options , args ) => {
148
175
const { path : maybeFullPath , pluginData = { } } = args ;
149
- const { buildRoot, log, relative } = build . context ;
176
+ const { buildRoot, log, cache } = build . context ;
150
177
const absPath = path . isAbsolute ( maybeFullPath )
151
178
? maybeFullPath
152
179
: path . resolve ( buildRoot , maybeFullPath ) ;
153
- const rpath = relative ( absPath ) ;
180
+ const rpath = pluginData . relativePathToBuildRoot ;
154
181
155
- log ( `loading ${ relative ( args . path ) } ${ args . suffix } ` ) ;
182
+ log ( `loading ${ rpath } ${ args . suffix } ` ) ;
156
183
157
- const cached = cache . get ( absPath ) ;
184
+ log ( `checking cache for` , absPath ) ;
185
+ const cached = await cache . get ( absPath ) ;
158
186
if ( cached ) {
159
- log ( 'return built cache for' , rpath ) ;
187
+ log ( 'return build cache for' , rpath ) ;
160
188
return cached ;
161
189
}
162
190
163
191
const hex = createHash ( 'sha256' ) . update ( rpath ) . digest ( 'hex' ) ;
164
192
const digest = hex . slice ( hex . length - 255 , hex . length ) ;
165
193
166
- const { js, resolveDir, css, exports } = await buildCssModulesJs ( {
194
+ const { js, resolveDir, css, exports, originCss } = await buildCssModulesJs ( {
167
195
fullPath : absPath ,
168
196
options,
169
197
digest,
@@ -182,7 +210,62 @@ const onLoadModulesCss = async (build, options, args) => {
182
210
contents : js ,
183
211
loader : 'js'
184
212
} ;
185
- cache . set ( absPath , result ) ;
213
+ await cache . set ( absPath , result , originCss ) ;
214
+ log ( `add build result to cache for ${ absPath } ` ) ;
215
+
216
+ return result ;
217
+ } ;
218
+
219
+ /**
220
+ * onResolveBuiltModulesCss
221
+ * @param {import('esbuild').OnResolveArgs } args
222
+ * @param {import('..').Build } build
223
+ * @returns {Promise<import('esbuild').OnResolveResult> }
224
+ */
225
+ const onResolveBuiltModulesCss = async ( args , build ) => {
226
+ const { path : p , pluginData = { } } = args ;
227
+ const { relativePathToBuildRoot } = pluginData ;
228
+
229
+ build . context ?. log ( `resolve virtual path ${ p } to ${ relativePathToBuildRoot } ${ builtCssSuffix } ` ) ;
230
+
231
+ /**
232
+ * @type {import('esbuild').OnResolveResult }
233
+ */
234
+ const result = {
235
+ namespace : pluginNamespace ,
236
+ path : relativePathToBuildRoot + builtCssSuffix ,
237
+ external : false ,
238
+ pluginData,
239
+ sideEffects : true ,
240
+ pluginName
241
+ } ;
242
+
243
+ return result ;
244
+ } ;
245
+
246
+ /**
247
+ * onLoadBuiltModulesCss
248
+ * @param {import('esbuild').OnLoadArgs } args
249
+ * @param {import('..').Build } build
250
+ * @returns {Promise<import('esbuild').OnLoadResult> }
251
+ */
252
+ const onLoadBuiltModulesCss = async ( { pluginData } , build ) => {
253
+ const { log, buildRoot } = build . context ;
254
+ const { css, relativePathToBuildRoot } = pluginData ;
255
+ const absPath = path . resolve ( buildRoot , relativePathToBuildRoot ) ;
256
+ const resolveDir = path . dirname ( absPath ) ;
257
+ log ( 'loading built css for' , relativePathToBuildRoot ) ;
258
+
259
+ /**
260
+ * @type {import('esbuild').OnLoadResult }
261
+ */
262
+ const result = {
263
+ contents : css ,
264
+ loader : 'css' ,
265
+ pluginName,
266
+ resolveDir,
267
+ pluginData
268
+ } ;
186
269
187
270
return result ;
188
271
} ;
@@ -194,8 +277,9 @@ const onLoadModulesCss = async (build, options, args) => {
194
277
* @param {import('esbuild').BuildResult } result
195
278
*/
196
279
const onEnd = async ( build , options , result ) => {
197
- const { buildId, buildRoot } = build . context ;
280
+ const { buildId, buildRoot, cache } = build . context ;
198
281
const log = getLogger ( build ) ;
282
+ log ( 'done' ) ;
199
283
200
284
if ( options . inject === true || typeof options . inject === 'string' ) {
201
285
const cssContents = [ ] ;
@@ -239,84 +323,6 @@ const onEnd = async (build, options, result) => {
239
323
}
240
324
} ;
241
325
242
- /**
243
- * prepareBuild
244
- * @param {import('..').Build } build
245
- * @param {import('..').Options } options
246
- * @return {Promise<void> }
247
- */
248
- const prepareBuild = async ( build , options ) => {
249
- const buildId = getBuildId ( build ) ;
250
- build . initialOptions . metafile = true ;
251
- const packageRoot = options . root ;
252
- const buildRoot = getRootDir ( build ) ;
253
- const log = getLogger ( build ) ;
254
- const relative = ( to ) => getRelativePath ( build , to ) ;
255
-
256
- log ( `root of this build(#${ buildId } ):` , buildRoot ) ;
257
-
258
- build . context = {
259
- buildId,
260
- buildRoot,
261
- packageRoot,
262
- log,
263
- relative
264
- } ;
265
- } ;
266
-
267
- /**
268
- * onLoadBuiltModulesCss
269
- * @param {import('esbuild').OnLoadArgs } args
270
- * @param {import('..').Build } build
271
- * @returns {Promise<import('esbuild').OnLoadResult> }
272
- */
273
- const onLoadBuiltModulesCss = async ( { pluginData } , build ) => {
274
- const { log, buildRoot } = build . context ;
275
- const { css, relativePathToBuildRoot } = pluginData ;
276
- const absPath = path . resolve ( buildRoot , relativePathToBuildRoot ) ;
277
- const resolveDir = path . dirname ( absPath ) ;
278
- log ( 'loading built css for' , relativePathToBuildRoot ) ;
279
-
280
- /**
281
- * @type {import('esbuild').OnLoadResult }
282
- */
283
- const result = {
284
- contents : css ,
285
- loader : 'css' ,
286
- pluginName,
287
- resolveDir,
288
- pluginData
289
- } ;
290
-
291
- return result ;
292
- } ;
293
-
294
- /**
295
- * onResolveBuiltModulesCss
296
- * @param {import('esbuild').OnResolveArgs } args
297
- * @param {import('..').Build } build
298
- * @returns {Promise<import('esbuild').OnResolveResult> }
299
- */
300
- const onResolveBuiltModulesCss = async ( args , build ) => {
301
- const { path : p , pluginData = { } } = args ;
302
-
303
- build . context ?. log ( `resolve built css: ${ args . path } ` ) ;
304
-
305
- /**
306
- * @type {import('esbuild').OnResolveResult }
307
- */
308
- const result = {
309
- namespace : pluginNamespace ,
310
- path : p ,
311
- external : false ,
312
- pluginData,
313
- sideEffects : true ,
314
- pluginName
315
- } ;
316
-
317
- return result ;
318
- } ;
319
-
320
326
/**
321
327
* setup
322
328
* @param {import('..').Build } build
@@ -326,14 +332,17 @@ const onResolveBuiltModulesCss = async (args, build) => {
326
332
const setup = async ( build , options ) => {
327
333
await prepareBuild ( build , options ) ;
328
334
335
+ // resolve xxx.module.css to xxx.module.css?esbuild-css-modules-plugin-building
329
336
build . onResolve ( { filter : modulesCssRegExp , namespace : 'file' } , async ( args ) => {
330
337
return await onResolveModulesCss ( args , build ) ;
331
338
} ) ;
332
339
340
+ // load xxx.module.css?esbuild-css-modules-plugin-building
333
341
build . onLoad ( { filter : modulesCssRegExp , namespace : pluginNamespace } , async ( args ) => {
334
342
return await onLoadModulesCss ( build , options , args ) ;
335
343
} ) ;
336
344
345
+ // resolve virtual path xxx.module.css?esbuild-css-modules-plugin-built
337
346
build . onResolve (
338
347
{
339
348
filter : builtModulesCssRegExp ,
@@ -344,6 +353,7 @@ const setup = async (build, options) => {
344
353
}
345
354
) ;
346
355
356
+ // load virtual path xxx.module.css?esbuild-css-modules-plugin-built
347
357
build . onLoad (
348
358
{
349
359
filter : builtModulesCssRegExp ,
0 commit comments