From e697cf9fa56bcab6482f7ceaf5f5fce98a7af665 Mon Sep 17 00:00:00 2001 From: Shai Reznik Date: Sat, 4 Mar 2023 22:24:42 +0200 Subject: [PATCH 1/2] feat: added deps migration --- packages/qwik-nx/migrations.json | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/packages/qwik-nx/migrations.json b/packages/qwik-nx/migrations.json index aaebd8ad..ab1e91f3 100644 --- a/packages/qwik-nx/migrations.json +++ b/packages/qwik-nx/migrations.json @@ -6,5 +6,60 @@ "cli": "nx", "implementation": "./src/migrations/switch-to-qwik-nx-build-executor/switch-to-qwik-nx-build-executor" } + }, + "packageJsonUpdates": { + "0.12.1": { + "version": "0.12.1", + "packages": { + "@builder.io/qwik": { + "version": "~0.20.1" + }, + "@builder.io/qwik-city": { + "version": "0.5.2" + }, + "@types/eslint": { + "version": "8.21.1" + }, + "@types/node": { + "version": "^18.14.0" + }, + "@types/node-fetch": { + "version": "latest" + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.54.0" + }, + "@typescript-eslint/parser": { + "version": "5.54.0" + }, + "eslint": { + "version": "8.35.0" + }, + "eslint-plugin-qwik": { + "version": "~0.20.1" + }, + "node-fetch": { + "version": "3.3.0" + }, + "prettier": { + "version": "2.8.4" + }, + "typescript": { + "version": "4.9.5" + }, + "undici": { + "version": "5.20.0" + }, + "vite": { + "version": "4.1.4" + }, + "vite-tsconfig-paths": { + "version": "3.5.0" + }, + "zod": { + "version": "^3.20.6" + } + } + } } } From cdcfb655c5ad323dc472abed3713932493519001 Mon Sep 17 00:00:00 2001 From: Dmitriy Stepanenko Date: Tue, 7 Mar 2023 21:20:16 +0200 Subject: [PATCH 2/2] feat: add migration to use "useVisisbleTask$" instead of "useClientEffect$" --- .gitignore | 2 +- package.json | 1 + packages/qwik-nx/migrations.json | 10 +- ...ient-effect$-to-use-visisble-task$.spec.ts | 110 ++++++++++++++++++ ...se-client-effect$-to-use-visisble-task$.ts | 73 ++++++++++++ pnpm-lock.yaml | 38 ++++++ 6 files changed, 231 insertions(+), 3 deletions(-) create mode 100644 packages/qwik-nx/src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$.spec.ts create mode 100644 packages/qwik-nx/src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$.ts diff --git a/.gitignore b/.gitignore index 2990465c..9a38ff5b 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,7 @@ npm-debug.log yarn-error.log testem.log /typings -migrations.json +./migrations.json # System Files .DS_Store diff --git a/package.json b/package.json index df047397..78c87baf 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "tcp-port-used": "1.0.2", "tree-kill": "1.2.2", "ts-jest": "29.0.5", + "ts-morph": "17.0.1", "ts-node": "10.9.1", "typescript": "4.9.5", "verdaccio": "5.21.1", diff --git a/packages/qwik-nx/migrations.json b/packages/qwik-nx/migrations.json index ab1e91f3..38af599b 100644 --- a/packages/qwik-nx/migrations.json +++ b/packages/qwik-nx/migrations.json @@ -5,11 +5,17 @@ "description": "switch-to-qwik-nx-build-executor", "cli": "nx", "implementation": "./src/migrations/switch-to-qwik-nx-build-executor/switch-to-qwik-nx-build-executor" + }, + "update-use-client-effect$-to-use-visisble-task$": { + "version": "0.13.1", + "description": "useClientEffect$ has been changed to useVisisbleTask$", + "cli": "nx", + "implementation": "./src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$" } }, "packageJsonUpdates": { - "0.12.1": { - "version": "0.12.1", + "0.13.1": { + "version": "0.13.1", "packages": { "@builder.io/qwik": { "version": "~0.20.1" diff --git a/packages/qwik-nx/src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$.spec.ts b/packages/qwik-nx/src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$.spec.ts new file mode 100644 index 00000000..75e15e2d --- /dev/null +++ b/packages/qwik-nx/src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$.spec.ts @@ -0,0 +1,110 @@ +import { addProjectConfiguration, Tree } from '@nrwl/devkit'; +import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; +import migrate from './update-use-client-effect$-to-use-visisble-task$'; + +describe('Use new "qwik-nx:build" executor in qwik apps', () => { + let tree: Tree; + + beforeEach(() => { + tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); + addProjectConfiguration(tree, 'app1', { + root: 'apps/app1', + }); + }); + + it('should update imports', async () => { + const { other, toBeRenamedAfter, toBeRenamedBefore } = getTestFiles(); + const toBerenamedFilePath = 'apps/app1/to-be-renamed.tsx'; + const otherFilePath = 'apps/app1/other.tsx'; + tree.write(toBerenamedFilePath, toBeRenamedBefore); + tree.write(otherFilePath, other); + + await migrate(tree); + + expect(tree.read(toBerenamedFilePath)?.toString()).toEqual( + toBeRenamedAfter + ); + expect(tree.read(otherFilePath)?.toString()).toEqual(other); + }); +}); + +function getTestFiles() { + return { + toBeRenamedBefore: `import { component$, useClientEffect$, useStore, useStylesScoped$ } from '@builder.io/qwik'; + import styles from './flower.css?inline'; + + const anotherVar = useClientEffect$; + + export default component$(() => { + useStylesScoped$(styles); + + const state = useStore({ + count: 0, + number: 20, + }); + + useClientEffect$(({ cleanup }) => { + const timeout = setTimeout(() => (state.count = 1), 500); + cleanup(() => clearTimeout(timeout)); + }); + + console.log('useClientEffect$'); + + return ( + <> + Content of a file that has useClientEffect$ function + + ); + });`, + toBeRenamedAfter: `import { component$, useVisibleTask$, useStore, useStylesScoped$ } from '@builder.io/qwik'; + import styles from './flower.css?inline'; + + const anotherVar = useVisibleTask$; + + export default component$(() => { + useStylesScoped$(styles); + + const state = useStore({ + count: 0, + number: 20, + }); + + useVisibleTask$(({ cleanup }) => { + const timeout = setTimeout(() => (state.count = 1), 500); + cleanup(() => clearTimeout(timeout)); + }); + + console.log('useClientEffect$'); + + return ( + <> + Content of a file that has useClientEffect$ function + + ); + });`, + other: `import { component$, useClientEffect$, useStore, useStylesScoped$ } from 'other-package'; + import styles from './flower.css?inline'; + + export default component$(() => { + useStylesScoped$(styles); + + const state = useStore({ + count: 0, + number: 20, + }); + + useClientEffect$(({ cleanup }) => { + const timeout = setTimeout(() => (state.count = 1), 500); + cleanup(() => clearTimeout(timeout)); + }); + + console.log('useClientEffect$'); + + return ( + <> + Content of a file that has useClientEffect$ function + + ); + });`, + }; +} diff --git a/packages/qwik-nx/src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$.ts b/packages/qwik-nx/src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$.ts new file mode 100644 index 00000000..1d48f305 --- /dev/null +++ b/packages/qwik-nx/src/migrations/update-use-client-effect$-to-use-visisble-task$/update-use-client-effect$-to-use-visisble-task$.ts @@ -0,0 +1,73 @@ +import { + ensurePackage, + getProjects, + Tree, + visitNotIgnoredFiles, +} from '@nrwl/devkit'; +import { extname } from 'path'; +import { SyntaxKind } from 'typescript'; + +export default async function update(tree: Tree) { + ensurePackage('ts-morph', '^17.0.0'); + const tsMorph = await import('ts-morph'); + for (const [, definition] of getProjects(tree)) { + visitNotIgnoredFiles(tree, definition.root, (file) => { + if (extname(file) === '.tsx') { + updateNamedImport( + tree, + tsMorph, + file, + '@builder.io/qwik', + 'useClientEffect$', + 'useVisibleTask$' + ); + } + }); + } +} + +function updateNamedImport( + tree: Tree, + tsMorph: typeof import('ts-morph'), + filePath: string, + importModuleSpecifier: string, + importName: string, + updatedImportName: string +) { + const fileContent = tree.read(filePath)!.toString(); + const project = new tsMorph.Project(); + const sourceFile = project.createSourceFile('temp.ts', fileContent); + const imports = sourceFile.getImportDeclarations(); + const relevantImports = imports + .map((imp) => { + const moduleSpecifier = imp.getModuleSpecifierValue(); + if (moduleSpecifier !== importModuleSpecifier) { + return []; + } + return imp + .getNamedImports() + .filter((namedImport) => namedImport.getName() === importName); + }) + .filter((imports) => imports.length) + .flat(); + + if (relevantImports.length > 0) { + relevantImports.forEach((imp) => imp.replaceWithText(updatedImportName)); + + sourceFile.forEachDescendant((node) => { + if ( + node.getKind() === SyntaxKind.Identifier && + node.getText() === importName && + [SyntaxKind.CallExpression, SyntaxKind.VariableDeclaration].includes( + node.getParent()?.getKind() as SyntaxKind + ) + ) { + node.replaceWithText(updatedImportName); + } + }); + + tree.write(filePath, sourceFile.getFullText()); + } + + return tree; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d12b5260..7452e0a9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,6 +51,7 @@ importers: tcp-port-used: 1.0.2 tree-kill: 1.2.2 ts-jest: 29.0.5 + ts-morph: 17.0.1 ts-node: 10.9.1 tslib: ^2.3.0 typescript: 4.9.5 @@ -107,6 +108,7 @@ importers: tcp-port-used: 1.0.2 tree-kill: 1.2.2 ts-jest: 29.0.5_tdvb75zhi4rosovphsrxxq3mum + ts-morph: 17.0.1 ts-node: 10.9.1_tsi375xftxorovxtfm3hlbydte typescript: 4.9.5 verdaccio: 5.21.1_typanion@3.12.1 @@ -3694,6 +3696,18 @@ packages: engines: { node: '>= 10' } dev: true + /@ts-morph/common/0.18.1: + resolution: + { + integrity: sha512-RVE+zSRICWRsfrkAw5qCAK+4ZH9kwEFv5h0+/YeHTLieWP7F4wWq4JsKFuNWG+fYh/KF+8rAtgdj5zb2mm+DVA==, + } + dependencies: + fast-glob: 3.2.12 + minimatch: 5.1.0 + mkdirp: 1.0.4 + path-browserify: 1.0.1 + dev: true + /@tsconfig/node10/1.0.9: resolution: { @@ -5426,6 +5440,13 @@ packages: engines: { iojs: '>= 1.0.0', node: '>= 0.12.0' } dev: true + /code-block-writer/11.0.3: + resolution: + { + integrity: sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==, + } + dev: true + /collect-v8-coverage/1.0.1: resolution: { @@ -10704,6 +10725,13 @@ packages: engines: { node: '>= 0.8' } dev: true + /path-browserify/1.0.1: + resolution: + { + integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==, + } + dev: true + /path-exists/3.0.0: resolution: { @@ -12431,6 +12459,16 @@ packages: yargs-parser: 21.1.1 dev: true + /ts-morph/17.0.1: + resolution: + { + integrity: sha512-10PkHyXmrtsTvZSL+cqtJLTgFXkU43Gd0JCc0Rw6GchWbqKe0Rwgt1v3ouobTZwQzF1mGhDeAlWYBMGRV7y+3g==, + } + dependencies: + '@ts-morph/common': 0.18.1 + code-block-writer: 11.0.3 + dev: true + /ts-node/10.9.1_tsi375xftxorovxtfm3hlbydte: resolution: {