Skip to content

Commit

Permalink
fix: normalize loader import path to compiled file
Browse files Browse the repository at this point in the history
  • Loading branch information
herberttn committed Apr 23, 2021
1 parent 6212492 commit 1bb918f
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 13 deletions.
13 changes: 7 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"npm-run-all": "4.1.5",
"rimraf": "3.0.2",
"semantic-release": "17.4.2",
"slash": "3.0.0",
"ts-jest": "26.5.4",
"ts-node": "9.1.1",
"typescript": "4.2.3",
Expand Down
8 changes: 1 addition & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { WebpackPluginInstance } from 'webpack';
import type { Source } from 'webpack-sources';
import WebpackVirtualModules from 'webpack-virtual-modules';

import { createLoaderCode } from './loader';
import type { Compiler, EntryPoint, WebpackOptionsNormalized } from './normalized';
import type { Options, Prepared, PreprocessedEntry, PreprocessedOutput, ProcessedOptions } from './types';

Expand Down Expand Up @@ -287,13 +288,6 @@ class BytenodeWebpackPlugin implements WebpackPluginInstance {
}
}

function createLoaderCode(relativePath: string): string {
return `
require('bytenode');
require('${relativePath}');
`;
}

function prepare(context: string | undefined, location: string | string[], name?: string, suffix = ''): Prepared {
const locationArray = Array.isArray(location) ? location : [location];

Expand Down
31 changes: 31 additions & 0 deletions src/loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { platform } from 'os';
import { win32 } from 'path';

import slash from 'slash';

function createLoaderCode(relativePath: string): string {
if (/win32/.test(platform()) && win32.isAbsolute(relativePath)) {
relativePath = exhaustiveReplace(relativePath, /\/\//g, '/');
relativePath = exhaustiveReplace(relativePath, /\//g, '\\');
relativePath = exhaustiveReplace(relativePath, /\\\\/g, '\\');
relativePath = relativePath.replace(/\\/g, '\\\\');
} else {
relativePath = slash(relativePath);
}

return `
require('bytenode');
require('${relativePath}');
`;
}

function exhaustiveReplace(source: string, regex: RegExp, target: string): string {
if (regex.test(source)) {
return exhaustiveReplace(source.replace(regex, target), regex, target);
}
return source;
}

export {
createLoaderCode,
};
84 changes: 84 additions & 0 deletions test/loader.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
describe('createLoaderCode', () => {

for (const platform of ['darwin', 'linux'] as NodeJS.Platform[]) {
describe(`${platform}`, () => {

describe('absolute', () => {
test('backwards', async () => {
await mockPlatform(platform);
await testLoaderCode('\\a\\b\\c', '/a/b/c');
});

test('forwards', async () => {
await mockPlatform(platform);
await testLoaderCode('/a/b/c', '/a/b/c');
});
});

describe('relative', () => {
test('backwards', async () => {
await mockPlatform(platform);
await testLoaderCode('.\\a\\b\\c', './a/b/c');
});

test('forwards', async () => {
await mockPlatform(platform);
await testLoaderCode('./a/b/c', './a/b/c');
});
});

});
}

describe('win32', () => {

describe('absolute', () => {
test('backwards', async () => {
await mockPlatform('win32');
await testLoaderCode('A:\\b\\c', 'A:\\\\b\\\\c');
});

test('forwards', async () => {
await mockPlatform('win32');
await testLoaderCode('A:/b/c', 'A:\\\\b\\\\c');
});
});

describe('relative', () => {
test('backwards', async () => {
await mockPlatform('win32');
await testLoaderCode('.\\a\\b\\c', './a/b/c');
});

test('forwards', async () => {
await mockPlatform('win32');
await testLoaderCode('./a/b/c', './a/b/c');
});
});

});

});

async function mockPlatform(platform: NodeJS.Platform): Promise<void> {
jest.resetModules();
jest.doMock('os', () => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const os = jest.requireActual('os');

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return { ...os, platform: () => platform };
});

const os = await import('os');
expect(os.platform()).toBe(platform);
}

async function testLoaderCode(from: string, to: string): Promise<void> {
const { createLoaderCode } = await import('../src/loader');

expect(createLoaderCode(from)).toBe(`
require('bytenode');
require('${to}');
`);
}

0 comments on commit 1bb918f

Please sign in to comment.