ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.02k stars 13.51k forks source link

feat: yarn with PnP support #23095

Closed ericis closed 1 year ago

ericis commented 3 years ago

Bug Report

Ionic version:

*Note: I tried both node versions 14.16.0 and 15.8.0.

Current behavior:

Creating a new, blank Ionic React app and using the latest yarn to initialize and run the project results in catastrophic failure related to inability to find dependencies.

For more information, see Yarn 2 "Zero Installs" documentation: https://yarnpkg.com/features/zero-installs

*Note: I did verify that the commands npm i, npm test, and npm start do work correctly with the same versions without any issue.

Expected behavior:

Tests run and project starts successfully. Ideally, zero warnings (but, I recognize you don't own the entire package dependency tree).

Steps to reproduce:

  1. Create a new Ionic React app: npx ionic start helloworld blank --type=react --no-git --no-deps
  2. cd helloworld
  3. yarn set version berry
  4. yarn install
  5. yarn test (q to stop test "watch")
  6. yarn start

Related code:

n/a

Other information:

Logs...

➜  helloworld.app git:(main) ✗ npx ionic start helloworld blank --type=react --no-git --no-deps
[INFO] Existing git project found (/mnt/c/Users/iseri/src/github/ourchitecture/helloworld.app). Git operations are
       disabled.
✔ Preparing directory ./helloworld - done!
✔ Downloading and extracting blank starter - done!

[INFO] Next Steps:

       - Go to your newly created project: cd ./helloworld
       - Run ionic serve within the app directory to see your app
       - Build features and components: https://ion.link/scaffolding-docs
       - Run your app on a hardware or virtual device: https://ion.link/running-docs

  ────────────────────────────────────────────────────────────

          Ionic CLI update available: 5.4.16 → 6.13.1

     The package name has changed from ionic to @ionic/cli!

             To update, run: npm uninstall -g ionic
                 Then run: npm i -g @ionic/cli

  ────────────────────────────────────────────────────────────

➜  helloworld.app git:(main) ✗ mv -v helloworld/* ./
renamed 'helloworld/ionic.config.json' -> './ionic.config.json'
renamed 'helloworld/package.json' -> './package.json'
renamed 'helloworld/public' -> './public'
renamed 'helloworld/src' -> './src'
renamed 'helloworld/tsconfig.json' -> './tsconfig.json'
➜  helloworld.app git:(main) ✗ rm -rf helloworld 
➜  helloworld.app git:(main) ✗ yarn set version berry
Resolving berry to a url...
Downloading https://github.com/yarnpkg/berry/raw/master/packages/berry-cli/bin/berry.js...
Saving it into /mnt/c/Users/iseri/src/github/ourchitecture/helloworld.app/.yarn/releases/yarn-berry.cjs...
Updating /mnt/c/Users/iseri/src/github/ourchitecture/helloworld.app/.yarnrc.yml...
Done!
➜  helloworld.app git:(main) ✗ yarn install
➤ YN0000: ┌ Resolution step
➤ YN0061: │ babel-eslint@npm:10.1.0 is deprecated: babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.
➤ YN0032: │ fsevents@npm:2.3.2: Implicit dependencies on node-gyp are discouraged
➤ YN0032: │ fsevents@npm:2.3.2: Implicit dependencies on node-gyp are discouraged
➤ YN0061: │ chokidar@npm:2.1.8 is deprecated: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.
➤ YN0061: │ fsevents@npm:1.2.13 is deprecated: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
➤ YN0061: │ fsevents@npm:1.2.13 is deprecated: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
➤ YN0061: │ @hapi/joi@npm:15.1.1 is deprecated: Switch to 'npm install joi'
➤ YN0061: │ @hapi/address@npm:2.1.4 is deprecated: Moved to 'npm install @sideway/address'
➤ YN0061: │ @hapi/bourne@npm:1.3.2 is deprecated: This version has been deprecated and is no longer supported or maintained
➤ YN0061: │ @hapi/topo@npm:3.1.6 is deprecated: This version has been deprecated and is no longer supported or maintained
➤ YN0061: │ @hapi/hoek@npm:8.5.1 is deprecated: This version has been deprecated and is no longer supported or maintained
➤ YN0061: │ request@npm:2.88.2 is deprecated: request has been deprecated, see https://github.com/request/request/issues/3142
➤ YN0032: │ evp_bytestokey@npm:1.0.3: Implicit dependencies on node-gyp are discouraged
➤ YN0061: │ har-validator@npm:5.1.5 is deprecated: this library is no longer supported
➤ YN0061: │ urix@npm:0.1.0 is deprecated: Please see https://github.com/lydell/urix#deprecated
➤ YN0061: │ resolve-url@npm:0.2.1 is deprecated: https://github.com/lydell/resolve-url#deprecated
➤ YN0061: │ request-promise-native@npm:1.0.9 is deprecated: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142
 FAIL  src/App.test.tsx
  ● Test suite failed to run

    @ionic/react-router tried to access history, but it isn't declared in its dependencies; this makes the require call ambiguous and unsound.

    Required package: history (via "history")
    Required by: @ionic/react-router@virtual:f122e2e0fc619083f1222d16db756a72e907cbf4082314c1e6b01e0171a948d0bef8b5fc91c1be8cfe7c332f514e52c96ac625fbd90689b1d0489b9cec8f1ce7#npm:5.6.3 (via /mnt/c/Users/iseri/src/github/ourchitecture/helloworld.app/.yarn/$$virtual/@ionic-react-router-virtual-0ec5b48533/0/cache/@ionic-react-router-npm-5.6.3-734f8999e5-a4232fa611.zip/node_modules/@ionic/react-router/dist/)

    Require stack:
      .yarn/$$virtual/@ionic-react-router-virtual-0ec5b48533/0/cache/@ionic-react-router-npm-5.6.3-734f8999e5-a4232fa611.zip/node_modules/@ionic/react-router/dist/index.js      
      src/App.tsx
      src/App.test.tsx

      25134 |     enumerable: false
      25135 |   };
    > 25136 |   return Object.defineProperties(new Error(message), {
            |                                  ^
      25137 |     code: { ...propertySpec,
      25138 |       value: code
      25139 |     },

      at internalTools_makeError (.pnp.js:25136:34)
      at resolveToUnqualified (.pnp.js:26101:23)
      at resolveRequest (.pnp.js:26193:29)
      at Object.resolveRequest (.pnp.js:26271:26)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        6.657 s
Ran all test suites related to changed files.

Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press q to quit watch mode.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press Enter to trigger a test run.

Ionic info:

➜  helloworld.app git:(main) ✗ npx ionic info
[ERROR] Error loading @ionic/react package.json: Error: Cannot find module '@ionic/react/package'

        Require stack:
        - /home/myuser/.npm/_npx/864a9e3c2cd0cf50/node_modules/ionic/lib/project/index.js
        - /home/myuser/.npm/_npx/864a9e3c2cd0cf50/node_modules/ionic/lib/index.js
        - /home/myuser/.npm/_npx/864a9e3c2cd0cf50/node_modules/ionic/index.js
        - /home/myuser/.npm/_npx/864a9e3c2cd0cf50/node_modules/ionic/bin/ionic

Ionic:

   Ionic CLI       : 5.4.16 (/home/myuser/.npm/_npx/864a9e3c2cd0cf50/node_modules/ionic)
   Ionic Framework : not installed

Utility:

   cordova-res : not installed
   native-run  : not installed

System:

   NodeJS : v15.8.0 (/home/myuser/.nvm/versions/node/v15.8.0/bin/node)
   npm    : 7.5.1
   OS     : Linux 5.4
mhartington commented 3 years ago

So sort answer, yarn2 changed how deps are resolved and can cause issue. To resolve for you situation, install the history pacakge with yarn add history

@liamdebeasi and @brandyscarney, we should probably decide if we to support Yarn 2. As far as I know, the yarn community is still pretty much on yarn 1, and yarn 2 is being treated as a completely different package manager.

liamdebeasi commented 3 years ago

Thanks for the issue. We do not have plans for full Yarn 2 support at the moment, but I will keep this issue open for now to gauge interest and collect feedback from the community.

merceyz commented 3 years ago

This issue should be renamed, it's about Yarn PnP support not Yarn 2. Yarn 2, just like Yarn 1, supports both PnP and node_modules

ericis commented 3 years ago

@merceyz my understanding is that PnP is the default for Yarn 2

Yarn 2 documentation refers to using the "node-modules" plug-in as:

Despite our best efforts some tools don't work at all under Plug'n'Play environments, and we don't have the resources to update them ourselves. There are only two notorious ones on our list: Flow, and React Native.

In such a radical case, you can enable the built-in node-modules plugin by adding the following into your local .yarnrc.yml file before running a fresh yarn install

This is pretty extreme language, seeming to suggest very strongly that projects should attempt to use PnP.

However, I can re-title the issue if it would bring clarity?

Perhaps "feat: yarn 2 with default PnP support" ?

ericis commented 3 years ago

@merceyz I noticed you are a Yarn Berry contributor, so I'll just trust your expertise and rename 😉 👍🏻

enk0de commented 3 years ago

when do you make it? i am looking forward to this...

Whizfactor commented 2 years ago

I am having to migrate to NPM back again and its affecting my development. Facing issues when i run ng config cli.packageManager yarn

result:

Schema validation failed with the following errors: Data path "/projects/app/architect/serve/builder" must NOT be valid. Data path "/projects/app/architect/serve/builder" must be equal to constant. Data path "/projects/app/architect/serve/builder" must be equal to constant. Data path "/projects/app/architect/serve/configurations/ci" must NOT have additional properties(progress). Data path "/projects/app/architect/serve/builder" must be equal to constant. Data path "/projects/app/architect/serve/builder" must be equal to constant. Data path "/projects/app/architect/serve/builder" must be equal to constant. Data path "/projects/app/architect/serve/builder" must be equal to constant. Data path "/projects/app/architect/serve/builder" must be equal to constant. Data path "/projects/app/architect/serve" must match exactly one schema in oneOf.

Did change "packageManager" : "yarn"

The Angular.json file

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "defaultProject": "app",
  "newProjectRoot": "projects",
  "projects": {
    "app": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "www",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "assets": [
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "assets"
              },
              {
                "glob": "**/*.svg",
                "input": "node_modules/ionicons/dist/ionicons/svg",
                "output": "./svg"
              }
            ],
            "styles": ["src/theme/variables.scss", "src/global.scss"],
            "scripts": [],
            "aot": false,
            "vendorChunk": true,
            "extractLicenses": false,
            "buildOptimizer": false,
            "sourceMap": true,
            "optimization": false,
            "namedChunks": true
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                }
              ]
            },
            "ci": {
              "progress": false
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "app:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "app:build:production"
            },
            "ci": {
              "progress": false
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "app:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "styles": [],
            "scripts": [],
            "assets": [
              {
                "glob": "favicon.ico",
                "input": "src/",
                "output": "/"
              },
              {
                "glob": "**/*",
                "input": "src/assets",
                "output": "/assets"
              }
            ]
          },
          "configurations": {
            "ci": {
              "progress": false,
              "watch": false
            }
          }
        },
        "lint": {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "lintFilePatterns": [
              "src/**/*.ts",
              "src/**/*.html"
            ]
          }
        },
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "app:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "app:serve:production"
            },
            "ci": {
              "devServerTarget": "app:serve:ci"
            }
          }
        }
      }
    }
  },
  "cli": {
    "analytics": false,
    "defaultCollection": "@ionic/angular-toolkit",
    "packageManager": "yarn"
  },
  "schematics": {
    "@ionic/angular-toolkit:component": {
      "styleext": "scss"
    },
    "@ionic/angular-toolkit:page": {
      "styleext": "scss"
    }
  }
}
wmadden commented 2 years ago

@liamdebeasi I think this issue could use some clarification.

The Ionic CLI is actually already compatible with Yarn PnP as far as I can tell - I'm using it myself. The OP's mistake is to install their dependencies with Yarn PnP, then invoke the Ionic CLI with npx, which fails to configure Node's module loader to use PnP, so all the dependencies appear to be missing.

It looks like the steps the OP took were approximately:

  1. Create a blank Ionic app using npx ionic start
  2. Install all the dependencies with Yarn PnP
  3. Invoke test runner with npx test or ionic test or something - a lot of the logs appear to be missing

All they have to do to correct their mistake is invoke their commands with yarn instead of npx, e.g. yarn exec ionic serve works fine with PnP.

Having said all that, Appflow's build system is 100% coupled to Node - it looks like it's hardcoded to invoke npm - despite documentation suggesting using Appflow with Yarn workspaces. I stumbled on this issue while I was debugging that. Should I raise a separate issue to discuss it, and should it be on this repo or somewhere else?

Whizfactor commented 2 years ago

I had to switch to NPM after using yarn 2 and I was having issues.

[Öñ [[[Ŵéð one], [Ĵûñ one] 15, 2022], [22:53]] Wisdom Ubaka < @.***> ŵŕöţé: one two]

Did you use it with yarn 1 or yarn 2??

[Öñ [[[Ŵéð one], [Ĵûñ one] 15, 2022], [21:41]] Will Madden < @.***> ŵŕöţé: one two]

@liamdebeasi https://github.com/liamdebeasi I think this issue could use some clarification.

The Ionic CLI is actually already compatible with Yarn PnP as far as I can tell - I'm using it myself. The OP's mistake is to install their dependencies with Yarn PnP, then invoke the Ionic CLI with npx, which fails to configure Node's module loader to use PnP, so all the dependencies appear to be missing.

It looks like the steps the OP took were approximately:

  1. Create a blank Ionic app using npx ionic start
  2. Install all the dependencies with Yarn PnP
  3. Invoke test runner with npx test or something - a lot of the logs appear to be missing

Having said all that, Appflow's build system is 100% coupled to Node - it looks like it's hardcoded to invoke npm - despite documentation suggesting using Appflow with Yarn workspaces https://ionic.io/docs/appflow/cookbook/appflow-config. I stumbled on this issue while I was debugging that. Should I raise a separate issue to discuss it, and should it be on this repo or somewhere else?

— Reply to this email directly, view it on GitHub https://github.com/ionic-team/ionic-framework/issues/23095#issuecomment-1156910004, or unsubscribe https://github.com/notifications/unsubscribe-auth/APRXSUTZ4WDCHYMVOI43JA3VPI5ZDANCNFSM4ZVRWGPA . You are receiving this because you commented.Message ID: @.***>

ericis commented 2 years ago

@wmadden I'd be happy to add any additional context that could help. So, I reran the exact same commands listed in the issue to retest as well as experimented with your suggestions "to correct [my] mistake [by invoking my] commands with yarn instead of npx".

First, an attempt to recreate with the latest tools

Since the tools have upgrades and changes, we'll retest the steps.

💥 Interestingly, things fail the same way.

Let's try the suggestion

All they have to do to correct their mistake is invoke their commands with yarn instead of npx

We'll assume the original post was simply a mistake of running an npx command. And, since there is only one command that uses npx at the very beginning, let's try step three again:

💥 This fails, because yarn exec doesn't quite work the same as npm exec or the npx alias.

So, let's just assume that a single version of the Ionic CLI must be installed globally and clutter our machine a little in order for modern yarn tooling to work properly in order to run the ionic start command one single time...

💥 Despite a successful installation, the ionic command appears to have never been installed or was not registered properly.

$ ionic --version
bash: ionic: command not found

So, let's follow the official instructions for installing the ionic CLI...

💥 This fails again, because yarn exec doesn't work the same way that npm exec or its alias npx does.

LONG way to say... still having pretty much the same, original issue.

wmadden commented 2 years ago

Sorry to hear that @ericis :/

Maybe someone from the Ionic team can help

Whizfactor commented 2 years ago

Did you use it with yarn 1 or yarn 2??

[Öñ [[[Ŵéð one], [Ĵûñ one] 15, 2022], [21:41]] Will Madden < @.***> ŵŕöţé: one two]

@liamdebeasi https://github.com/liamdebeasi I think this issue could use some clarification.

The Ionic CLI is actually already compatible with Yarn PnP as far as I can tell - I'm using it myself. The OP's mistake is to install their dependencies with Yarn PnP, then invoke the Ionic CLI with npx, which fails to configure Node's module loader to use PnP, so all the dependencies appear to be missing.

It looks like the steps the OP took were approximately:

  1. Create a blank Ionic app using npx ionic start
  2. Install all the dependencies with Yarn PnP
  3. Invoke test runner with npx test or something - a lot of the logs appear to be missing

Having said all that, Appflow's build system is 100% coupled to Node - it looks like it's hardcoded to invoke npm - despite documentation suggesting using Appflow with Yarn workspaces https://ionic.io/docs/appflow/cookbook/appflow-config. I stumbled on this issue while I was debugging that. Should I raise a separate issue to discuss it, and should it be on this repo or somewhere else?

— Reply to this email directly, view it on GitHub https://github.com/ionic-team/ionic-framework/issues/23095#issuecomment-1156910004, or unsubscribe https://github.com/notifications/unsubscribe-auth/APRXSUTZ4WDCHYMVOI43JA3VPI5ZDANCNFSM4ZVRWGPA . You are receiving this because you commented.Message ID: @.***>

liamdebeasi commented 1 year ago

Hi everyone,

I have an update to share. The original issue references an issue with the history dependency in Ionic React.

I recently merged a fix to the Ionic React starters (https://github.com/ionic-team/starters/pull/1691) that makes the history package a direct dependency of the project, which should resolve the reported Yarn issue. Developers with existing apps should manually add the history dependency with yarn add history.

There is also a related issue with Ionicons. Ionicons v6 now ships as a direct dependency of the Ionic React starter applications. Developers with existing apps should manually add the ionicons dependency with yarn add ionicons.


I am going to close this since the original reported issue has been resolved. For any other issues, please create a new issue. Thank you!

ionitron-bot[bot] commented 1 year ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.