Skip to content

Commit

Permalink
fix: proper import() cache busting + not do empty cache key busting
Browse files Browse the repository at this point in the history
  • Loading branch information
Kartones authored and Diego Muñoz Pérez committed Jun 4, 2024
1 parent 24aaa00 commit 7f26597
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 5 deletions.
26 changes: 21 additions & 5 deletions lib/nodejs/esm-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,32 @@ const forward = x => x;

let cacheBusterKey = '';

// When changing the key, old items won't be garbage collected, but there is no alternative with import().
// More info: https://github.com/nodejs/node/issues/49442
const withCacheBuster = x => {
if (!cacheBusterKey) {
return x;
}
if (typeof x === 'string') {
return x.includes('?')
? `${x}&cache=${cacheBusterKey}`
: `${x}?cache=${cacheBusterKey}`;
} else if (x instanceof url.URL) {
x.searchParams.append('cache', cacheBusterKey);
}
return x;
};

exports.setCacheBusterKey = key => {
cacheBusterKey = key;
};

const formattedImport = async (file, esmDecorator = forward) => {
if (path.isAbsolute(file)) {
try {
return await exports.doImport(esmDecorator(url.pathToFileURL(file)));
return await exports.doImport(
withCacheBuster(esmDecorator(url.pathToFileURL(file)))
);
} catch (err) {
// This is a hack created because ESM in Node.js (at least in Node v15.5.1) does not emit
// the location of the syntax error in the error thrown.
Expand All @@ -35,12 +53,10 @@ const formattedImport = async (file, esmDecorator = forward) => {
throw err;
}
}
return exports.doImport(esmDecorator(file));
return exports.doImport(withCacheBuster(esmDecorator(file)));
};

// When changing the key, old items won't be garbage collected, but there is no alternative with import().
// More info: https://github.com/nodejs/node/issues/49442
exports.doImport = async file => import(`${file}?cache=${cacheBusterKey}`);
exports.doImport = async file => import(file);

exports.requireOrImport = async (file, esmDecorator) => {
if (path.extname(file) === '.mjs') {
Expand Down
18 changes: 18 additions & 0 deletions test/node-unit/esm-utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('esm-utils', function () {

afterEach(function () {
sinon.restore();
esmUtils.setCacheBusterKey('');
});

describe('loadFilesAsync()', function () {
Expand Down Expand Up @@ -42,5 +43,22 @@ describe('esm-utils', function () {
`${url.pathToFileURL('/foo/bar.mjs').toString()}?foo=bar`
);
});

it('should decorate imported module with passed decorator - with cache buster key', async function () {
esmUtils.setCacheBusterKey('1234');

await esmUtils.loadFilesAsync(
['/foo/bar.mjs'],
() => {},
() => {},
x => `${x}?foo=bar`
);

expect(
esmUtils.doImport.firstCall.args[0].toString(),
'to be',
`${url.pathToFileURL('/foo/bar.mjs').toString()}?foo=bar&cache=1234`
);
});
});
});

0 comments on commit 7f26597

Please sign in to comment.