From 05f77745fd6ed0f9eae19aac6d259db27d70bc27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Espiau?= <7319147+FredericEspiau@users.noreply.github.com> Date: Tue, 17 Dec 2024 11:01:08 +0100 Subject: [PATCH] fix: prevent deleting files importes for side-effect --- lib/util/edit.test.ts | 18 ++++++++++++++++++ lib/util/findFileUsage.test.ts | 21 +++++++++++++++++++++ lib/util/findFileUsage.ts | 5 ++++- lib/util/parseFile.ts | 7 +++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/lib/util/edit.test.ts b/lib/util/edit.test.ts index 34fe9d2..27b5423 100644 --- a/lib/util/edit.test.ts +++ b/lib/util/edit.test.ts @@ -2103,4 +2103,22 @@ export const a = 'a';`, ); }); }); + + describe('side effect import', () => { + it('should not remove file if it is used for side effects', () => { + const fileService = new MemoryFileService(); + fileService.set('/app/main.ts', `import './a';`); + fileService.set('/app/a.ts', `console.log('a');`); + + edit({ + fileService, + recursive, + deleteUnusedFile: true, + entrypoints: ['/app/main.ts'], + }); + + assert.equal(fileService.get('/app/main.ts'), `import './a';`); + assert.equal(fileService.get('/app/a.ts'), `console.log('a');`); + }); + }); }); diff --git a/lib/util/findFileUsage.test.ts b/lib/util/findFileUsage.test.ts index a92ad66..8aae0a6 100644 --- a/lib/util/findFileUsage.test.ts +++ b/lib/util/findFileUsage.test.ts @@ -156,4 +156,25 @@ describe('findFileUsage', () => { // but for now this is the expected behavior assert.deepEqual(result, new Set(['glob', 'cwd'])); }); + + it('should handle files imported only for side effects', () => { + const fileService = new MemoryFileService(); + fileService.set('/app/main.ts', `import './a';`); + fileService.set('/app/a.ts', `console.log('a');`); + + const graph = createDependencyGraph({ + fileService, + options, + entrypoints: ['/app/main.ts'], + }); + const result = findFileUsage({ + targetFile: '/app/a.ts', + vertexes: graph.eject(), + files: fileService.eject(), + fileNames: fileService.getFileNames(), + options: {}, + }); + + assert.deepEqual(result, new Set(['#side-effect'])); + }); }); diff --git a/lib/util/findFileUsage.ts b/lib/util/findFileUsage.ts index c9a18c7..1047465 100644 --- a/lib/util/findFileUsage.ts +++ b/lib/util/findFileUsage.ts @@ -133,6 +133,9 @@ export const findFileUsage = ({ } return new Set( - result.filter((it) => exportsOfTargetFile.has(it) || it === '*'), + result.filter( + (it) => + exportsOfTargetFile.has(it) || it === '*' || it === '#side-effect', + ), ); }; diff --git a/lib/util/parseFile.ts b/lib/util/parseFile.ts index 8b6430d..bdf1cda 100644 --- a/lib/util/parseFile.ts +++ b/lib/util/parseFile.ts @@ -605,6 +605,13 @@ const fn = ({ imports[resolved]?.push('default'); } + // side effect import + if (!node.importClause) { + imports[resolved] ||= []; + // using a special symbol that can't be a valid identifier + imports[resolved]?.push('#side-effect'); + } + return; }