Skip to content

Commit

Permalink
feature: mock-import: add support of node v20 (nodejs/issues/48240)
Browse files Browse the repository at this point in the history
  • Loading branch information
coderaiser committed May 31, 2023
1 parent 90ab4e0 commit 8f2c09e
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ jobs:
- name: Coverage
run: redrun test
- name: Coveralls
uses: coverallsapp/github-action@master
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
105 changes: 105 additions & 0 deletions lib/loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
const port = {};

export function globalPreload({port}) {
const cache = global.__mockImportCache;
const reImports = global.__mockImportReImports;
const traceCache = global.__traceImportCache;

port.onmessage = ({data}) => {
const {type} = data;

if (type === 'add-reimport') {
const {pathname} = data;
reImports.add(pathname);

return;
}

if (type === 'set-cache') {
const {name} = data;
!cache.has(name) && cache.set(name);

return;
}

if (type === 'set-trace-cache') {
const {name, stack} = data;
cache.set(name, stack);

return;
}

if (type === 'stop-cache') {
const {name} = data;
cache.set(name, '[no stubs for loader]');

return;
}

if (type === 'stop-all') {
cache.clear();
reImports.clear();
traceCache.clear();

return;
}

if (type === 'enable-nested-imports') {
global.__mockImportNested = true;
return;
}

if (type === 'disable -nested-imports') {
global.__mockImportNested = false;
return;
}
};

return `(${mockImport})()`;
}

function mockImport() {
globalThis.__mockImportLoader = {
addReImport(pathname) {
port.postMessage({
type: 'add-reimport',
pathname,
});
},
enableNestedImports() {
port.postMessage({
type: 'enable-nested-imports',
});
},
disableNestedImports() {
port.postMessage({
type: 'disable-nested-imports',
});
},
stopCache(name) {
port.postMessage({
type: 'stop-cache',
name,
});
},
setCache(name) {
port.postMessage({
type: 'set-cache',
name,
});
},
setTraceCache(name, stack) {
port.postMessage({
type: 'set-trace-cache',
name,
stack,
});
},
stopAll() {
port.postMessage({
type: 'stop-all',
});
},
};
}

25 changes: 20 additions & 5 deletions lib/mock-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import convertTracedImports from './convert-traced-imports/index.js';
import traceImports from './trace-imports/index.js';
import {isBuiltIn} from './is-built-in.js';

global.__mockImportCache = global.__mockImportCache || new Map();
global.__mockImportReImports = global.__mockImportReImports || new Set();
global.__mockImportCounter = global.__mockImportCounter || 0;
globalThis.__mockImportCache = global.__mockImportCache || new Map();
globalThis.__mockImportReImports = global.__mockImportReImports || new Set();

global.__traceImportCache = global.__traceImportCache || new Map();
global.__nextCount = () => ++global.__mockImportCounter;
Expand All @@ -23,13 +23,21 @@ global.__reImport = async (moduleUrl, url) => {

global.__mockImportNested = Boolean(process.env.MOCK_IMPORT_NESTED);

const traceCache = global.__traceImportCache;
const cache = global.__mockImportCache;

const traceCache = global.__traceImportCache;
const reImports = global.__mockImportReImports;
const nextCount = global.__nextCount;

export const enableNestedImports = () => global.__mockImportNested = true;
export const disableNestedImports = () => global.__mockImportNested = false;
export const enableNestedImports = () => {
global.__mockImportNested = true;
globalThis.__mockImportLoader.enableNestedImports();
};

export const disableNestedImports = () => {
global.__mockImportNested = false;
globalThis.__mockImportLoader.disableNestedImports();
};

export const createMockImport = (url) => {
const {resolve} = createRequire(url);
Expand All @@ -45,6 +53,8 @@ export const createMockImport = (url) => {
};
};

export {globalPreload} from './loader.js';

function transform({url, source, pathname, resolve}) {
let code = source;

Expand Down Expand Up @@ -113,6 +123,7 @@ export async function load(url, context, defaultLoad) {
const traceImport = ({resolve}) => (name, {stack}) => {
const [, pathname = name] = tryCatch(resolve, name);
traceCache.set(pathname, stack);
globalThis.__mockImportLoader.setTraceCache(pathname);
};

const reTrace = ({resolve}) => async (name) => {
Expand All @@ -123,14 +134,17 @@ const reTrace = ({resolve}) => async (name) => {
const mockImport = ({resolve}) => (name, data) => {
const [, pathname = name] = tryCatch(resolve, name);
cache.set(pathname, data);
globalThis.__mockImportLoader.setCache(pathname);
};

const reImport = ({resolve}) => async (name) => {
if (isBuiltIn(name))
return await import(name);

const pathname = resolve(name);

reImports.add(pathname);
globalThis.__mockImportLoader.addReImport(pathname);

return await import(`${pathname}?mock-import-count=${nextCount()}`);
};
Expand All @@ -143,6 +157,7 @@ const reImportDefault = ({resolve}) => async (name) => {
const stop = ({resolve}) => (name) => {
const pathname = resolve(name);
cache.delete(pathname);
globalThis.__mockImportLoader.stopCache(pathname);
};

const stopAll = () => {
Expand Down
19 changes: 17 additions & 2 deletions lib/mock-import.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ const {
reImportDefault,
traceImport,
reTrace,
stop,
stopAll,
} = createMockImport(import.meta.url);

const checkVersion = () => /20/.test(process.version);

test('mock-import: mockImport: default transform', async (t) => {
const result = await reImportDefault('./fixture/import.js');

Expand Down Expand Up @@ -61,7 +62,6 @@ test('mock-import: mockImport: reImport', async (t) => {
mockImport('glob', 'hello');

const result = await reImport('./fixture/import');
stop('glob');

stopAll();

Expand Down Expand Up @@ -183,6 +183,9 @@ test('mock-import: mockImport: load: cannot resolve', async (t) => {
});

test('mock-import: mockImport: transformSource: traceImport: stack', async (t) => {
if (checkVersion())
return t.pass('skip on node v20');

const input = './fixture/trace.js';

const stack = [];
Expand All @@ -204,6 +207,9 @@ test('mock-import: mockImport: transformSource: traceImport: stack', async (t) =
});

test('mock-import: mockImport: transformSource: traceImport: reImport', async (t) => {
if (checkVersion())
return t.pass('skip on node v20');

const input = './fixture/trace.js';
const stack = [];

Expand All @@ -224,6 +230,9 @@ test('mock-import: mockImport: transformSource: traceImport: reImport', async (t
});

test('mock-import: mockImport: transformSource: traceImport: reImport: again the same trace', async (t) => {
if (checkVersion())
return t.pass('skip on node v20');

const input = './fixture/trace.js';
const stack = [];

Expand Down Expand Up @@ -253,6 +262,9 @@ test('mock-import: mockImport: transformSource: traceImport: reImport: again the
});

test('mock-import: mockImport: transformSource: traceImport: reImport: nested', async (t) => {
if (checkVersion())
return t.pass('skip on node v20');

const inputParser = './fixture/nested-trace/parser.js';
const inputTokenizer = './fixture/nested-trace/tokenizer.js';

Expand Down Expand Up @@ -288,6 +300,9 @@ test('mock-import: reImport: native', async (t) => {
});

test('mockImport: nested reImport', async (t) => {
if (checkVersion())
return t.pass('skip on node v20');

const {__mockImportNested} = global;
global.__mockImportNested = true;

Expand Down

0 comments on commit 8f2c09e

Please sign in to comment.