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

Yarn 2.0 (Yarn Plug’n’Play) #2112

Closed
jakeNiemiec opened this issue May 31, 2019 · 20 comments
Closed

Yarn 2.0 (Yarn Plug’n’Play) #2112

jakeNiemiec opened this issue May 31, 2019 · 20 comments

Comments

@jakeNiemiec
Copy link
Member

jakeNiemiec commented May 31, 2019

Summary from whitepaper:
Pros:

  • smaller install
  • faster install
  • better matches how gems behave
  • better install & cache for CIs
  • better peer dependencies
  • users working on multiple projects across a system won’t pay in-creasing install costs
  • no node_modules folder

Cons:

  • no node_modules folder (some webpacker stuff currently relies on this). You also can't edit anything in node_modules
  • packages must be accessed via yarn cache
  • packages cannot rely on cross package boundaries (e.g.: webpacker users can't rely on the sub-dependencies of @rails/webpacker as if they were direct dependencies)

Resources:

Newer links:

@omnilord
Copy link

Will pnp put all the modules in a singular global source of truth location on the local system, or will this still require downloading at least one new copy of them from the internet at every install, even if another project already uses the same version?

@jakeNiemiec
Copy link
Member Author

From the whitepaper (very short read):

In its current state, running yarn install does the following under the hood -assuming a cold setup:

  1. Dependency ranges are resolved into pinned versions
  2. Packages for each version are fetched from their sources and stored in the offline mirror
  3. The offline mirror is unpacked into the cache
  4. The cache is copied into thenode_modulesfolders

Our solution aims to trim the fourth step from the equation. Instead of copying each and every file from the cache to the node_modules folder (which can take a lot of time, amplified by the sheer number of files), we will instead generate a single file that will contain static resolutions tables that list:

  • What packages are available in the dependency tree
  • How they are linked together
  • Where they are located on the disk

So, instead of 100M of modules in a node_modules folder, that 100M is cached and you get a file that acts as a map to the modules that you need. No more filesystem traversal.

@paracycle
Copy link

PnP was exactly what I thought about when I read the thread at rails/rails#36282, great to see there is a will to tackle this.

I would be interested in taking a look at implementing this but I am super new to webpacker. Let me see how fast I can get familiar with it to make a contribution.

@jakeNiemiec
Copy link
Member Author

jakeNiemiec commented Jun 4, 2019

I have tried it out and can confirm that webpacker needs to implement something like peerDependencies in order to make this work. Error with the default setup: You cannot require a package ("@babel/preset-env") that is not declared in your dependencies:

Add this to package.json to enable.

"installConfig": {
    "pnp": true
  }

The errors

Uncaught Error: Module build failed (from /Users/user/Library/Caches/Yarn/v4/npm-babel-loader-8.0.6-e33bdb6f362b03f4bb141a0c21ab87c501b70dfb/node_modules/babel-loader/lib/index.js):
Error: You cannot require a package ("@babel/preset-env") that is not declared in your dependencies (via "/Users/user/webpacker_tests/hello/babel.config.js")
    at makeError (Users/user/webpacker_tests/hello/.pnp.js:55)
    at Object.resolveToUnqualified (Users/user/webpacker_tests/hello/.pnp.js:11126)
    at Object.resolveRequest (Users/user/webpacker_tests/hello/.pnp.js:11204)
    at Function.Module._resolveFilename (Users/user/webpacker_tests/hello/.pnp.js:11386)
    at Function.Module._load (Users/user/webpacker_tests/hello/.pnp.js:11302)
    at Module.require (internal/modules/cjs/loader.js:637)
    ...

image

If you meticulously install all of the deps you need with PnP, the starter files will actually compile successfully:

image

@gauravtiwari, This is only possible since you already did some work last year to enable PnP 🎉: https://github.com/rails/webpacker/pull/1823/files#diff-1701de23f718ce36149c9b23e2db08caR95

First glance action items:

@gauravtiwari
Copy link
Member

Thanks @jakeNiemiec Sorry about the delay. I will take a look tomorrow and get back to you.

@somebody32
Copy link
Contributor

just my 2 cents on Should PnP be the default?: https://twitter.com/sebmck/status/1137059802838757377?s=20. Obviously, Facebook's scale is a different story, but anyway

@jakeNiemiec
Copy link
Member Author

Yarn 2.0 summary post

With yarn@2 released, I assume that other users will attempt to upgrade and use with webpacker. This will not work since yarn now enforces package boundaries.

@jakeNiemiec jakeNiemiec changed the title Get rid of node_modules with Yarn Plug’n’Play Yarn 2.0 (Yarn Plug’n’Play) Feb 3, 2020
@swrobel
Copy link
Contributor

swrobel commented Feb 7, 2020

FWIW I attempted to use Yarn 2 about 4 months ago to see what would happen w/ Webpacker, and this is the discussion it led to on the Yarn 2 (aka berry) repo: yarnpkg/berry#494

@jakeNiemiec
Copy link
Member Author

I wanted to add this resource for anyone looking to try this out: https://next.yarnpkg.com/getting-started

It now occurs to me that migrating to Yarn 2.0 will require 2 major efforts:

  • Migrating the Webpacker repo to Yarn 2
  • Migrating user's Webpacker setups to Yarn 2

Both of these involve cutting reliance on node_modules. See more in the migration guide: https://next.yarnpkg.com/advanced/migration

@doits
Copy link
Contributor

doits commented Dec 1, 2020

Shouldn't it work with nodeLinker: node-modules in .yarnrc.yml (https://yarnpkg.com/configuration/yarnrc#nodeLinker)? It doesn't use pnp then and the good old node_modules folder is still present.

@arcanis
Copy link

arcanis commented Dec 1, 2020

Yes, that would be the ideal migration for Webpacker / Rails. That's what we typically recommend in our migration guide:

Don't worry if your project isn't quite ready for Plug'n'Play just yet! This guide will let you migrate without losing your node_modules folder, and only in a later optional section we will cover how to enable PnP support (which is recommended, but not mandatory). Baby steps! 😉

@doits
Copy link
Contributor

doits commented Dec 1, 2020

I just tested it and it seems to work with two additional steps. I did this to upgrade and it is working in my development setup:

$ yarn set version berry
$ echo "nodeLinker: node-modules" >> .yarnrc.yml
$ yarn
$ yarn add webpack@^4.0 webpack-cli@^4.0 # otherwise it will complain about not finding the binary `webpack`

Compiling in development mode!

Tested with current master version of webpacker.

@doits
Copy link
Contributor

doits commented Dec 2, 2020

I created #2799 with the changes needed to experimentally support Yarn 2, e.g. not to break when Yarn 2 is used.

@n-rodriguez
Copy link
Contributor

I created #2799 with the changes needed to experimentally support Yarn 2, e.g. not to break when Yarn 2 is used.

Thank you! It works here :)

yonta added a commit to momocus/sakazuki that referenced this issue Jul 28, 2021
Yarn v2移行のデフォルトはPlug'n'Playがオンになっている。
PnPはパッケージ内容をレポジトリに含めてキャッシュし、node_modulesディレクトリを使わない。
そのため高速かつ再現性よく動作するようになっている。

しかし、rails/webpackerがまだYarnのPnPに対応していないようである。
  ttps://github.com/rails/webpacker/issues/2112
そのため、PnPをまだ使わず、node_modulesディレクトリを使い続ける設定にした。
@jrochkind
Copy link

Is there any word of plans/intentions from webpacker/rails maintainers?

@shamrt
Copy link

shamrt commented Oct 23, 2021

A heads up for projects using https://github.com/shakacode/react_on_rails and Yarn 2: React on Rails's Rake assets:precompile enhance command results in a Unknown Syntax Error:

Unknown Syntax Error: Unsupported option name ("--no-progress").

This is due to Yarn 2 no longer supporting some Yarn 1 install options, namely the --no-progress flag.

For the time being, react_on_rails projects using Yarn 2 can leverage https://github.com/tujoworker/plugin-ignore-install-options Yarn plugin to mitigate the issue.

@justin808
Copy link
Contributor

Hi @shamrt, can you tell us a bit more about your requirements for rails/webpacker with react_on_rails?

@guillaumebriday, maybe I can add a test case for react_on_rails using yarn v2? I could update https://github.com/shakacode/react_on_rails_tutorial_with_ssr_and_hmr_fast_refresh with yarn v2?

@guillaumebriday it seems odd that rails/webpacker has to worry about very specific flags for yarn. Seems out of scope for the project and a good example of how keeping things leaner is better.

@dhh dhh closed this as completed Jan 19, 2022
@justin808
Copy link
Contributor

Feel free to reopen this issue here:
https://github.com/shakacode/shakapacker/issues

@jrochkind
Copy link

jrochkind commented Jan 20, 2022

Thanks @justin808 , can you provide a link explaining the origin of shakapacker. It says "Official, actively maintained fork of rails/webpacker" -- but I don't understand what that means, official according to whom, is there something not "official" or "actively maintained" about this repo that I hadn't heard, is there some coordination/hand-off from rails to that team, is shakapacker officially supported by rails or something, is there news I missed somewhere?

@justin808
Copy link
Contributor

@dhh suggested the name for the fork 😄 and it's listed on the README.md for https://github.com/rails/webpacker.

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

No branches or pull requests