Skip to content

Commit

Permalink
fix: imports within comments are no longer discoverable
Browse files Browse the repository at this point in the history
  • Loading branch information
theKashey committed Jun 6, 2021
1 parent 4ee1c64 commit b47dea0
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 43 deletions.
2 changes: 1 addition & 1 deletion bin/imported-components
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/usr/bin/env node

require('../dist/es5/scanners/scanForImports');
require('../dist/es5/scanners/cli');
93 changes: 62 additions & 31 deletions __tests__/utils.spec.ts → src/scanners/__tests__/parser.spec.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,81 @@
import { dirname } from 'path';
import { remapImports } from '../src/scanners/scanForImports';
import { remapImports } from '../scanForImports';
import { getRelative } from '../shared';

describe('scanForImports', () => {
const rel = '.' + dirname(__dirname);
const rel = dirname(__dirname);
const root = '.';
const rootRel = '.' + process.cwd();
const sourceFile = `${rel}/a`;

it('should map simple import', () => {
const imports = {};
remapImports(
[{ file: 'a', content: 'blabla;import("./a.js"); blabla;' }],
root,
root,
(a, b) => a + b,
[{ file: `${rel}/a`, content: 'blabla;import("./b.js"); blabla;' }],
rel,
rel,
getRelative,
imports,
() => true
);
expect(Object.values(imports)).toEqual([`[() => import('${rel}/a.js'), '', '${rel}/a.js', false] /* from .a */`]);
expect(Object.values(imports)).toEqual([`[() => import('./b.js'), '', './b.js', false] /* from ./a */`]);
});

it('handles imports in jsdoc', () => {
const imports = {};
remapImports(
[
{
file: sourceFile,
content: `
/**
* @type {import('wrong-import')}
*/
import(/* comment:valuable */ "./a.js");
import("./b.js");
// import('another-wrong-import');// FIXME: temporary removed
`,
},
],
rel,
rel,
getRelative,
imports,
() => true
);
expect(Object.values(imports)).toEqual([
`[() => import(/* comment:valuable */'./a.js'), '', './a.js', false] /* from ./a */`,
`[() => import('./b.js'), '', './b.js', false] /* from ./a */`,
]);
});

it('should map client-side import', () => {
const imports = {};
remapImports(
[{ file: 'a', content: 'blabla;import(/* client-side */"./a.js"); blabla;' }],
root,
root,
(a, b) => a + b,
[{ file: sourceFile, content: 'blabla;import(/* client-side */"./a.js"); blabla;' }],
rel,
rel,
getRelative,
imports,
() => true
);
expect(Object.values(imports)).toEqual([
`[() => import(/* client-side */'${rel}/a.js'), '', '${rel}/a.js', true] /* from .a */`,
`[() => import(/* client-side */'./a.js'), '', './a.js', true] /* from ./a */`,
]);
});

it('should map simple import with a comment', () => {
const imports = {};
remapImports(
[{ file: 'a', content: 'blabla;import(/* comment:42 */"./a.js"); blabla;' }],
root,
root,
(a, b) => a + b,
[{ file: sourceFile, content: 'blabla;import(/* comment:42 */"./a.js"); blabla;' }],
rel,
rel,
getRelative,
imports,
() => true
);
expect(Object.values(imports)).toEqual([
`[() => import(/* comment:42 */'${rel}/a.js'), '', '${rel}/a.js', false] /* from .a */`,
`[() => import(/* comment:42 */'./a.js'), '', './a.js', false] /* from ./a */`,
]);
});

Expand All @@ -53,19 +84,19 @@ describe('scanForImports', () => {
remapImports(
[
{
file: 'a',
file: sourceFile,
content: 'blabla;import(/* webpack: "123" */"./a.js"); blabla; import(/* webpack: 123 */ \'./b.js\');',
},
],
root,
root,
(a, b) => a + b,
rel,
rel,
getRelative,
imports,
() => true
);
expect(Object.values(imports)).toEqual([
`[() => import(/* webpack: \"123\" */'${rel}/a.js'), '', '${rel}/a.js', false] /* from .a */`,
`[() => import(/* webpack: 123 */'${rel}/b.js'), '', '${rel}/b.js', false] /* from .a */`,
`[() => import(/* webpack: \"123\" */'./a.js'), '', './a.js', false] /* from ./a */`,
`[() => import(/* webpack: 123 */'./b.js'), '', './b.js', false] /* from ./a */`,
]);
});

Expand All @@ -86,8 +117,8 @@ describe('scanForImports', () => {
() => true
);
expect(Object.values(imports)).toEqual([
`[() => import(/* webpackChunkName: "chunk-a" */'${rel}/a.js'), 'chunk-a', '${rel}/a.js', false] /* from .a */`,
`[() => import(/* webpack: 123 */'${rel}/b.js'), '', '${rel}/b.js', false] /* from .a */`,
`[() => import(/* webpackChunkName: "chunk-a" */'${rootRel}/a.js'), 'chunk-a', '${rootRel}/a.js', false] /* from .a */`,
`[() => import(/* webpack: 123 */'${rootRel}/b.js'), '', '${rootRel}/b.js', false] /* from .a */`,
]);
});

Expand All @@ -109,8 +140,8 @@ describe('scanForImports', () => {
(imported, _, options) => (imported.indexOf('a.js') > 0 ? `test-${options.chunkName}-test` : 'bundle-b')
);
expect(Object.values(imports)).toEqual([
`[() => import(/* webpackChunkName: \"chunk-a\" */'${rel}/a.js'), 'test-chunk-a-test', '${rel}/a.js', false] /* from .a */`,
`[() => import(/* webpackChunkName: \"chunk-b\" */'${rel}/b.js'), 'bundle-b', '${rel}/b.js', false] /* from .a */`,
`[() => import(/* webpackChunkName: \"chunk-a\" */'${rootRel}/a.js'), 'test-chunk-a-test', '${rootRel}/a.js', false] /* from .a */`,
`[() => import(/* webpackChunkName: \"chunk-b\" */'${rootRel}/b.js'), 'bundle-b', '${rootRel}/b.js', false] /* from .a */`,
]);
});

Expand Down Expand Up @@ -140,8 +171,8 @@ describe('scanForImports', () => {
() => true
);
expect(Object.values(imports)).toEqual([
`[() => import(/* webpackChunkName: \"chunk-a\" */'${rel}/a.js'), 'chunk-a', '${rel}/a.js', false] /* from .a */`,
`[() => import('${rel}/b.js'), '', '${rel}/b.js', false] /* from .a */`,
`[() => import(/* webpackChunkName: \"chunk-a\" */'${rootRel}/a.js'), 'chunk-a', '${rootRel}/a.js', false] /* from .a */`,
`[() => import('${rootRel}/b.js'), '', '${rootRel}/b.js', false] /* from .a */`,
]);
});

Expand All @@ -162,8 +193,8 @@ describe('scanForImports', () => {
() => true
);
expect(Object.values(imports)).toEqual([
`[() => import(/* *//* webpack: \"123\" */'${rel}/a.js'), '', '${rel}/a.js', false] /* from .a */`,
`[() => import(/* */'${rel}/b.js'), '', '${rel}/b.js', false] /* from .a */`,
`[() => import(/* *//* webpack: \"123\" */'${rootRel}/a.js'), '', '${rootRel}/a.js', false] /* from .a */`,
`[() => import(/* */'${rootRel}/b.js'), '', '${rootRel}/b.js', false] /* from .a */`,
]);
});
});
10 changes: 10 additions & 0 deletions src/scanners/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* tslint:disable no-console */

import { scanTop } from './scanForImports';

if (!process.argv[3]) {
console.log('usage: imported-components sourceRoot targetFile');
console.log('example: imported-components src src/importedComponents.js');
} else {
scanTop(process.cwd(), process.argv[2], process.argv[3]);
}
30 changes: 19 additions & 11 deletions src/scanners/scanForImports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ const getImportString = (pattern: string, selected: number) => (str: string): Ma

export const getDynamicImports = getImportString(`import[\\s]?\\((([^)])+['"]?)\\)`, 1);

export const cleanFileContent = (content: string) => {
const mapping: string[] = [];
// wrap
const wrapped = content.replace(new RegExp(`import[\\s]?\\((([^)])+['"]?)\\)`, 'g'), match => {
const placement = mapping.push(match) - 1;
return `imported_${placement}_replacement`;
});

const cleaned = wrapped.replace(new RegExp('//.*', 'g'), '').replace(new RegExp('\\/\\*[\\s\\S]*?\\*\\/', 'gm'), '');

const unwrapped = cleaned.replace(new RegExp('imported_([\\d]*)_replacement', 'g'), (_, b: string) => {
return mapping[+b];
});

return unwrapped;
};

const mapImports = (file: string, imports: MappedImport[]) =>
imports.map(dep => {
const { name } = dep;
Expand Down Expand Up @@ -85,7 +102,7 @@ export const remapImports = (
chunkName?: ImportedConfiguration['chunkName']
) =>
data
.map(({ file, content }) => mapImports(file, getDynamicImports(content)))
.map(({ file, content }) => mapImports(file, getDynamicImports(cleanFileContent(content))))
.forEach(importBlock =>
importBlock.forEach(({ name, comment, doNotTransform, file }) => {
const rootName = doNotTransform ? name : getRelativeName(root, name);
Expand All @@ -105,7 +122,7 @@ export const remapImports = (
})
);

function scanTop(root: string, start: string, target: string) {
export function scanTop(root: string, start: string, target: string) {
async function scan() {
console.log('scanning', start, 'for imports...');

Expand Down Expand Up @@ -184,12 +201,3 @@ ${Object.keys(imports)

return scan();
}

// --------

if (!process.argv[3]) {
console.log('usage: imported-components sourceRoot targetFile');
console.log('example: imported-components src src/importedComponents.js');
} else {
scanTop(process.cwd(), process.argv[2], process.argv[3]);
}

0 comments on commit b47dea0

Please sign in to comment.