Skip to content

Commit

Permalink
fix: prevent duplicate imports (#12931)
Browse files Browse the repository at this point in the history
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
  • Loading branch information
dummdidumm and benmccann authored Nov 2, 2024
1 parent d55b822 commit 204506b
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/spicy-cars-cheer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte-migrate': patch
---

fix: prevent duplicate imports
13 changes: 3 additions & 10 deletions packages/migrate/migrations/svelte-5/migrate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'node:fs';
import { Project, ts, Node } from 'ts-morph';
import { update_pkg } from '../../utils.js';
import { add_named_import, update_pkg } from '../../utils.js';

export function update_pkg_json() {
fs.writeFileSync(
Expand Down Expand Up @@ -94,14 +94,7 @@ function update_component_instantiation(source) {
?.remove();
}

if (source.getImportDeclaration('svelte')) {
source.getImportDeclaration('svelte')?.addNamedImport(method);
} else {
source.addImportDeclaration({
moduleSpecifier: 'svelte',
namedImports: [method]
});
}
add_named_import(source, 'svelte', method);

const declaration = parent
.getParentIfKind(ts.SyntaxKind.VariableDeclaration)
Expand All @@ -114,7 +107,7 @@ function update_component_instantiation(source) {
const call_expr = parent.getParentIfKind(ts.SyntaxKind.CallExpression);
if (call_expr) {
call_expr.replaceWithText(`unmount(${usage.getText()})`);
source.getImportDeclaration('svelte')?.addNamedImport('unmount');
add_named_import(source, 'svelte', 'unmount');
}
}
}
Expand Down
29 changes: 29 additions & 0 deletions packages/migrate/migrations/svelte-5/migrate.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,35 @@ function destroy() {
);
});

test('Updates component creation with multiple components', () => {
const result = transform_module_code(
`import App from './App.svelte';
import Child from './Child.svelte';
const x = new App({
target: document.getElementById('app')!
});
const y = new Child({
target: document.getElementById('child')!
});
`
);
assert.equal(
result,
`import App from './App.svelte';
import Child from './Child.svelte';
import { mount } from "svelte";
const x = mount(App, {
target: document.getElementById('app')!
});
const y = mount(Child, {
target: document.getElementById('child')!
});
`
);
});

test('Update package.json', () => {
const result = update_pkg_json_content(`{
"name": "svelte-app",
Expand Down
19 changes: 7 additions & 12 deletions packages/migrate/migrations/sveltekit-2/migrate.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import fs from 'node:fs';
import { Project, Node, SyntaxKind } from 'ts-morph';
import { log_migration, log_on_ts_modification, update_pkg } from '../../utils.js';
import {
add_named_import,
log_migration,
log_on_ts_modification,
update_pkg
} from '../../utils.js';
import path from 'node:path';

export function update_pkg_json() {
Expand Down Expand Up @@ -112,17 +117,7 @@ export function update_svelte_config_content(code) {
?.setModuleSpecifier('@sveltejs/vite-plugin-svelte');
} else {
namedImport.remove();
const vps = source.getImportDeclaration(
(i) => i.getModuleSpecifierValue() === '@sveltejs/vite-plugin-svelte'
);
if (vps) {
vps.addNamedImport('vitePreprocess');
} else {
source.addImportDeclaration({
moduleSpecifier: '@sveltejs/vite-plugin-svelte',
namedImports: ['vitePreprocess']
});
}
add_named_import(source, '@sveltejs/vite-plugin-svelte', 'vitePreprocess');
}

logger();
Expand Down
18 changes: 18 additions & 0 deletions packages/migrate/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,3 +401,21 @@ export function read_samples(test_file) {

return samples;
}

/**
* @param {import('ts-morph').SourceFile} source
* @param {string} _import
* @param {string} method
*/
export function add_named_import(source, _import, method) {
const existing = source.getImportDeclaration(_import);
if (existing) {
if (existing.getNamedImports().some((i) => i.getName() === method)) return;
existing?.addNamedImport(method);
} else {
source.addImportDeclaration({
moduleSpecifier: _import,
namedImports: [method]
});
}
}

0 comments on commit 204506b

Please sign in to comment.