Skip to content

Commit e1464cf

Browse files
feat(cjs): support query for cache busting (#37)
1 parent 585f117 commit e1464cf

File tree

5 files changed

+37
-15
lines changed

5 files changed

+37
-15
lines changed

src/cjs/api/module-extensions.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,26 @@ const transformer = (
3434
module: Module,
3535
filePath: string,
3636
) => {
37+
// Make sure __filename doesnt contain query
38+
const cleanFilePath = filePath.split('?')[0];
39+
3740
// For tracking dependencies in watch mode
3841
if (parent?.send) {
3942
parent.send({
4043
type: 'dependency',
41-
path: filePath,
44+
path: cleanFilePath,
4245
});
4346
}
4447

45-
const transformTs = typescriptExtensions.some(extension => filePath.endsWith(extension));
46-
const transformJs = transformExtensions.some(extension => filePath.endsWith(extension));
48+
const transformTs = typescriptExtensions.some(extension => cleanFilePath.endsWith(extension));
49+
const transformJs = transformExtensions.some(extension => cleanFilePath.endsWith(extension));
4750
if (!transformTs && !transformJs) {
48-
return defaultLoader(module, filePath);
51+
return defaultLoader(module, cleanFilePath);
4952
}
5053

51-
let code = fs.readFileSync(filePath, 'utf8');
54+
let code = fs.readFileSync(cleanFilePath, 'utf8');
5255

53-
if (filePath.endsWith('.cjs')) {
56+
if (cleanFilePath.endsWith('.cjs')) {
5457
// Contains native ESM check
5558
const transformed = transformDynamicImport(filePath, code);
5659
if (transformed) {
@@ -70,7 +73,7 @@ const transformer = (
7073
code,
7174
filePath,
7275
{
73-
tsconfigRaw: fileMatcher?.(filePath) as TransformOptions['tsconfigRaw'],
76+
tsconfigRaw: fileMatcher?.(cleanFilePath) as TransformOptions['tsconfigRaw'],
7477
},
7578
);
7679

@@ -81,7 +84,7 @@ const transformer = (
8184
);
8285
}
8386

84-
module._compile(code, filePath);
87+
module._compile(code, cleanFilePath);
8588
};
8689

8790
[

src/cjs/api/module-resolve-filename.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export const createResolveFilename = (
6262
) => {
6363
// Strip query string
6464
const queryIndex = request.indexOf('?');
65+
const query = queryIndex === -1 ? '' : request.slice(queryIndex);
6566
if (queryIndex !== -1) {
6667
request = request.slice(0, queryIndex);
6768
}
@@ -86,7 +87,7 @@ export const createResolveFilename = (
8687
for (const possiblePath of possiblePaths) {
8788
const tsFilename = resolveTsFilename(nextResolve, possiblePath, parent, isMain, options);
8889
if (tsFilename) {
89-
return tsFilename;
90+
return tsFilename + query;
9091
}
9192

9293
try {
@@ -95,15 +96,15 @@ export const createResolveFilename = (
9596
parent,
9697
isMain,
9798
options,
98-
);
99+
) + query;
99100
} catch {}
100101
}
101102
}
102103

103104
const tsFilename = resolveTsFilename(nextResolve, request, parent, isMain, options);
104105
if (tsFilename) {
105-
return tsFilename;
106+
return tsFilename + query;
106107
}
107108

108-
return nextResolve(request, parent, isMain, options);
109+
return nextResolve(request, parent, isMain, options) + query;
109110
};

src/utils/transform/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,17 @@ export const transformSync = (
3939
filePath: string,
4040
extendOptions?: TransformOptions,
4141
): Transformed => {
42+
const [filePathWithoutQuery, query] = filePath.split('?');
4243
const define: { [key: string]: string } = {};
4344

44-
if (!(filePath.endsWith('.cjs') || filePath.endsWith('.cts'))) {
45-
define['import.meta.url'] = JSON.stringify(pathToFileURL(filePath));
45+
if (!(filePathWithoutQuery.endsWith('.cjs') || filePathWithoutQuery.endsWith('.cts'))) {
46+
define['import.meta.url'] = JSON.stringify(pathToFileURL(filePathWithoutQuery) + (query ? `?${query}` : ''));
4647
}
4748

4849
const esbuildOptions = {
4950
...cacheConfig,
5051
format: 'cjs',
51-
sourcefile: filePath,
52+
sourcefile: filePathWithoutQuery,
5253
define,
5354
banner: '(()=>{',
5455
footer: '})()',

tests/fixtures.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ export const files = {
129129

130130
'js/index.js': outdent`
131131
import assert from 'assert';
132+
console.log(JSON.stringify({
133+
importMetaUrl: import.meta.url,
134+
__filename: typeof __filename !== 'undefined' ? __filename : undefined,
135+
}));
132136
${syntaxLowering}
133137
${preserveName}
134138
export const cjsContext = ${cjsContextCheck};

tests/specs/smoke.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => {
138138
console.error(error);
139139
console.log(p);
140140
});
141+
141142
expect(p.failed).toBe(false);
142143
expect(p.stdout).toMatch(`"import.meta.url":"${pathToFileURL(fixture.getPath('import-from-js.js'))}"`);
143144
expect(p.stdout).toMatch(`"js":{"cjsContext":${isCommonJs},"default":1,"named":2}`);
@@ -146,8 +147,14 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => {
146147
expect(p.stdout).toMatch('"pkgModule":{"default":1,"named":2}');
147148
if (isCommonJs) {
148149
expect(p.stdout).toMatch('"pkgCommonjs":{"default":1,"named":2}');
150+
151+
expect(p.stdout).toMatch(/\{"importMetaUrl":"file:\/\/\/.+?\/js\/index\.js","__filename":".+?index\.js"\}/);
152+
expect(p.stdout).toMatch(/\{"importMetaUrl":"file:\/\/\/.+?\/js\/index\.js\?query=123","__filename":".+?index\.js"\}/);
149153
} else {
150154
expect(p.stdout).toMatch('"pkgCommonjs":{"default":{"default":1,"named":2}}');
155+
156+
expect(p.stdout).toMatch(/\{"importMetaUrl":"file:\/\/\/.+?\/js\/index\.js"\}/);
157+
expect(p.stdout).toMatch(/\{"importMetaUrl":"file:\/\/\/.+?\/js\/index\.js\?query=123"\}/);
151158
}
152159

153160
// By "require()"ing an ESM file, it forces it to be compiled in a CJS context
@@ -354,8 +361,14 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => {
354361
expect(p.stdout).toMatch('"pkgModule":{"default":1,"named":2}');
355362
if (isCommonJs) {
356363
expect(p.stdout).toMatch('"pkgCommonjs":{"default":1,"named":2}');
364+
365+
expect(p.stdout).toMatch(/\{"importMetaUrl":"file:\/\/\/.+?\/js\/index\.js","__filename":".+?index\.js"\}/);
366+
expect(p.stdout).toMatch(/\{"importMetaUrl":"file:\/\/\/.+?\/js\/index\.js\?query=123","__filename":".+?index\.js"\}/);
357367
} else {
358368
expect(p.stdout).toMatch('"pkgCommonjs":{"default":{"default":1,"named":2}}');
369+
370+
expect(p.stdout).toMatch(/\{"importMetaUrl":"file:\/\/\/.+?\/js\/index\.js"\}/);
371+
expect(p.stdout).toMatch(/\{"importMetaUrl":"file:\/\/\/.+?\/js\/index\.js\?query=123"\}/);
359372
}
360373

361374
// By "require()"ing an ESM file, it forces it to be compiled in a CJS context

0 commit comments

Comments
 (0)