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

chore: migrate from yarn to pnpm #4897

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open

Conversation

cardoso
Copy link
Contributor

@cardoso cardoso commented Nov 20, 2024

Details

I'm still going through all scripts and haven't touched CI yet, but this is mostly working.

I don't know what external workflows might depend on things like the versions being spelled out in package.json and could break by using workspace:* and others. I initially made it work without that feature, so I can revert back to spelled out versions if needed.

Since pnpm doesn’t hoist dependencies to the root by default, it uncovers several issues similar to

I’m submitting fixes for those separately to make sure they are correct.

I recommend cloning in a separate folder or running git clean -dfX before trying this out.

pnpm version used: 9.14.2.

Closes #4426

Top-level package.json scripts I tested so far:

  • prepare
  • lint
  • format
  • bundlesize,
  • build
  • build:performance
  • build:performance:components
  • build:performance:benchmarks
  • copy-fork
  • dev
  • test
  • test:bespoke,
  • test:debug
  • test:ci
  • test:karma
  • test:karma:start
  • test:integration
  • test:performance
  • test:performance:best
  • test:performance:best:ci
  • test:types
  • release:version
  • release:publish

Does this pull request introduce a breaking change?

  • 😮‍💨 No, it does not introduce a breaking change.

Does this pull request introduce an observable change?

  • 🤞 No, it does not introduce an observable change.

GUS work item

@cardoso cardoso requested a review from a team as a code owner November 20, 2024 20:59
Comment on lines 24 to +25
```
yarn local
pnpm local
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently running into this issue: webdriverio/webdriverio#13787

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently worked around it by adding tsx as devDependency in `@lwc/integration-tests".

Copy link
Collaborator

@nolanlawson nolanlawson left a comment

Choose a reason for hiding this comment

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

This is looking good so far. I'm surprised so many changed are needed for pnpm, but I do like the workspace:* thing.

One thing missing: this code to build the benchmarks will need to run yarn or pnpm:

'yarn --immutable',
// bust the Tachometer cache in case these files change locally
`echo '${directoryHash}'`,
'yarn build:performance:components',

The reason is that it is going to compare the current master against an arbitrary commit from the past. Since that arbitrary commit might be using yarn, I'd suggest checking if [ -f yarn.lock ] inline.

@cardoso
Copy link
Contributor Author

cardoso commented Nov 21, 2024

@nolanlawson thank you for looking into this! I'll see what I can do about the benchmark scripts. I left them for last since it takes a while to fully run.

The changes in src are mostly due to the non-flat structure of node_modules, which actually helps figure out some "phantom" and cyclic dependencies since they break pnpm i or type-checking. I'm trying to move the changes to separate PRs though.

Copy link
Collaborator

@nolanlawson nolanlawson left a comment

Choose a reason for hiding this comment

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

Thank you for looking into this! I plan to give this a deeper look, but this week is crunch week so we're a bit time-strapped. 🙇

For the perf benchmark tests, don't worry about running all of them. If you'd like you can also set BENCHMARK_SAMPLE_SIZE=1 BENCHMARK_TIMEOUT=0 and it should run pretty fast.

@cardoso
Copy link
Contributor Author

cardoso commented Nov 22, 2024

It seems changes are needed at least in these two scripts as well:

// The root must be whatever dir contains your `node_modules`, so that Tachometer can resolve bare npm imports
// See: https://github.com/google/tachometer/issues/244#issuecomment-2267191898
root: path.relative(path.dirname(htmlFilename), packageRootDir),

# Create symlinks in the local node_modules directory to point to the root ones.
# This is a bit bizarre, but it's very tricky to get Tachometer to allow bare npm-style imports in
# a monorepo project. We could potentially get rid of this script by doing relative imports instead.
# See: https://github.com/google/tachometer/issues/215#issuecomment-2267194394
set -e
mkdir -p ./node_modules/@lwc
for pkg in @lwc/engine-dom @lwc/engine-server @lwc/perf-benchmarks-components @lwc/ssr-runtime @lwc/synthetic-shadow; do
if [ ! -L "./node_modules/$pkg" ]; then
ln -s "../../../../../packages/$pkg" "./node_modules/$pkg"
fi
done

Currently observing these errors in the console:

Uncaught (in promise) TypeError: class CardComponent extends LightningElement {
  constructor(...args) {
    super(...args);
    this.title = void 0;
    // Note: This is only to give volume to the rehydration process.
    this.rows = void 0;
  }
  /*LWC compiler v8.10.1*/
} is not a valid component, or does not extends LightningElement from "lwc". You probably forgot to add the extend clause on the class declaration.
    at getComponentInternalDef (index.js:3972:13)
    at createVM (index.js:6905:14)
    at renderComponent (render-component.ts:72:5)
    at table-hydrate-1k.benchmark.js:103:21
    at table-hydrate-1k.benchmark.js:51:45
    at Array.map (<anonymous>)
    at runBenchmark (table-hydrate-1k.benchmark.js:51:29)

@nolanlawson
Copy link
Collaborator

I think this means that Rollup is bundling incorrectly and we're ending up with two copies of lwc. I'll take a look.

@nolanlawson
Copy link
Collaborator

/nucleus test

@nolanlawson
Copy link
Collaborator

/nucleus test

.package.json.swp Outdated Show resolved Hide resolved
async function findLicenseText(depName) {
// Iterate through possible names for the license file
const names = ['LICENSE', 'LICENSE.md', 'LICENSE.txt'];

// We would use require.resolve, but 1) that doesn't work if the module lacks a "main" in its `package.json`,
// and 2) it gives us a deep `./path/to/index.js` which makes it harder to find a top-level LICENSE file. So
// just assume that our deps are hoisted to the top-level `node_modules`.
const resolvedDepPath = path.join(process.cwd(), 'node_modules', depName);
const resolvedDepPath = list.find((dep) => dep.name === depName).paths[0];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why does generate-license-files.js need to be updated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The dependencies are not hoisted to the top-level anymore. Transitive dependencies like entities from '@parse5/tools` are also not hoisted to the package which depends on it. This is the only reasonable way to accomplish this.

Refs:

@nolanlawson
Copy link
Collaborator

/nucleus test

@nolanlawson
Copy link
Collaborator

OK yeah it looks like our fix-deps.sh script which is a hack to work around google/tachometer#215 really does not play nice with pnpm's node_modules system. When I run a tachometer test with --manual (e.g. ../../../node_modules/.bin/tach --config ./dist/__benchmarks__/engine-dom/benchmark-expression/expression.tachometer.json --manual from the perf-benchmarks directory), I can see that we are loading two copies of engine-dom:

  • http://127.0.0.1:8080/node_modules/@lwc/engine-dom/dist/index.js
  • http://127.0.0.1:8080/node_modules/@lwc/perf-benchmarks-components/node_modules/@lwc/engine-dom/dist/index.js

This has always been a nasty hacky, and now it's coming back to bite us. I may need to get clever here.

@nolanlawson
Copy link
Collaborator

I mean, at this point I would be happy to switch to npm or modern yarn instead. I'm not married to pnpm especially if it's going to give us headaches like this. I just wanted us to get off of yarn v1 😅

@cardoso
Copy link
Contributor Author

cardoso commented Nov 23, 2024

@nolanlawson we could always use shamefully-hoist and avoid most changes here. The reason I didn't use it from the get-go was to try and get the full benefits of pnpm (especially avoiding the phantom dependencies).

Thanks for helping with the PR. I'll see if I can fix the issue with the benchmarks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migrate from yarn to pnpm
2 participants