nuxt / nuxt

The Intuitive Vue Framework.
https://nuxt.com
MIT License
54.75k stars 5.01k forks source link

Occur error when module path is a package subpath that does not match the actual path #29735

Open shunnNet opened 1 day ago

shunnNet commented 1 day ago

Environment

Reproduction

https://codesandbox.io/p/devbox/bold-moon-4f3lll?workspaceId=02247d38-3c4c-4910-9e35-fabf9385962a

module's code

Describe the bug

A Nuxt module can be installed via a package subpath, which allows it to differ from the actual directory structure, such as:

{
  "exports": {
      "./mod": {
          "types": "./packages/mod/dist/types.d.ts",
          "import": "./packages/mod/dist/module.mjs",
          "require": "./packages/mod/dist/module.cjs"
      }
  }
}

When installed through this subpath, although the module was successfully installed, the Nuxt module's runtime code (e.g: Nuxt plugin) encounters errors when import from aliases e.g: #app.

export default defineNuxtConfig({
  // omit
  modules: [
    "subpath-demo/mod"
  ],
})
import { defineNuxtPlugin } from "#app";  // <--- will fail
export default defineNuxtPlugin((_nuxtApp) => {
  console.log("Plugin injected by my-module!");
});

This may be related to how Vite ssr.noExternal is configured.

Currently, Nuxt directly sets it to the user-provided string (subpath-demo/mod), but imports plugins using the full absolute path. ( ..... /node_modules/subpath-demo/packages/mod/dist/module.mjs), which is not match. And dependencies will be externalized by Vite if it wasn't included in ssr.noExternal. vite ssr-external

Therefore, when the subpath differs from the actual path, Vite excludes it from compilation.

Workaround

  1. Align subpath with actual path

  2. Manually add package name to ssr.noExternal

export default defineNuxtConfig({
  // omit
  modules: [
    "subpath-demo/mod"
  ],
  vite: {
      ssr: { 
        noExternal: [ "subpath-demo" ] 
      }
  }
})

Additional context

No response

Logs

ERROR  [nuxt] [request error] [unhandled] [500] Package import specifier "#app" is not defined in package /Users/net/repository/test-mod-dep/node_modules/.pnpm/subpath-demo@https+++codeload.github.com+shunnNet+demo-nuxt-module-subpath-issue+tar.gz+f5f70_gfo3iqyqpkpaqjbz4jtbsmbv6e/node_modules/subpath-demo/package.json imported from /Users/net/repository/test-mod-dep/node_modules/.pnpm/subpath-demo@https+++codeload.github.com+shunnNet+demo-nuxt-module-subpath-issue+tar.gz+f5f70_gfo3iqyqpkpaqjbz4jtbsmbv6e/node_modules/subpath-demo/packages/mod/dist/runtime/plugin.js
  at importNotDefined (node:internal/modules/esm/resolve:291:10)  
  at packageImportsResolve (node:internal/modules/esm/resolve:741:9)  
  at moduleResolve (node:internal/modules/esm/resolve:917:16)  
  at defaultResolve (node:internal/modules/esm/resolve:1157:11)  
  at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:390:12)  
  at ModuleLoader.resolve (node:internal/modules/esm/loader:359:25)  
  at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:234:38)  
  at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:87:39)  
  at link (node:internal/modules/esm/module_job:86:36)
github-actions[bot] commented 1 day ago

Stackblitz link for the reproduction: Stackblitz

github-actions[bot] commented 1 day ago

Would you be able to provide a reproduction? 🙏

More info ### Why do I need to provide a reproduction? Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making. ### What will happen? If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritize it based on its severity and how many people we think it might affect. If `needs reproduction` labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it. ### How can I create a reproduction? We have a couple of templates for starting with a minimal reproduction: 👉 https://stackblitz.com/github/nuxt/starter/tree/v3-stackblitz 👉 https://codesandbox.io/s/github/nuxt/starter/v3-codesandbox A public GitHub repository is also perfect. 👌 Please ensure that the reproduction is as **minimal** as possible. See more details [in our guide](https://nuxt.com/docs/community/reporting-bugs/#create-a-minimal-reproduction). You might also find these other articles interesting and/or helpful: - [The Importance of Reproductions](https://antfu.me/posts/why-reproductions-are-required) - [How to Generate a Minimal, Complete, and Verifiable Example](https://stackoverflow.com/help/minimal-reproducible-example)
shunnNet commented 1 day ago

Reproduction: https://codesandbox.io/p/devbox/bold-moon-4f3lll?workspaceId=02247d38-3c4c-4910-9e35-fabf9385962a

module's code