The Wayback Machine - https://web.archive.org/web/20210715004325/https://github.com/nuxt/nuxt.js/pull/8389
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

feat: support plug-and-play, typescript runtime and native modules #8389

Merged
merged 51 commits into from Dec 22, 2020

Conversation

@pi0
Copy link
Member

@pi0 pi0 commented Nov 22, 2020

Summary

  • Using nuxt-contrib/jiti to for imports for better ESM support
  • Support typescript runtime out of the box with jiti
  • Use explicit dependencies for plug-and-play compatibility (with exception of @nuxt/cli and @nuxt/config)
  • Resolving dependencies with proper path for plug-and-play compatibility
  • Allow overriding dependencies from project with higher priority (like postcss@8)

Supporting plug-and-play and yarn v2 (berry)

Berry requires every package have explicitly defining their dependencies and also passing require-path for resolving on behalf of another module. After awesome works by @paul-soporan and @arcanis to support berry (#7295) ( ❤️ ) we finally had to close PR since it was risking breaking changes for nuxt2 users (specially for loaders matching) and was requiring to change way of nuxt2 mono-repo packages are connected with distro dependencies and relying on node_modules implicit structure. (nuxt3 rewrite is already considered this)

Since @evanrlong started another initiative with nuxt-berry ( ❤️ ) I got an idea to support a new nuxt distro nuxt-pnp fixing mono-repo issues. Technically a nuxt distro is build from source. With only difference that this special distro, squashes all packages in core (400Kbs in total) and automatically syncs dependencies. This means final install size is exactly the same but with single package (similar to nuxt3) which is fully compatible with berry without any compat mode or patches (Update: solution is simplified with __NUXT_PATHS__ for dynamic imports in Config and CLI)

Changing default require from esm to jiti

We started to support ESM syntax long time ago using standard-things/esm. This helped a lot adopting syntax for runtime places like nuxt.config and serverMiddleware. But over the time this package started to introduce countless issues and lack of maintenance.

We had to disable it for typescript-runtime and since regression with jest, we had to also auto detect jest environment and auto-disable it. At that point, I felt we really need a stable solution supporting syntax and replace esm so started developing in-house solution nuxt-contrib/jiti which is a 1MB build of babel to support both esm modules and typescript on the fly with caching and proper traces.

Even though currently it is possible to switch require engine using createRequire: 'jiti' from nuxt config, I think it is finally time to switch off using esm package. One plus point with this is also that we can support typescript runtime out of the box for config and middleware!

What about native esm? Jiti bypasse .mjs requires when native support is available. Yet as it is not possible to do hot reload for modules (cache is intentionally not exposed to user level)., changing config or middleware, would require a full server reload when using native modules...

Noticeable changes:

  • Using explicit dependencies (with exception of @nuxt/cli which is used for nuxt-start and ad-hoc modules
  • Removing unused dependencies
  • lodash dependency is not bundled anymore to simplify flow
    @nuxt/components/ @nuxt/telemetry which are discovered by @nuxt/config which is also used for nuxt-start)
  • __NUXT_PATHS__: Importing resolve mechanism to extend paths used for CLI
  • Resolve loader paths (potential breaking)
  • Build scripts (for nuxt packaging) will fail if there are unused for implicit dependencies
  • Removed @rollup/plugin-node-resolve to avoid silent inlining of dependencies (we was doing this in past without even notice)

TO...DO

  • More tests for native esm support (@danielroe @rchl need your help)
  • More tests for typescript (both runtime and build module) (/@kevinmarrec need your help)
  • Update docs for createRequire option and new features (@Atinux @debs-obrien need you help)
  • Double check to ensure there are no breaking changes (@clarkdo need your help) (using nuxt-edge)
@pi0 pi0 mentioned this pull request Nov 22, 2020
3 of 7 tasks
@pi0 pi0 changed the title feat: support yarn berry (nuxt-pnp) and use jiti by default feat: support berry via nuxt-pnp and use jiti by default Nov 22, 2020
@merceyz
Copy link

@merceyz merceyz commented Nov 22, 2020

Could the documentation suggest to use this as an alias instead?

{
  "dependencies": {
    "nuxt": "npm:nuxt-pnp@latest"
  }
}

That way imports and peer dependencies would still work

@clarkdo
Copy link
Member

@clarkdo clarkdo commented Nov 22, 2020

I assigned to me as well for reminding me this issue to be working on.

@evanrlong
Copy link

@evanrlong evanrlong commented Nov 22, 2020

This is amazing, thanks for adding this!

One addition I would suggest would be to support Zero-Installs. I opened a PR for nuxt-pnp-demo with an example of how it can be done.

pi0/nuxt-pnp-demo#2

Its mostly straightforward... just version control .yarn/cache. However, there are some native modules required by nuxt-pnp that complicate things. See my PR for a more detailed description.

Short version... adding the following snippet to a project's (root) package.json will make Zero-Installs work once .yarn/cache is version controlled.

  "dependenciesMeta": {
    "core-js": {
      "built": false,
      "unplugged": false
    },
    "ejs": {
      "built": false,
      "unplugged": false
    },
    "fsevents": {
      "built": false,
      "unplugged": false
    },
    "nan": {
      "built": false,
      "unplugged": false
    },
    "node-gyp": {
      "built": false,
      "unplugged": false
    },
    "nuxt-pnp": {
      "built": false,
      "unplugged": false
    },
    "term-size": {
      "built": false,
      "unplugged": false
    }
  }

I don't know if resolving the install of those native dependencies inside nuxt-pnp itself would be an option or if that could cause conflicts with other packages installed in a project. If that can't be done, I'd suggest that instructions could be added to the nuxt-pnp readme, telling people how to use Zero-Installs inside their project, along with any possible side-effects.

@codecov-io
Copy link

@codecov-io codecov-io commented Dec 19, 2020

Codecov Report

Merging #8389 (ab918c5) into dev (03384d3) will decrease coverage by 0.03%.
The diff coverage is 90.12%.

Impacted file tree graph

@@            Coverage Diff             @@
##              dev    #8389      +/-   ##
==========================================
- Coverage   67.62%   67.59%   -0.04%     
==========================================
  Files          91       91              
  Lines        3917     3913       -4     
  Branches     1070     1075       +5     
==========================================
- Hits         2649     2645       -4     
+ Misses       1024     1022       -2     
- Partials      244      246       +2     
Flag Coverage Δ
unittests 67.59% <90.12%> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
packages/babel-preset-app/src/index.js 0.00% <ø> (ø)
packages/cli/src/commands/webpack.js 93.33% <ø> (ø)
packages/config/src/config/_common.js 100.00% <ø> (ø)
packages/core/src/nuxt.js 93.18% <ø> (ø)
packages/generator/src/generator.js 80.46% <0.00%> (ø)
packages/server/src/server.js 79.14% <ø> (-0.26%) ⬇️
packages/utils/src/modern.js 100.00% <ø> (ø)
packages/utils/src/route.js 86.25% <ø> (ø)
packages/vue-renderer/src/renderer.js 0.00% <ø> (ø)
packages/vue-renderer/src/renderers/spa.js 0.00% <ø> (ø)
... and 19 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 03384d3...ab918c5. Read the comment docs.

@clarkdo clarkdo marked this pull request as ready for review Dec 22, 2020
@pi0 pi0 merged commit dec8f99 into dev Dec 22, 2020
19 checks passed
19 checks passed
@github-actions
setup (ubuntu-latest, 10)
Details
@github-actions
setup (windows-latest, 12)
Details
@github-actions
setup (ubuntu-latest, 12)
Details
@github-actions
lint (ubuntu-latest, 12)
Details
@github-actions
test-unit (windows-latest, 12)
Details
@github-actions
audit (ubuntu-latest, 12)
Details
@github-actions
build (windows-latest, 12)
Details
@github-actions
test-unit (ubuntu-latest, 10)
Details
@github-actions
test-dev (windows-latest, 12)
Details
@github-actions
test-unit (ubuntu-latest, 12)
Details
@github-actions
build (ubuntu-latest, 10)
Details
@github-actions
build (ubuntu-latest, 12)
Details
@github-actions
lint-app (ubuntu-latest, 12)
Details
@github-actions
test-dev (ubuntu-latest, 10)
Details
@github-actions
test-dev (ubuntu-latest, 12)
Details
@github-actions
test-e2e (ubuntu-latest, 10)
Details
@github-actions
test-e2e (ubuntu-latest, 12)
Details
@github-actions
release-commit
Details
@semantic-pull-requests
Semantic Pull Request ready to be squashed
Details
@pi0 pi0 deleted the feat/better-require branch Dec 22, 2020
@pi0 pi0 mentioned this pull request Jan 4, 2021
@mainrs
Copy link

@mainrs mainrs commented Feb 13, 2021

@evanrlong I tried to setup my project the same as your demo PR with zero-installs but I get errors for nuxt-pnp:

Error: Qualified path resolution failed - none of those files can be found on the disk.

Source path: .yarn/cache/nuxt-pnp-npm-2.14.12-3-3820474557-1d93ba144a.zip/node_modules/nuxt-pnp/dist/nuxt
Not found: .yarn/cache/nuxt-pnp-npm-2.14.12-3-3820474557-1d93ba144a.zip/node_modules/nuxt-pnp/dist/nuxt
Not found: .yarn/cache/nuxt-pnp-npm-2.14.12-3-3820474557-1d93ba144a.zip/node_modules/nuxt-pnp/dist/nuxt.js
Not found: .yarn/cache/nuxt-pnp-npm-2.14.12-3-3820474557-1d93ba144a.zip/node_modules/nuxt-pnp/dist/nuxt.json
Not found: .yarn/cache/nuxt-pnp-npm-2.14.12-3-3820474557-1d93ba144a.zip/node_modules/nuxt-pnp/dist/nuxt.node

Did you come across this error? If so, how did you solve it?

Edit I got it to work with nuxt-edge, as that seems to contain the PR mentioned here. Still, I'd expect the nuxt-pnp package to also work as it did for you :)

@pi0
Copy link
Member Author

@pi0 pi0 commented Feb 13, 2021

Hi @SirWindfield. Thanks for giving it a try. If it works with nuxt-edge that's perfect. nuxt-pnp was a prototype idea to make it working without breaking nuxt 2 but finally it is working out of the box with main distro :) (i will tear down both nuxt-pnp and my old repo)

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

Successfully merging this pull request may close these issues.

None yet

6 participants