Skip to content

Commit

Permalink
[EASI-3082] CRA -> Vite migration (#2163)
Browse files Browse the repository at this point in the history
* Add Vite and required packages

* Create vite.config.ts

* Move and update index.html

- Move index.html to root folder
- Remove %PUBLIC_URL% references
- Add Vite entry point

* Update tsconfig.json

* Create vite-env.d.ts

* Remove react-scripts

- Remove react-scripts
- Delete react-app-env.d.ts

* Update scripts in package.json

* Update env variables

* Change build output folder

* Remove craco

* Configure vite.config.ts for docker

* Updated caniuse-lite

Not necessary for vite migration, but removed warning message to update.

* Upgraded react-csv

Previous version was incompatible with Vite because Link component was .js file instead of .jsx

* Set scss load paths

* Hide uswds console notifications

* Upgrade storybook

* Upgrade Apollo

* Fix build script

* Fix Okta bug

* Fix uswds theme paths

* Enable css source maps

* Add autoprefixer

* Add autoprefixer to vite.config.ts

* Add vitest

* Snapshots

* Remove Jest canvas mock

* BusinessCaseReview test error

Error: Uncaught [TypeError: Cannot read properties of null (reading 'offsetWidth')]

* Upgrade Vite

Multiple installed versions of vite was causing type error

* Add vitest globals to tsconfig

* Add vi global to .eslintrc

* Replace jest global with vi

* Set global timezone

- Renamed jest-global-setup.js to global-setup.js
- Set timezone to UTC in global-setup.js
- Added globalSetup file to vite.config.ts

* Mock getTrbRequestDocumentsQuery

- Added mocked query to src/data/mock/trbRequest.ts
- Fixed missing mock query error in Consult.test.tsx

* Snapshots

* Added Vitest UI package

* Added vitest:ui

Opens unit tests in Vitest UI

* Removed jest-launchdarkly-references

* Fix createObjectURL JSDOM error

- Fixes error from react-csv: "TypeError: The "obj" argument must be an instance of Blob. Received an instance of Blob"
- JSDOM does not support window.URL.createObjectURL, so needed to mock in setupTests.ts

* Clay changes for vitest canvas mock, WIP, non functional

* Fix navigationBar test

* Fix setupTests typeError

* Fix Header unit test errors

- Fixed typo
- Wrapped component in Provider
- Updated to async function

* Enable threads

- Disabling threads causes tests to fail
- See vitest-dev/vitest#1430

* Fix flaky TRB Consult test

Test randomly threw error that no more mocked responses were available for getTRBRequestAttendeesQuery. Duplicating the query in the mocks array fixed this.

* Skip Tabs test

* Snapshots

* Update yarn.lock

* Update snapshot

* Remove unit tests that render Okta signin widget

* Remove vitest-canvas-mock

* Add role attribute to csv download link

byRole queries in unit tests were not recognizing csv download links as links because the href prop isn't set. Explicitly setting "role=link" solved this.

* Fix "cannot find offset width of null" error

* Fix unit test classlist argument error

* Remove vitest UI

* Fix references to REACT_APP_ env vars that have not yet been converted to use VITE_

* Enable test coverage when running yarn test:coverage with v8. See https://vitest.dev/guide/coverage.html for info

* Fix cypress plugins env variables bug

Changed import.meta.env to process.env

* Add cypress-vite

- Removed cypress/webpack-preprocessor
- Added cypress-vite

* Cypress-vite config updates

* Empty commit

* Debug file:preprocessor

* Upgrade Cypress

* Comment out tests that import app code

* Comment out missed suite with imports

* Re-introduce webpack for Cypress

* Uncomment tests

* Cleanup

- Removed commented out debug code
- Uncommented e2e test code

* Enable cypress video

* Set long timeout on Okta login

* Try clicking multiple times

* Try clicking multiple times

* Upgrade okta-signin-widget from 6 to 7

* Undo multi click in Cypress

* import css from okta widget using exported path. Add commonjsOptions to transform require to import in imported modules

* Remove extra setting of VITE_OKTA_REDIRECT_URI

* Remove references to craco, add ADR

* Remove unused packages. Add comments, remove TODO comments.

---------

Co-authored-by: ClayBenson94 <clay.benson@oddball.io>
  • Loading branch information
aterstriep and ClayBenson94 committed Sep 11, 2023
1 parent 005fe51 commit a545d93
Show file tree
Hide file tree
Showing 180 changed files with 5,959 additions and 12,951 deletions.
22 changes: 11 additions & 11 deletions .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ export CLIENT_PORT=3000
export CLIENT_HOSTNAME=$CLIENT_DOMAIN:$CLIENT_PORT
export CLIENT_ADDRESS=$CLIENT_PROTOCOL://$CLIENT_HOSTNAME
export API_PORT=8080
export REACT_APP_API_ADDRESS=$CLIENT_PROTOCOL://$CLIENT_DOMAIN:$API_PORT/api/v1
export REACT_APP_GRAPHQL_ADDRESS=$CLIENT_PROTOCOL://$CLIENT_DOMAIN:$API_PORT/api/graph/query
export REACT_APP_APP_ENV=$APP_ENV
export VITE_API_ADDRESS=$CLIENT_PROTOCOL://$CLIENT_DOMAIN:$API_PORT/api/v1
export VITE_GRAPHQL_ADDRESS=$CLIENT_PROTOCOL://$CLIENT_DOMAIN:$API_PORT/api/graph/query
export VITE_APP_ENV=$APP_ENV
export LOCAL_AUTH_ENABLED=true
export REACT_APP_LOCAL_AUTH_ENABLED=true
export VITE_LOCAL_AUTH_ENABLED=true

# Email variables
export EMAIL_TEMPLATE_DIR=$APP_DIR/pkg/email/templates
Expand All @@ -52,16 +52,16 @@ export LAMBDA_ENDPOINT="http://localhost:9001"
# OKTA variables
export OKTA_CLIENT_ID=0oa2e913coDQeG19S297
export OKTA_CLIENT_ID_DEV=0oa2e913coDQeG19S297
export REACT_APP_OKTA_CLIENT_ID=$OKTA_CLIENT_ID
export VITE_OKTA_CLIENT_ID=$OKTA_CLIENT_ID
export OKTA_DOMAIN=https://test.idp.idm.cms.gov
export REACT_APP_OKTA_DOMAIN=$OKTA_DOMAIN
export VITE_OKTA_DOMAIN=$OKTA_DOMAIN
export OKTA_SERVER_ID=aus2e96etlbFPnBHt297
export OKTA_SERVER_ID_DEV=aus2e96etlbFPnBHt297
export REACT_APP_OKTA_SERVER_ID=$OKTA_SERVER_ID
export VITE_OKTA_SERVER_ID=$OKTA_SERVER_ID
export OKTA_ISSUER=$OKTA_DOMAIN/oauth2/$OKTA_SERVER_ID
export REACT_APP_OKTA_ISSUER=$OKTA_ISSUER
export VITE_OKTA_ISSUER=$OKTA_ISSUER
export OKTA_REDIRECT_URI=http://localhost:3000/implicit/callback
export REACT_APP_OKTA_REDIRECT_URI=$OKTA_REDIRECT_URI
export VITE_OKTA_REDIRECT_URI=$OKTA_REDIRECT_URI
export OKTA_API_URL=https://test.idp.idm.cms.gov
export USE_OKTA_API=true
# Needed for Okta login if not using local. Look in 1Password.
Expand All @@ -76,7 +76,7 @@ export OKTA_TEST_SECRET=
# Launch Darkly configuration
export FLAG_SOURCE=LOCAL # LAUNCH_DARKLY, LOCAL, or FILE
export LD_SDK_KEY="check 1Password to find this value"
export REACT_APP_LD_CLIENT_ID=63231d448bd05a111f06195b # Points to our "local" environment
export VITE_LD_CLIENT_ID=63231d448bd05a111f06195b # Points to our "local" environment
export LD_TIMEOUT_SECONDS=30
export FLAGDATA_FILE="./cypress/fixtures/flagdata.json" # File to load LD flag data from when FLAG_SOURCE=FILE

Expand All @@ -100,7 +100,7 @@ export DB_MAX_CONNECTIONS=20
# For exposing a locally running app to other machines via Tailscale
export TAILSCALE_HOSTNAME=$(hostname | awk '{gsub(/\.local$/,""); print tolower($0)}').truss.works.beta.tailscale.net
export TAILSCALE_CLIENT_ADDRESS="http://${TAILSCALE_HOSTNAME}:3000"
export TAILSCALE_REACT_APP_API_ADDRESS="http://${TAILSCALE_HOSTNAME}:8080/api/v1"
export TAILSCALE_VITE_API_ADDRESS="http://${TAILSCALE_HOSTNAME}:8080/api/v1"
export TAILSCALE_REACT_GRAPHQL_ADDRESS="http://${TAILSCALE_HOSTNAME}:8080/api/graph/query"
export TAILSCALE_MINIO_ADDRESS="http://${TAILSCALE_HOSTNAME}:9000"

Expand Down
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"ignorePatterns": ["**/*.d.ts", "serviceWorker.ts",".storybook/**/*"],
"globals" : {
"JSX" : "readonly"
"JSX" : "readonly",
"vi": true
},
"root": true,
"extends": [
Expand Down
19 changes: 19 additions & 0 deletions .github/workflows/run_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,25 @@ jobs:
uses: actions/checkout@v4
with:
ref: ${{ env.GIT_HASH }}
- name: Set up node
uses: actions/setup-node@v3
with:
node-version: ${{ env.EASI_APP_NODE_VERSION }}
cache: 'yarn'
- name: Install yarn dependencies
run: yarn install --frozen-lockfile
- name: Build frontend code
env:
VITE_API_ADDRESS: http://easi:8080/api/v1
VITE_GRAPHQL_ADDRESS: http://easi:8080/api/graph/query
VITE_APP_ENV: test
VITE_OKTA_CLIENT_ID: 0oa2e913coDQeG19S297
VITE_OKTA_DOMAIN: https://test.idp.idm.cms.gov
VITE_OKTA_SERVER_ID: aus2e96etlbFPnBHt297
VITE_OKTA_ISSUER: https://test.idp.idm.cms.gov/oauth2/aus2e96etlbFPnBHt297
VITE_OKTA_REDIRECT_URI: http://localhost:3000/implicit/callback
VITE_LOCAL_AUTH_ENABLED: true
run: yarn run build
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
Expand Down
2 changes: 2 additions & 0 deletions .spelling
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ deliverables
Sprague
Shoup
TinyMCE
Vite

# Jira ticket numbers
# The underlying spellchecking package doesn't currently support patterns; see https://github.com/lukeapage/node-markdown-spellcheck/issues/49
Expand All @@ -212,3 +213,4 @@ EASI-1447
EASI-3224
EASI-2888
EASI-3019
EASI-3082
19 changes: 9 additions & 10 deletions Dockerfile.client
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,22 @@ RUN yarn install --frozen-lockfile

FROM modules AS src

COPY craco.config.js ./
COPY tsconfig.json ./
COPY .eslintrc ./
COPY public ./public
COPY src ./src

FROM src AS build

ARG REACT_APP_APP_ENV
ARG REACT_APP_API_ADDRESS
ARG REACT_APP_GRAPHQL_ADDRESS
ARG REACT_APP_OKTA_CLIENT_ID
ARG REACT_APP_OKTA_DOMAIN
ARG REACT_APP_OKTA_ISSUER
ARG REACT_APP_OKTA_REDIRECT_URI
ARG REACT_APP_OKTA_SERVER_ID
ARG REACT_APP_LOCAL_AUTH_ENABLED
ARG VITE_APP_ENV
ARG VITE_API_ADDRESS
ARG VITE_GRAPHQL_ADDRESS
ARG VITE_OKTA_CLIENT_ID
ARG VITE_OKTA_DOMAIN
ARG VITE_OKTA_ISSUER
ARG VITE_OKTA_REDIRECT_URI
ARG VITE_OKTA_SERVER_ID
ARG VITE_LOCAL_AUTH_ENABLED

RUN yarn run build

Expand Down
35 changes: 0 additions & 35 deletions craco.config.js

This file was deleted.

1 change: 1 addition & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { defineConfig } from 'cypress';
export default defineConfig({
viewportHeight: 800,
viewportWidth: 1280,
video: true,
e2e: {
// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
Expand Down
2 changes: 1 addition & 1 deletion cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ module.exports = (on, config) => {
newConfig.env.username = process.env.OKTA_TEST_USERNAME;
newConfig.env.password = process.env.OKTA_TEST_PASSWORD;
newConfig.env.otpSecret = process.env.OKTA_TEST_SECRET;
newConfig.env.systemIntakeApi = `${process.env.REACT_APP_API_ADDRESS}/system_intake`;
newConfig.env.systemIntakeApi = `${process.env.VITE_API_ADDRESS}/system_intake`;

return config;
};
4 changes: 2 additions & 2 deletions cypress/support/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ Cypress.Commands.add('login', () => {
token => {
cy.get('input[name="answer"]').type(token, { log: false });
cy.get('input[name="rememberDevice"]').check({ force: true });
cy.get('input[value="Verify"').click();
cy.get('input[value="Verify"]').click();
}
);
});
}
});
cy.url().should('eq', 'http://localhost:3000/');
cy.url({ timeout: 20000 }).should('eq', 'http://localhost:3000/');
});

Cypress.Commands.add('localLogin', ({ name, role }) => {
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.cypress_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ services:
- OKTA_TEST_USERNAME
- OKTA_TEST_PASSWORD
- OKTA_TEST_SECRET
- REACT_APP_API_ADDRESS=http://easi:8080/api/v1
- VITE_API_ADDRESS=http://easi:8080/api/v1
- MINIO_ADDRESS=minio
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
Expand Down
18 changes: 9 additions & 9 deletions docker-compose.cypress_local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ services:
context: .
dockerfile: Dockerfile.client
args:
- REACT_APP_APP_ENV=test
- REACT_APP_API_ADDRESS=http://easi:8080/api/v1
- REACT_APP_OKTA_CLIENT_ID
- REACT_APP_OKTA_DOMAIN
- REACT_APP_OKTA_ISSUER
- REACT_APP_OKTA_REDIRECT_URI
- REACT_APP_OKTA_SERVER_ID
- REACT_APP_LOCAL_AUTH_ENABLED=true
- VITE_APP_ENV=test
- VITE_API_ADDRESS=http://easi:8080/api/v1
- VITE_OKTA_CLIENT_ID
- VITE_OKTA_DOMAIN
- VITE_OKTA_ISSUER
- VITE_OKTA_REDIRECT_URI
- VITE_OKTA_SERVER_ID
- VITE_LOCAL_AUTH_ENABLED=true
environment:
- CI=true #https://github.com/facebook/create-react-app/issues/8688
entrypoint: ['serve', '-s', '-l', '3000']
Expand All @@ -66,7 +66,7 @@ services:
- OKTA_TEST_USERNAME
- OKTA_TEST_PASSWORD
- OKTA_TEST_SECRET
- REACT_APP_API_ADDRESS=http://easi:8080/api/v1
- VITE_API_ADDRESS=http://easi:8080/api/v1
- MINIO_ACCESS_KEY
- MINIO_SECRET_KEY
- PGHOST=db
Expand Down
24 changes: 12 additions & 12 deletions docker-compose.override.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ services:
dockerfile: Dockerfile.client
target: src
environment:
- REACT_APP_APP_ENV
- REACT_APP_API_ADDRESS
- REACT_APP_GRAPHQL_ADDRESS
- REACT_APP_OKTA_CLIENT_ID
- REACT_APP_OKTA_DOMAIN
- REACT_APP_OKTA_ISSUER
- REACT_APP_OKTA_REDIRECT_URI
- REACT_APP_OKTA_SERVER_ID
- REACT_APP_LD_ENV_USER
- REACT_APP_LD_USER_HASH
- REACT_APP_LD_CLIENT_ID
- REACT_APP_LOCAL_AUTH_ENABLED
- VITE_APP_ENV
- VITE_API_ADDRESS
- VITE_GRAPHQL_ADDRESS
- VITE_OKTA_CLIENT_ID
- VITE_OKTA_DOMAIN
- VITE_OKTA_ISSUER
- VITE_OKTA_REDIRECT_URI
- VITE_OKTA_SERVER_ID
- VITE_LD_ENV_USER
- VITE_LD_USER_HASH
- VITE_LD_CLIENT_ID
- VITE_LOCAL_AUTH_ENABLED
- CHOKIDAR_USEPOLLING=true
- ESLINT_NO_DEV_ERRORS=true
entrypoint: ['yarn', 'start']
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.tailscale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ services:
- MINIO_ADDRESS=$TAILSCALE_MINIO_ADDRESS
easi_client:
environment:
- REACT_APP_API_ADDRESS=$TAILSCALE_REACT_APP_API_ADDRESS
- REACT_APP_GRAPHQL_ADDRESS=$TAILSCALE_REACT_GRAPHQL_ADDRESS
- VITE_API_ADDRESS=$TAILSCALE_VITE_API_ADDRESS
- VITE_GRAPHQL_ADDRESS=$TAILSCALE_REACT_GRAPHQL_ADDRESS
34 changes: 34 additions & 0 deletions docs/adr/0038-replace-craco-with-vite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Migrate from Create React App & Craco to Vite

**User Story:** [EASI-3082](https://jiraent.cms.gov/browse/EASI-3082)

Meta (the organization who created React) has formally stopped recommending that developers use Create React App. The reasons won't be enumerated here in perfect detail, but this [Pull Request](https://github.com/reactjs/react.dev/pull/5487) on the official React docs site is a good place to start if you want more context.

Given this recommendation, and with the fact that Vite promises (and delivers) faster compilation times, we have considered (and settled on) migrating the application to Vite.


## Considered Alternatives

* Stay on CRA/Craco
* Migrate to Vite

## Decision Outcome

* Chosen Alternative: **Migrate to Vite**

This approach, while a heavy lift, should provide us with faster compilation, better support, and a more modern toolchain.

## Pros and Cons of the Alternatives

### Stay on CRA/Craco

* `+` No config changes to make
* `+` CRA is a popular tool, despite its age and limitations
* `-` Less efficient (larger) bundle sizes
* `-` Much slower compilation times

### Migrate to Vite

* `+` Faster build times
* `+` More active support and development
* `-` Requires a lot of trial and error to migrate, with potential breaking changes
16 changes: 5 additions & 11 deletions public/index.html → index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="icon" href="/favicon.ico" />
<!-- TODO: This font should be imported through USWDS and not Google Fonts -->
<link
href="https://fonts.googleapis.com/css?family=Public+Sans:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&display=swap"
Expand All @@ -19,16 +19,8 @@
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<link rel="manifest" href="/manifest.json" />

<title>CMS EASi</title>
</head>
<body>
Expand All @@ -44,5 +36,7 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->

<script type="module" src="/src/index.tsx"></script>
</body>
</html>
3 changes: 0 additions & 3 deletions jest-global-setup.js

This file was deleted.

Loading

0 comments on commit a545d93

Please sign in to comment.