Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to support new Typescript, vite, Vitest and NX tooling #83

Merged
merged 44 commits into from
Sep 28, 2023
Merged

Conversation

SimeonC
Copy link
Collaborator

@SimeonC SimeonC commented Jun 30, 2023

Version

Published prerelease version: @tablecheck/nx@1.0.1-next.18

Changelog

⚠️ Pushed to next

  • ci: revert switch next to canary releases due to lerna issue (@SimeonC)
  • ci: switch next to canary releases due to lerna issue (@SimeonC)
  • fix: add forcePublish to npm publish to bump all packages in next (@SimeonC)
  • ci: skip husky in release actions install (@SimeonC)
  • fix: tests and github_actions (@SimeonC)
  • ci: fix github actions to have main branch for nx (@SimeonC)
  • @tablecheck/nx
    • fix: quality generator fixes and cleanups (@SimeonC)
    • fix(nx): quality executor should run prettier from root cwd to correctly resolve configs and ignores (@SimeonC)
    • fix: quality generator and migration include file-types (@SimeonC)
    • fix: add nx meta files to bundle for detection (@SimeonC)
    • ci: fix github release action (@SimeonC)
  • @tablecheck/commitlint-config
    • fix: remove start-case restriction in scope-case (@SimeonC)
    • fix(commitlint-config): use correct junit format via package (@SimeonC)
    • feat(commitlint-config): add junit formatter (@SimeonC)
  • @tablecheck/frontend-audit, @tablecheck/commitlint-config, @tablecheck/eslint-config, @tablecheck/eslint-plugin, @tablecheck/nx, @tablecheck/semantic-release-config, @tablecheck/frontend-utils
    • fix: prettier works with v2/v3 though v3 is preferred (@SimeonC)
    • fix: remove audit project and correct paths for nx schemas (@SimeonC)
    • feat: full build and passing lint via nx!! (@SimeonC)
    • feat: build runs and quality packages function (@SimeonC)
    • feat: move everything except quality (@SimeonC)
    • feat: scripts is dead, long live scripts! WIP! (@SimeonC)
  • @tablecheck/nx, @tablecheck/frontend-utils
    • feat: remove library build (use nx rollup) fixes for monorepo (@SimeonC)
    • fix: quality generator bugfixes (@SimeonC)
    • fix(nx): quality script should run correctly (@SimeonC)
    • fix: nx quality scripts and prettier fixes (@SimeonC)
    • fix: esm/cjs interop fixes (@SimeonC)
    • fix: pre-commit scripts and apply formatting (@SimeonC)
  • @tablecheck/eslint-config, @tablecheck/eslint-plugin, @tablecheck/nx, @tablecheck/prettier-config, @tablecheck/frontend-utils
    • feat: bump prettier and add lib publishing checks (@SimeonC)
  • @tablecheck/eslint-config, @tablecheck/eslint-plugin, @tablecheck/nx, @tablecheck/frontend-utils
    • fix: assorted bugfixes and rule tweaks (@SimeonC)
  • @tablecheck/frontend-audit, @tablecheck/eslint-config, @tablecheck/eslint-plugin, @tablecheck/nx, @tablecheck/frontend-utils
    • feat: upgrade eslint dependencies (@SimeonC)
    • fix: bump package versions in deps (@SimeonC)
    • fix: install from public npm and remove dist files (@SimeonC)
  • @tablecheck/eslint-plugin, @tablecheck/nx, @tablecheck/frontend-utils
  • @tablecheck/eslint-plugin, @tablecheck/nx, @tablecheck/prettier-config, @tablecheck/frontend-utils
    • fix: downgrade prettier to v2 (@SimeonC)
  • @tablecheck/frontend-audit, @tablecheck/nx, @tablecheck/frontend-utils
    • fix: nx requires commonjs or weird node memory errors occur (@SimeonC)
  • @tablecheck/frontend-audit, @tablecheck/nx, @tablecheck/prettier-config
    • fix: migrate script updates and remove dead packages (@SimeonC)
  • @tablecheck/commitlint-config, @tablecheck/eslint-config, @tablecheck/eslint-plugin, @tablecheck/nx, @tablecheck/prettier-config, @tablecheck/semantic-release-config, @tablecheck/frontend-utils
    • feat: add prettier config file and bump prettier version (@SimeonC)
  • @tablecheck/frontend-audit, @tablecheck/commitlint-config, @tablecheck/eslint-config, @tablecheck/eslint-plugin, @tablecheck/nx, @tablecheck/semantic-release-config
    • fix: audit works and passes (@SimeonC)
  • @tablecheck/frontend-audit, @tablecheck/eslint-plugin, @tablecheck/frontend-utils
  • @tablecheck/eslint-config, @tablecheck/nx, @tablecheck/frontend-utils
    • feat: remove stylelint and fix lint/ts issues (@SimeonC)
  • @tablecheck/eslint-plugin
    • feat: add shortest import eslint rule (@SimeonC)
  • @tablecheck/frontend-audit, @tablecheck/commitlint-config, @tablecheck/eslint-config, @tablecheck/eslint-plugin, @tablecheck/semantic-release-config, @tablecheck/frontend-utils
    • chore: deps upgrade (@SimeonC)
    • feat: major upgrade (@SimeonC)
    • refactor: get the ts to js build working nicely (@SimeonC)

Authors: 1

Dropping scripts and splitting out into multiple packages. We have also deprecated the usage of razzle and jest internally and recommend switching to vite/vitest.
Documentation, upgrade docs and setup templates to come in later commits once this is a bit more stable.

The newer packages are easier to run via npx (hopefully)

BREAKING CHANGE: scripts package removed
audit package working
Still need to refactor quality to be minimal package and move a lot of it into the nx package.
Need to fix a lot of errors.
Dropped the precommit entirely due to discussion in slack
(not quite working, something to do with ESM/package issues)
Stylelint just crashed in a lot of cases, remove to get this done faster and we can look at re-adding it later
@SimeonC SimeonC added the major Increment the major version when merged label Jun 30, 2023
@SimeonC SimeonC force-pushed the next branch 6 times, most recently from e1ebcd1 to 05e68b8 Compare July 7, 2023 06:14
@github-actions
Copy link

github-actions bot commented Jul 7, 2023

Unit Test Results

0 tests   0 ✔️  0s ⏱️
0 suites  0 💤
0 files    0

Results for commit d59f1a5.

♻️ This comment has been updated with latest results.

@SimeonC
Copy link
Collaborator Author

SimeonC commented Jul 11, 2023

TODO: upgrade to the new version of typescript-eslint

Included a fix to push `save-exact` to the root `.npmrc` to go along with our package deps conventions.
@SimeonC
Copy link
Collaborator Author

SimeonC commented Sep 28, 2023

Upgrade Process (Adapted from Here and Here)

Reference PRs:

Prepare for upgrade:

Create separate PRs for;

  1. Upgrade to react 18
  2. Change prettier config to have "trailingComma": "all" which is the v3 default we are aligning with. Can't upgrade prettier to v3 as it's locked in dependenciesp.b10 API changes but this should reduce 90% of those changes.
  3. Run knip and clean up any unused code, this reduces the surface area and fixing irrelevant files.
  4. Use patch-package to upgrade eslint and Typescript paths (refer this PR)

Upgrade

  1. Create an NX project next to the project you want to upgrade (consult the above links, recommend react-monorepo - make sure it's "vite") npx create-nx-workspace@latest --preset=react-monorepo CleanShot 2023-09-28 at 11 11 00

Important

Do not enable distributed caching at this point, we're over the limit so if we can get cloud subscription we can add them all.

  1. Ensure to set the encryptionKey value in nx.json to enable E2E encryption
    CleanShot 2023-09-29 at 18 43 26
  2. Run echo "v20.8.1" > .nvmrc (or latest nodejs)
  3. Add a .npmrc with the following; (remove the legacy-peer-deps if possible)
registry=https://tablecheck-934763610305.d.codeartifact.ap-northeast-1.amazonaws.com/npm/tablecheck/
legacy-peer-deps=true
  1. Upgrade Typescript + Vite + Prettier to the latest versions (run npm-upgrade package)
  2. Install TC NX packages - npm i -D @tablecheck/nx (will probably need --legacy-peer-deps)
  3. Run npx nx g @tablecheck/nx:quality or from the NX UI and follow the prompts for each "project"
  4. Run npm i
  5. Run npm i -D rollup-plugin-visualizer vite-plugin-checker (configured later)
  6. Remove .prettierrc (prettierrc.json is now used)
  7. Figure out what dependencies you need to keep and install (preferably the latest versions - recommend doing this via npm i ... and npm i -D ... over manual editing the package.json).
    • commitlint-format-junit is deprecated, use npx commitlint --format @tablecheck/commitlint-config/formatters/junit
  8. Merge the changes back into the original repo as the initial setup, removing old and unnecessary files at the same time.
  9. Commit all changes
  10. Migrate each of src cypress to their new homes. Committing for each folder to keep diffs smaller.
  11. Run npx prettier -w .
  12. Commit all changes
  13. Convert CONFIG -> VITE env vars (see below section)
  14. Update Semaphore as well (see https://github.com/tablecheck/portal-frontend/tree/main/.semaphore for an example on how use .env freely)
  15. Commit all changes
  16. Debug and run, build, test, lint separately. Commit as necessary.

Configuring Vite

Change vite.config.ts to include the following, note that the "Typescript" check is now part of the build not the lint/quality - NX will handle this as part of the @nx/vite build runner.

import { visualizer } from 'rollup-plugin-visualizer';

...
  build: {
    rollupOptions: {
      plugins: [
        visualizer({
          template: 'treemap',
          open: false,
          gzipSize: true,
          brotliSize: true,
          filename: 'analyse.html',
        }),
      ],
    },
  },
  plugins: [
    react(),
    nxViteTsPaths(),
  ],

Migrations

config (or node-config)

This package should be removed and all CONFIG variables re-written. The vite standard (and now in nodejs as well) is to use dotenv. A useful plugin for validating env vars is; https://github.com/Julien-R44/vite-plugin-validate-env (use the zod variant for a consistent UI with our upgrade path yup -> zod)

Great way to ease this migration is with Grit (example). Here are the list of Grit patterns I've used.

CONFIG to vite ENV

I run these two in sequence - replace with the values in your config.json files

pattern CONFIG_to_vite_env() {
    member_expression(object = $o, chain = $c, property = $p) where {
        $o <: contains `CONFIG` => `import.meta.env.VITE`,
        $c => `_`,
        or {
            $p <: `appVersion` => `APP_VERSION`,
            $p <: `environment` => `DEPLOY_TARGET`,
            $p => $p
        }
    }
}

pattern cleanup_vite_env() {
    member_expression(object = $o, chain = $c, property = $p) where {
        or {
            $p <: `VITE_spaConfig_insight` => `VITE_INSIGHT_HOST`,
            $p <: `VITE_spaConfig_settings` => `VITE_SETTINGS_HOST`,
            $p <: `VITE_DEV` => `DEV`,
            $p => $p
        }
    }
}

`@loadable/component` to React Suspense

pattern loadable_to_suspense() {
or {
    `import loadable from '@loadable/component';` as $import where {
        if ($import <: within program(statements = contains `import * as React from 'react'`)) {
            $import => .
        } else {
            $import => `import * as React from 'react';`
        }
    },
    `LoadableComponent<$generic>` where {
        $generic <: js"unknown" => `React.ComponentType`
    } => `ReturnType<typeof React.lazy<$generic>>`,
    or {
        `const $name = loadable($fileImport, $options) as $type;`,
        `$name: loadable($fileImport, $options) as $type`,
        `const $name = loadable($fileImport, $options);`,
        `$name: loadable($fileImport, $options)`,
        and {
            or {
                `const $name = loadable($fileImport);`,
                `$name: loadable($fileImport)`,
            },
            $options = `{}`
        }
    } as $statement where {
        or {
            and {
                or {
                    $options <: contains `resolveComponent: ($_) => $_.$import`,
                    $options <: contains `resolveComponent: ($_) => $_.$import as $_`
                }, 
                $importRemap = js".then(e => ({ default: e.$import }))"
            },
            $importRemap = js""
        },
        or {
            $options <: contains `fallback: $fallback`,
            $fallback = js"null"
        },
        or {
            $statement <: within pair() => `// TODO wrap with <React.Suspense fallback={$fallback}>
$name: React.lazy($fileImport$importRemap)`,
            $statement <: within export_statement() => `// TODO wrap with <React.Suspense fallback={$fallback}>
export const $name = React.lazy($fileImport$importRemap)`,
            $statement => `// TODO wrap with <React.Suspense fallback={$fallback}>
const $name = React.lazy($fileImport$importRemap)`
        }
    },
}
}

React Router v5 - v6

This is probably as much of a automatic conversion as can be sensibly done, other changes should be done manually.

pattern RR_to_v6() {
    or {
        `import { $props } from 'react-router-dom'` where {
            $props <: contains `useHistory` => `useNavigate`
        },
        `history.push($path)` => `navigate($path)`,
        `history.go` => `(steps: number) => navigate(steps)`,
        `history.go($a)` => `navigate($a)`,
        `history.goBack` => `() => navigate(-1)`,
        `history.goBack()` => `navigate(-1)`,
        `history.goForward` => `() => navigate(1)`,
        `history.goForward()` => `navigate(1)`,
        `history.replace($path)` => `navigate($path, { replace: true })`,
        `const history = useHistory()` => `const navigate = useNavigate()`
    }
}

TypeScript `baseUrl: src` to `paths["~/*"]`

Run with: `grit apply TS_prefix_absolute_path`

The switch from import A from 'components/A' to import A from '~/components/A' is to make our code more compatible with linter rules and other products that support paths/aliases but not the baseUrl method.

pattern TS_prefix_absolute_path() { 
    `import $_ from '$importFolder'` where {
        $importFolder <: r"^([a-zA-Z]+)(/.*|$)"($folder,$rest),
        $folder <: r"^(?:App|Common|Configs|data|definitions|enums|i18n|Layouts|Pages|Router|types|utils|storybook-assets)$" => js"~/$folder"
    }
}

.gitignore Outdated Show resolved Hide resolved
@SashaShostyr
Copy link
Contributor

SashaShostyr commented Sep 28, 2023

packages/eslint-plugin/__tests__/test_src contains empty files. Do we need it?

@SimeonC SimeonC enabled auto-merge (rebase) September 28, 2023 08:31
@SimeonC SimeonC merged commit 5c3b461 into main Sep 28, 2023
7 checks passed
@SimeonC SimeonC deleted the next branch September 28, 2023 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
major Increment the major version when merged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants