From 5c1d4a24b37c2fc59756bf5f6a2b140dda31e211 Mon Sep 17 00:00:00 2001 From: Vincent Rubinetti Date: Mon, 11 Mar 2024 16:55:42 -0400 Subject: [PATCH] Node/Yarn to Bun (#624) Converts repo from using Node and Yarn to just using Bun, and upgrades packages (notably Vite -> v5). This is not absolutely necessary. In my testing, it saves some headache and time, but it's also possible it could cause a problem down the road. See the added note in the readme. I think using Bun just as a package manager is very low risk, so at the very least we could replace Yarn with Bun. In my testing, starting from cleared caches, Yarn took 1 minute to install the frontend dependencies, and Bun took 6 seconds (where simply downloading the packages was the main bottleneck). This could save us time waiting for frontend tests to finish, and possibly some $$ if we were to ever go over GitHub Actions quota. Using Bun as a Node replacement, again from anecdotal evidence, is also fairly low risk. They seem to have already covered the general, commonly used Node functionality, and have tested popular tools like Vite to make sure they work with Bun. In some edge cases though, Bun might not behave _exactly_ as Node. But that is a bug in Bun, as they explicitly say that anything in Node should also work in Bun. The other reason it's low risk is that it shouldn't be difficult to go back to Node if there is ever a problem. The biggest risk, I think, is there being a problem, and the maintainers not being aware that it could be a Bun bug. Using Bun as a bundler or test runner would probably be a bigger change, and could cause more problems, in my estimation, so that is left out of this PR. Another caveat: Bun's support of Windows is still in progress. They say about 90% of Bun's test suite passes on Windows. @kevinschaper If someone has a laptop that does NOT have node or yarn installed on it, I'd be interested to test to make sure that _just_ installing Bun will work as expected. Theoretically, Bun should be the only installation requirement for the frontend after this. --------- Co-authored-by: Glass --- .../workflows/build-and-deploy-images.yaml | 10 +- .github/workflows/test-frontend.yaml | 99 +- Makefile | 12 +- frontend/.eslintrc | 35 + frontend/.eslintrc.js | 54 - frontend/README.md | 55 +- frontend/bun.lockb | Bin 0 -> 237622 bytes frontend/e2e/text-annotator.test.ts | 1 + frontend/package.json | 85 +- frontend/public/mockServiceWorker.js | 4 +- frontend/src/api/search.ts | 1 - frontend/src/components/AppSelectMulti.vue | 12 +- frontend/src/components/AppSelectSingle.vue | 12 +- frontend/src/components/TheHeader.vue | 3 +- frontend/src/pages/explore/TabSearch.vue | 2 +- frontend/tsconfig.json | 3 +- frontend/{vite.config.ts => vite.config.mjs} | 0 frontend/vitest.config.ts | 2 +- frontend/yarn.lock | 4274 ----------------- 19 files changed, 169 insertions(+), 4495 deletions(-) create mode 100644 frontend/.eslintrc delete mode 100644 frontend/.eslintrc.js create mode 100644 frontend/bun.lockb rename frontend/{vite.config.ts => vite.config.mjs} (100%) delete mode 100644 frontend/yarn.lock diff --git a/.github/workflows/build-and-deploy-images.yaml b/.github/workflows/build-and-deploy-images.yaml index 98102131d..070bb4f05 100644 --- a/.github/workflows/build-and-deploy-images.yaml +++ b/.github/workflows/build-and-deploy-images.yaml @@ -50,16 +50,14 @@ jobs: with: fetch-depth: 0 # to get all tags - - name: Set up Node - uses: actions/setup-node@v3 - with: - node-version: "18" + - name: Set up Bun + uses: oven-sh/setup-bun@v1 - name: Install packages - run: yarn install + run: bun install - name: Build app - run: yarn build + run: bun run build - name: Generate Image Tag for Frontend Dir id: get-tag diff --git a/.github/workflows/test-frontend.yaml b/.github/workflows/test-frontend.yaml index 1fcbeb5b7..3b9dafc79 100644 --- a/.github/workflows/test-frontend.yaml +++ b/.github/workflows/test-frontend.yaml @@ -12,130 +12,97 @@ defaults: working-directory: ./frontend jobs: - # build cache for rest of jobs - install-cache: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Node - uses: actions/setup-node@v4 - with: - node-version: "18" - - - name: Install packages - run: yarn install - - - name: Install Playwright - run: npx playwright install - - - name: Define cache key - id: define-key - run: echo "key=${{ hashFiles('frontend/yarn.lock') }}" >> $GITHUB_OUTPUT - - - name: Store cache - uses: actions/cache@v4 - with: - path: ${{ env.CACHE_PATH }} - key: ${{ steps.define-key.outputs.key }} - - outputs: - cache-key: ${{ steps.define-key.outputs.key }} - # test that app can build without issues test-build: runs-on: ubuntu-latest - needs: install-cache steps: - name: Checkout code uses: actions/checkout@v4 - - name: Restore cache - uses: actions/cache@v4 - with: - path: ${{ env.CACHE_PATH }} - key: ${{ needs.install-cache.outputs.cache-key }} + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Install packages + run: bun install - if: runner.debug == '1' uses: mxschmitt/action-tmate@v3 - name: Run test - run: yarn build + run: bun run build # test that app has no typescript errors test-types: runs-on: ubuntu-latest - needs: install-cache steps: - name: Checkout code uses: actions/checkout@v4 - - name: Restore cache - uses: actions/cache@v4 - with: - path: ${{ env.CACHE_PATH }} - key: ${{ needs.install-cache.outputs.cache-key }} + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Install packages + run: bun install - if: runner.debug == '1' uses: mxschmitt/action-tmate@v3 - name: Run test - run: yarn test:types + run: bun run test:types # test that app is properly formatted and linted test-lint: runs-on: ubuntu-latest - needs: install-cache steps: - name: Checkout code uses: actions/checkout@v4 - - name: Restore cache - uses: actions/cache@v4 - with: - path: ${{ env.CACHE_PATH }} - key: ${{ needs.install-cache.outputs.cache-key }} + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Install packages + run: bun install - if: runner.debug == '1' uses: mxschmitt/action-tmate@v3 - name: Run test - run: yarn test:lint + run: bun run test:lint # run unit tests test-unit: runs-on: ubuntu-latest - needs: install-cache steps: - name: Checkout code uses: actions/checkout@v4 - - name: Restore cache - uses: actions/cache@v4 - with: - path: ${{ env.CACHE_PATH }} - key: ${{ needs.install-cache.outputs.cache-key }} + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Install packages + run: bun install - name: Run test - run: yarn test:unit + run: bun run test:unit # run end to end integration tests test-e2e: runs-on: ubuntu-latest - needs: install-cache steps: - name: Checkout code uses: actions/checkout@v4 - - name: Restore cache - uses: actions/cache@v4 - with: - path: ${{ env.CACHE_PATH }} - key: ${{ needs.install-cache.outputs.cache-key }} + - name: Set up Bun + uses: oven-sh/setup-bun@v1 + + - name: Install packages + run: bun install + + - name: Install Playwright + run: bunx playwright install - if: runner.debug == '1' uses: mxschmitt/action-tmate@v3 - name: Run test - run: yarn test:e2e + run: bun run test:e2e diff --git a/Makefile b/Makefile index fd4e62d4a..e57b18111 100644 --- a/Makefile +++ b/Makefile @@ -71,8 +71,8 @@ install-backend: .PHONY: install-frontend install-frontend: cd frontend && \ - yarn install && \ - npx playwright install + bun install && \ + bunx playwright install .PHONY: model @@ -134,7 +134,7 @@ test-backend: .PHONY: test-frontend test-frontend: cd frontend && \ - yarn test + bun run test ### Development ### @@ -142,7 +142,7 @@ test-frontend: .PHONY: dev-frontend dev-frontend: frontend/src/api/model.ts cd frontend && \ - VITE_API=local yarn dev + VITE_API=local bun run dev .PHONY: dev-api @@ -190,7 +190,7 @@ lint: lint-frontend lint-backend .PHONY: lint-frontend lint-frontend: cd frontend && \ - yarn test:lint + bun run test:lint .PHONY: lint-backend @@ -212,4 +212,4 @@ format-backend: .PHONY: format-frontend format-frontend: cd frontend && \ - yarn lint + bun run lint diff --git a/frontend/.eslintrc b/frontend/.eslintrc new file mode 100644 index 000000000..702e771df --- /dev/null +++ b/frontend/.eslintrc @@ -0,0 +1,35 @@ +{ + "root": true, + "extends": [ + "plugin:vue/vue3-recommended", + "plugin:vuejs-accessibility/recommended", + "eslint:recommended", + "@vue/eslint-config-typescript", + "@vue/eslint-config-prettier/skip-formatting", + ], + "parserOptions": { + "ecmaVersion": "latest", + }, + "rules": { + "prettier/prettier": "warn", + "vuejs-accessibility/anchor-has-content": [ + "error", + { + "accessibleDirectives": ["tooltip"], + }, + ], + "vuejs-accessibility/label-has-for": [ + "error", + { + "controlComponents": ["AppInput"], + "required": { + "some": ["nesting", "id"], + }, + "allowChildren": true, + }, + ], + "vue/no-v-html": ["off"], + "vue/no-v-text-v-html-on-component": ["off"], + "vuejs-accessibility/mouse-events-have-key-events": ["off"], + }, +} diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js deleted file mode 100644 index 5494aedb6..000000000 --- a/frontend/.eslintrc.js +++ /dev/null @@ -1,54 +0,0 @@ -/* eslint-env node */ -require("@rushstack/eslint-patch/modern-module-resolution"); - -module.exports = { - root: true, - extends: [ - "plugin:vue/vue3-recommended", - "plugin:vuejs-accessibility/recommended", - "eslint:recommended", - "@vue/eslint-config-typescript", - "@vue/eslint-config-prettier/skip-formatting", - ], - parserOptions: { - ecmaVersion: "latest", - }, - - /** rule overrides (KEEP THIS AS MINIMAL AS POSSIBLE) */ - rules: { - "prettier/prettier": "warn", - - /** - * count v-tooltip (which adds an accessible aria-label attribute) as - * accessible - */ - "vuejs-accessibility/anchor-has-content": [ - "error", - { accessibleDirectives: ["tooltip"] }, - ], - /** - * allow nesting a control in a label without a for attribute (perfectly - * fine practice) - */ - "vuejs-accessibility/label-has-for": [ - "error", - { - controlComponents: ["AppInput"], - required: { some: ["nesting", "id"] }, - allowChildren: true, - }, - ], - /** - * allow v-html. we are only using this from very controlled sources, so - * little risk of XSS. - */ - "vue/no-v-html": ["off"], - "vue/no-v-text-v-html-on-component": ["off"], - /** - * important rule. only disregard in cases where mouse event only adds - * non-essentially functionality, e.g. hovering over a table cell to - * highlight its row and column. - */ - "vuejs-accessibility/mouse-events-have-key-events": ["off"], - }, -}; diff --git a/frontend/README.md b/frontend/README.md index 3063caaf8..770f87c9f 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,16 +1,16 @@ # Monarch Frontend -This project was scaffolded using Vite (`yarn create vite` → `Vue` → `create-vue`) with the following options: +This project was scaffolded using Vite (`bun create vite` → `Vue` → `create-vue`). +Stack summary: + +- Bun (for runtime and package manager, see note below) - TypeScript (for type checking) - Vue Router (for SPA navigation) - Vitest (unit testing) - Playwright (e2e testing) - ESLint (code quality) - Prettier (code formatting) - -Techniques/approaches used: - - Vue 3 - Composition API - `