Skip to content
This repository has been archived by the owner on Sep 30, 2024. It is now read-only.

web: migrate from yarn to pnpm #46143

Merged
merged 56 commits into from
Jan 12, 2023
Merged

web: migrate from yarn to pnpm #46143

merged 56 commits into from
Jan 12, 2023

Conversation

valerybugakov
Copy link
Member

@valerybugakov valerybugakov commented Jan 5, 2023

Context

Bazel's rules_js rely on the pnpm package manager. To simplify the integration, we're migrating to pnpm from our current package manager — yarn. Another reason to migrate is that pnpm is cool and fast. 😉

Closes:

Breaking changes

If you used yarn commands directly, most of them should still work by replacing yarn with pnpm.
E.g., yarn build-ts —> pnpm build-ts. For more advanced commands, refer to pnpm documentation.

If you used only sg to interface with our npm scripts — nothing changes for you. All sg commands should work without changes.

Test plan

  1. CI.
  2. Local DX is intact.

Install pnpm locally with asdf install or npm i -g pnpm.

rm -rf node_modules ./client/*/node_modules
pnpm install

# Test your workflows!

@valerybugakov valerybugakov self-assigned this Jan 5, 2023
@cla-bot cla-bot bot added the cla-signed label Jan 5, 2023
@github-actions github-actions bot added the team/code-exploration Issues owned by the Code Exploration team label Jan 5, 2023
@sg-e2e-regression-test-bob
Copy link

sg-e2e-regression-test-bob commented Jan 5, 2023

Bundle size report 📦

Initial size Total size Async size Modules
-0.38% (-10.57 kb) 🔽 -0.03% (-4.02 kb) 0.06% (+6.55 kb) 0.42% (+3) 🔺

Look at the Statoscope report for a full comparison between the commits a765b31 and b277484 or learn more.

Open explanation
  • Initial size is the size of the initial bundle (the one that is loaded when you open the page)
  • Total size is the size of the initial bundle + all the async loaded chunks
  • Async size is the size of all the async loaded chunks
  • Modules is the number of modules in the initial bundle

Base automatically changed from contractors/SG-45990 to vb/pnpm-test-2 January 6, 2023 03:16
@valerybugakov valerybugakov requested review from a team and jbedard January 11, 2023 01:15
Comment on lines +15 to +16
# We have to hoist eslint packages to use them in the `.eslintrc` config.
public-hoist-pattern[]=*eslint*
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only required when Storybook packages are hoisted. We can remove both patterns after upgrading Storybook to v7.

@sourcegraph-bot
Copy link
Contributor

sourcegraph-bot commented Jan 11, 2023

Codenotify: Notifying subscribers in CODENOTIFY files for diff b277484...a765b31.

Notify File(s)
@bobheadxi .github/workflows/licenses-check.yml
.github/workflows/licenses-update.yml
enterprise/dev/ci/internal/ci/cache_helpers.go
enterprise/dev/ci/internal/ci/changed/diff.go
enterprise/dev/ci/internal/ci/changed/files.go
enterprise/dev/ci/internal/ci/operations.go
@efritz doc/code_navigation/explanations/diagrams/generate.sh
doc/code_navigation/how-to/index_a_typescript_and_javascript_repository.md
doc/dev/background-information/codeintel/diagrams/generate.sh
@philipp-spiess client/jetbrains/CONTRIBUTING.md
client/jetbrains/package.json
client/jetbrains/scripts/release.sh
@vdavid client/jetbrains/CONTRIBUTING.md
client/jetbrains/package.json
client/jetbrains/scripts/release.sh

@sourcegraph-bot
Copy link
Contributor

sourcegraph-bot commented Jan 11, 2023

Codenotify: Notifying subscribers in OWNERS files for diff b277484...a765b31.

Notify File(s)
@mrnugget dev/sg/checks.go
dev/sg/dependencies/helpers.go
dev/sg/dependencies/mac.go
dev/sg/dependencies/shared.go
dev/sg/linters/linters.go
dev/sg/linters/prettier.go
dev/sg/linters/svg.go
dev/sg/sg.config.example.yaml
@sourcegraph/code-exploration-devs client/common/package.json
client/http-client/package.json
client/observability-client/package.json
client/observability-server/package.json
client/observability-server/src/honeycomb/clone-boards.ts
client/observability-server/src/webBundleSize/index.ts
client/wildcard/package.json
client/wildcard/src/components/Charts/components/stacked-meter/StackedMeter.story.tsx
client/wildcard/src/components/Charts/components/stacked-meter/StackedMeter.test.tsx
@sourcegraph/dev-experience dev/sg/checks.go
dev/sg/dependencies/helpers.go
dev/sg/dependencies/mac.go
dev/sg/dependencies/shared.go
dev/sg/linters/linters.go
dev/sg/linters/prettier.go
dev/sg/linters/svg.go
dev/sg/sg.config.example.yaml
enterprise/dev/ci/internal/ci/cache_helpers.go
enterprise/dev/ci/internal/ci/changed/diff.go
enterprise/dev/ci/internal/ci/changed/files.go
enterprise/dev/ci/internal/ci/operations.go
@sourcegraph/frontend-platform-devs client/build-config/package.json
client/build-config/src/paths.ts
@vovakulikov client/wildcard/package.json
client/wildcard/src/components/Charts/components/stacked-meter/StackedMeter.story.tsx
client/wildcard/src/components/Charts/components/stacked-meter/StackedMeter.test.tsx

@valerybugakov valerybugakov changed the title web: pnpm migration updates web: migrate from yarn to pnpm Jan 11, 2023
@valerybugakov
Copy link
Member Author

Backend integration tests fail on main too 👀

Copy link
Contributor

@philipp-spiess philipp-spiess left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 🚀 🚀

Screenshot 2023-01-11 at 11 05 39

I wonder what's causing the bundle size to degree but I AM DOWN FOR IT!

Let's get this merged sooner rather than later, the surface for conflicts seem huge 😅

I was wondering if we can install a custom yarn shim somehow that only does echo "Use pnpm instead" && exit 1 or so but I wouldn't know where to put it so that it is in everyone's PATH and takes precedence over the asdf installation one 🤔

- uses: pnpm/action-setup@v2
id: pnpm-install
with:
version: 7.24.2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid hard coding the version in the github workflow, I've used this action before. Maybe we can reuse it here?

      # The pnpm GitHub action does not support reading the version from
      # .tool-versions yet so we have to be creative.
      - name: Read .tool-versions
        uses: marocchino/tool-versions-action@v1
        id: versions

      - name: Setup pnpm
        uses: pnpm/action-setup@v2
        with:
          version: ${{ steps.versions.outputs.pnpm}}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find, I love that. Let's do it in a follow-up PR!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh nice, that's awesome!

.github/workflows/scip-typescript.yml Show resolved Hide resolved
.tool-versions Show resolved Hide resolved
WORKSPACE Show resolved Hide resolved
dev/ci/integration/setup-deps.sh Outdated Show resolved Hide resolved
dev/ci/pnpm-install-with-retry.sh Outdated Show resolved Hide resolved
doc/dev/background-information/ci/development.md Outdated Show resolved Hide resolved
@eseliger
Copy link
Member

I was wondering if we can install a custom yarn shim somehow that only does echo "Use pnpm instead" && exit 1 or so but I wouldn't know where to put it so that it is in everyone's PATH and takes precedence over the asdf installation one 🤔

☝️ that's a great idea

// the bundlesize thing concerns me a bit, there's no free drinks here, is it? 😆

Copy link
Member

@eseliger eseliger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did a code pass, will do a functional test in a bit. LGTM! Thanks for working through this :)

"client/*",
"dev/release"
]
},
"devDependencies": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how come there are quite a few changes in the listed dependencies here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With node_modules hoisting disabled, pnpm makes it impossible to use packages not specified in the package.json file. This change revealed several dependencies we use but didn't add to our dependencies list explicitly.

@@ -1,6 +1,7 @@
lockfileVersion: 5.4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

were you able to keep exactly the same pinned versions that we had in yarn.lock? Just curious, not necessarily a blocker but would make this switch much less regression-prone.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the pnpm import transforms the yarn.lock file into the pnpm-lock.yaml, preserving pinned versions.

@@ -233,6 +233,11 @@ const config = {
resolve: {
extensions: ['.mjs', '.ts', '.tsx', '.js', '.json'],
mainFields: ['es2015', 'module', 'browser', 'main'],
fallback: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why was this not required before?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't required before the package hoisting was disabled. We can see that the main-dry-run build with hoisting=true is green. My guess is that without hoisting some internal modules stopped having access to the hoisted implementations of these packages, that's why we now need to have fallbacks for them.

@@ -205,7 +196,7 @@ const webviewConfig = {
loader: 'worker-loader',
options: { inline: 'no-fallback' },
},
'ts-loader',
getBabelLoader(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the difference here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, interesting, the whole time we transpire vscode client with tsc instead of babel with TS preset?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I tried to find the context behind this decision but didn't discover anything that prevents us from switching to babel. This was found when we bumped into TS errors upon building the VSCode extension, and it should not happen because we do type-checking as a separate CI step.

@eseliger
Copy link
Member

tried it locally, nothing broke :)

@@ -1,18 +1,13 @@
import { Meta, Story } from '@storybook/react'
import ParentSize from '@visx/responsive/lib/components/ParentSizeModern'

import webStyles from '@sourcegraph/web/src/SourcegraphWebApp.scss'
import { BrandedStory } from '@sourcegraph/wildcard/src/stories'
import { BrandedStory } from '../../../../stories'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the *.story.tsx files are part of the @sourcegraph/wildcard package? So should import by name like previously, instead of relatively within the package...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update the configuration somehow to enable that. Typescript complains about absolute imports like that inside of the package because it cannot locate type definitions for @sourcegraph/wildcard/src/stories. Let's discuss and update it in a follow-up PR.

jest.config.base.js Outdated Show resolved Hide resolved
Copy link
Contributor

@vovakulikov vovakulikov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested manually, all standard flows work as expected (at least subset that I use), if CI is happy I'm happy too. Big thanks to @valerybugakov this is blazingly amazing

.github/workflows/lighthouse-production.yml-disabled Outdated Show resolved Hide resolved
client/branded/package.json Outdated Show resolved Hide resolved
@@ -158,7 +158,7 @@ export const createSharedIntegrationTestContext = async <

// Fail the test in the case a request handler threw an error,
// e.g. because a request had no mock defined.
const cdpAdapter = polly.adapters.get(CdpAdapter.id) as CdpAdapter
const cdpAdapter = polly.adapters.get(CdpAdapter.id) as unknown as CdpAdapter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just out of curiosity is pnpm migration related to this and other TypeScript types fixes in this PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pnpm migration-related change that started happening after disabling the package hoisting.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's related to the fact that I installed @types/pollyjs__adapter to fix another TS issue before doing this change.

@@ -205,7 +196,7 @@ const webviewConfig = {
loader: 'worker-loader',
options: { inline: 'no-fallback' },
},
'ts-loader',
getBabelLoader(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, interesting, the whole time we transpire vscode client with tsc instead of babel with TS preset?

enterprise/cmd/frontend/pre-build.sh Outdated Show resolved Hide resolved
dev/ci/integration/setup-deps.sh Outdated Show resolved Hide resolved
Comment on lines -195 to +190
use: [
{
loader: 'ts-loader',
},
],
use: [getBabelLoader()],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VSCode extensions changes were reviewed here:

Name: "yarn",
Check: checkYarnVersion,
Name: "pnpm",
Check: checkPnpmVersion,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally by running: go run ./dev/sg setup -check

dev/ci/pnpm-install-with-retry.sh Outdated Show resolved Hide resolved
.tool-versions Show resolved Hide resolved
- uses: pnpm/action-setup@v2
id: pnpm-install
with:
version: 7.24.2
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find, I love that. Let's do it in a follow-up PR!

@@ -158,7 +158,7 @@ export const createSharedIntegrationTestContext = async <

// Fail the test in the case a request handler threw an error,
// e.g. because a request had no mock defined.
const cdpAdapter = polly.adapters.get(CdpAdapter.id) as CdpAdapter
const cdpAdapter = polly.adapters.get(CdpAdapter.id) as unknown as CdpAdapter
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pnpm migration-related change that started happening after disabling the package hoisting.

@@ -158,7 +158,7 @@ export const createSharedIntegrationTestContext = async <

// Fail the test in the case a request handler threw an error,
// e.g. because a request had no mock defined.
const cdpAdapter = polly.adapters.get(CdpAdapter.id) as CdpAdapter
const cdpAdapter = polly.adapters.get(CdpAdapter.id) as unknown as CdpAdapter
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's related to the fact that I installed @types/pollyjs__adapter to fix another TS issue before doing this change.

@@ -233,6 +233,11 @@ const config = {
resolve: {
extensions: ['.mjs', '.ts', '.tsx', '.js', '.json'],
mainFields: ['es2015', 'module', 'browser', 'main'],
fallback: {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't required before the package hoisting was disabled. We can see that the main-dry-run build with hoisting=true is green. My guess is that without hoisting some internal modules stopped having access to the hoisted implementations of these packages, that's why we now need to have fallbacks for them.

@@ -1,18 +1,13 @@
import { Meta, Story } from '@storybook/react'
import ParentSize from '@visx/responsive/lib/components/ParentSizeModern'

import webStyles from '@sourcegraph/web/src/SourcegraphWebApp.scss'
import { BrandedStory } from '@sourcegraph/wildcard/src/stories'
import { BrandedStory } from '../../../../stories'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update the configuration somehow to enable that. Typescript complains about absolute imports like that inside of the package because it cannot locate type definitions for @sourcegraph/wildcard/src/stories. Let's discuss and update it in a follow-up PR.

jest.config.base.js Outdated Show resolved Hide resolved
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
aspect-dev bazel cla-signed team/code-exploration Issues owned by the Code Exploration team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants