1
+ // @ts -check
1
2
/**
2
3
* Filesystem Cache
3
4
*
@@ -17,6 +18,26 @@ const { sync: findUpSync } = require("find-up");
17
18
const { env } = process ;
18
19
const transform = require ( "./transform" ) ;
19
20
const serialize = require ( "./serialize" ) ;
21
+ /**
22
+ * @typedef {object } FileSystemInfoEntry
23
+ * @property {number } safeTime
24
+ * @property {number } timestamp
25
+ */
26
+ /**
27
+ * @typedef {object } WebpackLogger
28
+ * @property {function(string): void } debug
29
+ * @property {function(string): void } info
30
+ * @property {function(string): void } warn
31
+ * @property {function(string): void } error
32
+ */
33
+ /**
34
+ * @typedef {object } WebpackHash
35
+ * @property {(data: string | Buffer, inputEncoding?: string) => WebpackHash } update
36
+ */
37
+
38
+ /**
39
+ * @type {string | null }
40
+ */
20
41
let defaultCacheDirectory = null ;
21
42
22
43
const gunzip = promisify ( zlib . gunzip ) ;
@@ -35,8 +56,8 @@ const findRootPackageJSON = () => {
35
56
* Read the contents from the compressed file.
36
57
*
37
58
* @async
38
- * @params {String } filename
39
- * @params {Boolean } compress
59
+ * @param { string } filename
60
+ * @param { boolean } compress
40
61
*/
41
62
const read = async function ( filename , compress ) {
42
63
const data = await readFile ( filename + ( compress ? ".gz" : "" ) ) ;
@@ -49,9 +70,9 @@ const read = async function (filename, compress) {
49
70
* Write contents into a compressed file.
50
71
*
51
72
* @async
52
- * @params {String } filename
53
- * @params {Boolean } compress
54
- * @params {String } result
73
+ * @param { string } filename
74
+ * @param { boolean } compress
75
+ * @param { any } result
55
76
*/
56
77
const write = async function ( filename , compress , result ) {
57
78
const content = JSON . stringify ( result ) ;
@@ -63,17 +84,23 @@ const write = async function (filename, compress, result) {
63
84
/**
64
85
* Build the filename for the cached file
65
86
*
66
- * @params {String} source File source code
67
- * @params {Object} options Options used
68
- *
69
- * @return {String }
87
+ * @param {string } source File source code
88
+ * @param {string } identifier Unique identifier to bust cache
89
+ * @param {Object } options Options used
90
+ * @param {any } hash Hash function returned by `LoaderContext.utils.createHash`
91
+ * @return {string }
70
92
*/
71
93
const filename = function ( source , identifier , options , hash ) {
72
94
hash . update ( serialize ( [ options , source , identifier ] ) ) ;
73
95
74
96
return hash . digest ( "hex" ) + ".json" ;
75
97
} ;
76
98
99
+ /**
100
+ * Add timestamps to external dependencies.
101
+ * @param {import("./transform").TransformResult["externalDependencies"] } externalDependencies
102
+ * @param {(filename: string) => Promise<FileSystemInfoEntry> } getFileTimestamp
103
+ */
77
104
const addTimestamps = async function ( externalDependencies , getFileTimestamp ) {
78
105
for ( const depAndEmptyTimestamp of externalDependencies ) {
79
106
try {
@@ -86,6 +113,12 @@ const addTimestamps = async function (externalDependencies, getFileTimestamp) {
86
113
}
87
114
} ;
88
115
116
+ /**
117
+ * Check if any external dependencies have been modified.
118
+ * @param {import("./transform").TransformResult["externalDependencies"] } externalDepsWithTimestamp
119
+ * @param {(filename: string) => Promise<FileSystemInfoEntry> } getFileTimestamp
120
+ * @returns {Promise<boolean> }
121
+ */
89
122
const areExternalDependenciesModified = async function (
90
123
externalDepsWithTimestamp ,
91
124
getFileTimestamp ,
@@ -108,8 +141,17 @@ const areExternalDependenciesModified = async function (
108
141
/**
109
142
* Handle the cache
110
143
*
111
- * @params {String} directory
112
- * @params {Object} params
144
+ * @param {string } directory
145
+ * @param {Object } params
146
+ * @param {string } params.source - The source code to transform.
147
+ * @param {import(".").NormalizedOptions } [params.options] - Options used for transformation.
148
+ * @param {string } params.cacheIdentifier - Unique identifier to bust cache.
149
+ * @param {string } [params.cacheDirectory] - Directory to store cached files.
150
+ * @param {boolean } [params.cacheCompression] - Whether to compress cached files.
151
+ * @param {WebpackHash } params.hash - Hash function to use for the cache filename.
152
+ * @param {(filename: string) => Promise<FileSystemInfoEntry> } params.getFileTimestamp - Function to get file timestamps.
153
+ * @param {WebpackLogger } params.logger
154
+ * @returns {Promise<null | import("./transform").TransformResult> }
113
155
*/
114
156
const handleCache = async function ( directory , params ) {
115
157
const {
@@ -170,6 +212,10 @@ const handleCache = async function (directory, params) {
170
212
// return it to the user asap and write it in cache
171
213
logger . debug ( `applying Babel transform` ) ;
172
214
const result = await transform ( source , options ) ;
215
+ if ( ! result ) {
216
+ logger . debug ( `no result from Babel transform, skipping cache write` ) ;
217
+ return null ;
218
+ }
173
219
await addTimestamps ( result . externalDependencies , getFileTimestamp ) ;
174
220
175
221
try {
@@ -191,12 +237,16 @@ const handleCache = async function (directory, params) {
191
237
* Retrieve file from cache, or create a new one for future reads
192
238
*
193
239
* @async
194
- * @param {Object } params
195
- * @param {String } params.cacheDirectory Directory to store cached files
196
- * @param {String } params.cacheIdentifier Unique identifier to bust cache
197
- * @param {Boolean } params.cacheCompression Whether compressing cached files
198
- * @param {String } params.source Original contents of the file to be cached
199
- * @param {Object } params.options Options to be given to the transform fn
240
+ * @param {object } params
241
+ * @param {string } params.cacheDirectory Directory to store cached files
242
+ * @param {string } params.cacheIdentifier Unique identifier to bust cache
243
+ * @param {boolean } params.cacheCompression Whether compressing cached files
244
+ * @param {string } params.source Original contents of the file to be cached
245
+ * @param {import(".").NormalizedOptions } params.options Options to be given to the transform fn
246
+ * @param {function } params.transform Transform function to apply to the file
247
+ * @param {WebpackHash } params.hash Hash function to use for the cache filename
248
+ * @param {function(string): Promise<FileSystemInfoEntry> } params.getFileTimestamp Function to get file timestamps
249
+ * @param {WebpackLogger } params.logger Logger instance
200
250
*
201
251
* @example
202
252
*
@@ -212,7 +262,7 @@ const handleCache = async function (directory, params) {
212
262
* });
213
263
*/
214
264
215
- module . exports = async function ( params ) {
265
+ module . exports = async function cache ( params ) {
216
266
let directory ;
217
267
218
268
if ( typeof params . cacheDirectory === "string" ) {
@@ -225,13 +275,23 @@ module.exports = async function (params) {
225
275
return await handleCache ( directory , params ) ;
226
276
} ;
227
277
278
+ /**
279
+ * Find the cache directory for babel-loader.
280
+ * @param {string } name "babel-loader"
281
+ * @returns {string }
282
+ */
228
283
function findCacheDir ( name ) {
229
284
if ( env . CACHE_DIR && ! [ "true" , "false" , "1" , "0" ] . includes ( env . CACHE_DIR ) ) {
230
285
return path . join ( env . CACHE_DIR , name ) ;
231
286
}
232
- const rootPkgJSONPath = path . dirname ( findRootPackageJSON ( ) ) ;
287
+ const rootPkgJSONPath = findRootPackageJSON ( ) ;
233
288
if ( rootPkgJSONPath ) {
234
- return path . join ( rootPkgJSONPath , "node_modules" , ".cache" , name ) ;
289
+ return path . join (
290
+ path . dirname ( rootPkgJSONPath ) ,
291
+ "node_modules" ,
292
+ ".cache" ,
293
+ name ,
294
+ ) ;
235
295
}
236
296
return os . tmpdir ( ) ;
237
297
}
0 commit comments