Skip to content

Commit e6e5b03

Browse files
feat: added deps migration (#99)
* feat: added deps migration * feat: add migration to use "useVisisbleTask$" instead of "useClientEffect$" --------- Co-authored-by: Dmitriy Stepanenko <[email protected]>
1 parent bd267c2 commit e6e5b03

File tree

5 files changed

+283
-0
lines changed

5 files changed

+283
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"tcp-port-used": "1.0.2",
6161
"tree-kill": "1.2.2",
6262
"ts-jest": "29.0.5",
63+
"ts-morph": "17.0.1",
6364
"ts-node": "10.9.1",
6465
"typescript": "4.9.5",
6566
"verdaccio": "5.21.1",

packages/qwik-nx/migrations.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,67 @@
55
"description": "switch-to-qwik-nx-build-executor",
66
"cli": "nx",
77
"implementation": "./src/migrations/switch-to-qwik-nx-build-executor/switch-to-qwik-nx-build-executor"
8+
},
9+
"update-use-client-effect$-to-use-visisble-task$": {
10+
"version": "0.13.1",
11+
"description": "useClientEffect$ has been changed to useVisisbleTask$",
12+
"cli": "nx",
13+
"implementation": "./src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$"
14+
}
15+
},
16+
"packageJsonUpdates": {
17+
"0.13.1": {
18+
"version": "0.13.1",
19+
"packages": {
20+
"@builder.io/qwik": {
21+
"version": "~0.20.1"
22+
},
23+
"@builder.io/qwik-city": {
24+
"version": "0.5.2"
25+
},
26+
"@types/eslint": {
27+
"version": "8.21.1"
28+
},
29+
"@types/node": {
30+
"version": "^18.14.0"
31+
},
32+
"@types/node-fetch": {
33+
"version": "latest"
34+
},
35+
"@typescript-eslint/eslint-plugin": {
36+
"version": "5.54.0"
37+
},
38+
"@typescript-eslint/parser": {
39+
"version": "5.54.0"
40+
},
41+
"eslint": {
42+
"version": "8.35.0"
43+
},
44+
"eslint-plugin-qwik": {
45+
"version": "~0.20.1"
46+
},
47+
"node-fetch": {
48+
"version": "3.3.0"
49+
},
50+
"prettier": {
51+
"version": "2.8.4"
52+
},
53+
"typescript": {
54+
"version": "4.9.5"
55+
},
56+
"undici": {
57+
"version": "5.20.0"
58+
},
59+
"vite": {
60+
"version": "4.1.4"
61+
},
62+
"vite-tsconfig-paths": {
63+
"version": "3.5.0"
64+
},
65+
"zod": {
66+
"version": "^3.20.6"
67+
}
68+
}
869
}
970
}
1071
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { addProjectConfiguration, Tree } from '@nrwl/devkit';
2+
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
3+
import migrate from './update-use-client-effect$-to-use-visisble-task$';
4+
5+
describe('Use new "qwik-nx:build" executor in qwik apps', () => {
6+
let tree: Tree;
7+
8+
beforeEach(() => {
9+
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
10+
addProjectConfiguration(tree, 'app1', {
11+
root: 'apps/app1',
12+
});
13+
});
14+
15+
it('should update imports', async () => {
16+
const { other, toBeRenamedAfter, toBeRenamedBefore } = getTestFiles();
17+
const toBerenamedFilePath = 'apps/app1/to-be-renamed.tsx';
18+
const otherFilePath = 'apps/app1/other.tsx';
19+
tree.write(toBerenamedFilePath, toBeRenamedBefore);
20+
tree.write(otherFilePath, other);
21+
22+
await migrate(tree);
23+
24+
expect(tree.read(toBerenamedFilePath)?.toString()).toEqual(
25+
toBeRenamedAfter
26+
);
27+
expect(tree.read(otherFilePath)?.toString()).toEqual(other);
28+
});
29+
});
30+
31+
function getTestFiles() {
32+
return {
33+
toBeRenamedBefore: `import { component$, useClientEffect$, useStore, useStylesScoped$ } from '@builder.io/qwik';
34+
import styles from './flower.css?inline';
35+
36+
const anotherVar = useClientEffect$;
37+
38+
export default component$(() => {
39+
useStylesScoped$(styles);
40+
41+
const state = useStore({
42+
count: 0,
43+
number: 20,
44+
});
45+
46+
useClientEffect$(({ cleanup }) => {
47+
const timeout = setTimeout(() => (state.count = 1), 500);
48+
cleanup(() => clearTimeout(timeout));
49+
});
50+
51+
console.log('useClientEffect$');
52+
53+
return (
54+
<>
55+
Content of a file that has useClientEffect$ function
56+
</>
57+
);
58+
});`,
59+
toBeRenamedAfter: `import { component$, useVisibleTask$, useStore, useStylesScoped$ } from '@builder.io/qwik';
60+
import styles from './flower.css?inline';
61+
62+
const anotherVar = useVisibleTask$;
63+
64+
export default component$(() => {
65+
useStylesScoped$(styles);
66+
67+
const state = useStore({
68+
count: 0,
69+
number: 20,
70+
});
71+
72+
useVisibleTask$(({ cleanup }) => {
73+
const timeout = setTimeout(() => (state.count = 1), 500);
74+
cleanup(() => clearTimeout(timeout));
75+
});
76+
77+
console.log('useClientEffect$');
78+
79+
return (
80+
<>
81+
Content of a file that has useClientEffect$ function
82+
</>
83+
);
84+
});`,
85+
other: `import { component$, useClientEffect$, useStore, useStylesScoped$ } from 'other-package';
86+
import styles from './flower.css?inline';
87+
88+
export default component$(() => {
89+
useStylesScoped$(styles);
90+
91+
const state = useStore({
92+
count: 0,
93+
number: 20,
94+
});
95+
96+
useClientEffect$(({ cleanup }) => {
97+
const timeout = setTimeout(() => (state.count = 1), 500);
98+
cleanup(() => clearTimeout(timeout));
99+
});
100+
101+
console.log('useClientEffect$');
102+
103+
return (
104+
<>
105+
Content of a file that has useClientEffect$ function
106+
</>
107+
);
108+
});`,
109+
};
110+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import {
2+
ensurePackage,
3+
getProjects,
4+
Tree,
5+
visitNotIgnoredFiles,
6+
} from '@nrwl/devkit';
7+
import { extname } from 'path';
8+
import { SyntaxKind } from 'typescript';
9+
10+
export default async function update(tree: Tree) {
11+
ensurePackage('ts-morph', '^17.0.0');
12+
const tsMorph = await import('ts-morph');
13+
for (const [, definition] of getProjects(tree)) {
14+
visitNotIgnoredFiles(tree, definition.root, (file) => {
15+
if (extname(file) === '.tsx') {
16+
updateNamedImport(
17+
tree,
18+
tsMorph,
19+
file,
20+
'@builder.io/qwik',
21+
'useClientEffect$',
22+
'useVisibleTask$'
23+
);
24+
}
25+
});
26+
}
27+
}
28+
29+
function updateNamedImport(
30+
tree: Tree,
31+
tsMorph: typeof import('ts-morph'),
32+
filePath: string,
33+
importModuleSpecifier: string,
34+
importName: string,
35+
updatedImportName: string
36+
) {
37+
const fileContent = tree.read(filePath)!.toString();
38+
const project = new tsMorph.Project();
39+
const sourceFile = project.createSourceFile('temp.ts', fileContent);
40+
const imports = sourceFile.getImportDeclarations();
41+
const relevantImports = imports
42+
.map((imp) => {
43+
const moduleSpecifier = imp.getModuleSpecifierValue();
44+
if (moduleSpecifier !== importModuleSpecifier) {
45+
return [];
46+
}
47+
return imp
48+
.getNamedImports()
49+
.filter((namedImport) => namedImport.getName() === importName);
50+
})
51+
.filter((imports) => imports.length)
52+
.flat();
53+
54+
if (relevantImports.length > 0) {
55+
relevantImports.forEach((imp) => imp.replaceWithText(updatedImportName));
56+
57+
sourceFile.forEachDescendant((node) => {
58+
if (
59+
node.getKind() === SyntaxKind.Identifier &&
60+
node.getText() === importName &&
61+
[SyntaxKind.CallExpression, SyntaxKind.VariableDeclaration].includes(
62+
node.getParent()?.getKind() as SyntaxKind
63+
)
64+
) {
65+
node.replaceWithText(updatedImportName);
66+
}
67+
});
68+
69+
tree.write(filePath, sourceFile.getFullText());
70+
}
71+
72+
return tree;
73+
}

pnpm-lock.yaml

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)