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

Permitted TypeScript moduleResolution field is silently ignored during build step #38854

Closed
1 task done
nopelluhh opened this issue Jul 20, 2022 · 6 comments · Fixed by #45670
Closed
1 task done

Permitted TypeScript moduleResolution field is silently ignored during build step #38854

nopelluhh opened this issue Jul 20, 2022 · 6 comments · Fixed by #45670
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. TypeScript Related to types with Next.js.

Comments

@nopelluhh
Copy link

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
Platform: linux
Arch: x64
Version: Ubuntu 20.04.0 LTS Wed Jul 20 2022 15:07:23 GMT-0700 (Pacific Daylight Time)
Binaries:
Node: 16.14.2
npm: 7.17.0
Yarn: 1.22.10
pnpm: N/A
Relevant packages:
next: 12.2.3-canary.14
eslint-config-next: N/A
react: 18.2.0
react-dom: 18.2.0

warn - Latest canary version not detected, detected: "12.2.3-canary.14", newest: "12.2.3-canary.15".
Please try the latest canary version (npm install next@canary) to confirm the issue still exists before creating a new issue.
Read more - https://nextjs.org/docs/messages/opening-an-issue

NOTE: I was unable to install 12.2.3-canary.15, it doesn't seem to exist on NPM at the time of creating this issue

What browser are you using? (if relevant)

N/A

How are you deploying your application? (if relevant)

N/A

Describe the Bug

Running next build ignores the moduleResolution field if it contains a value other than nodejs, even when using a permitted type as outlined here:

ts.ModuleResolutionKind.NodeJs,
ts.ModuleResolutionKind.Node12,
ts.ModuleResolutionKind.NodeNext,

This means that builds that pass direct type checking via tsc will fail to build if node12 or nodenext are used.

I did a bit of digging and it appears this is because while writeConfigurationDefaults allows parsedValues options above, getRequiredConfiguration only returns parsedValue and which overrides the user's config:

const requiredConfig = getRequiredConfiguration(ts)
const options = {
...effectiveConfiguration.options,
...requiredConfig,
declarationMap: false,
emitDeclarationOnly: false,
noEmit: true,
}

If this is not the expected behavior I'm happy to attempt a PR to fix, but wanted to confirm before giving it a shot.

Expected Behavior

Running yarn build should respect the moduleResolution field when it contains a permitted value other than nodejs.

Link to reproduction

https://stackblitz.com/edit/vercel-next-js-wtfonr

To Reproduce

Run yarn build (and also observe that yarn tsc does not error)

@nopelluhh nopelluhh added the bug Issue was opened via the bug report template. label Jul 20, 2022
@nopelluhh nopelluhh changed the title Permitted TypeScript moduleResolution field is silently ignores during build step Permitted TypeScript moduleResolution field is silently ignored during build step Jul 20, 2022
@balazsorban44 balazsorban44 added the TypeScript Related to types with Next.js. label Jul 21, 2022
@harrysolovay
Copy link

I'm also running into this issue.

I have my tsconfig's moduleResolution set to "NodeNext" so that I can use non-root exports.

For instance:

import * as M from "capi/frame_metadata";
// ...

The following error occurs upon running next build.

./components/layout/sidebar/ExtrinsicsList.tsx:1:20
Type error: Cannot find module 'capi/frame_metadata' or its corresponding type declarations.

> 1 | import * as M from "capi/frame_metadata";
    |                    ^
  2 | import classNames from "classnames";
  3 | import * as H from "hooks";
  4 | import Link from "next/link";

I'd also recommend that setting the tsconfig field auto-disable the import/no-unresolved lint, which does not account for such NodeNext import path specifiers.

@karl-kallavus
Copy link

Same. I'm also running into this problem.

package.json

"exports": {
    ".": {
      "import": "./esm/index.js",
      "require": "./script/index.js",
      "types": "./types/index.d.ts"
    },
    "./test-util": {
      "import": "./esm/test-util/test.js",
      "require": "./script/test-util/test.js",
      "types": "./types/test-util/test.d.ts"
 },

And same error occurs upon running next build.

Seems like quite a big problem that type resolution of package.json exports is unsupported.

@jankaifer jankaifer added the please verify canary The issue should be verified against next@canary. It will be closed after 30 days of inactivity label Jan 18, 2023
@github-actions
Copy link
Contributor

Please verify that your issue can be recreated with next@canary.

Why was this issue marked with the please verify canary label?

We noticed the provided reproduction was using an older version of Next.js, instead of canary.

The canary version of Next.js ships daily and includes all features and fixes that have not been released to the stable version yet. You can think of canary as a public beta. Some issues may already be fixed in the canary version, so please verify that your issue reproduces by running npm install next@canary and test it in your project, using your reproduction steps.

If the issue does not reproduce with the canary version, then it has already been fixed and this issue can be closed.

How can I quickly verify if my issue has been fixed in canary?

The safest way is to install next@canary in your project and test it, but you can also search through closed Next.js issues for duplicates or check the Next.js releases. You can also use the GitHub template (preferred), or the CodeSandbox or StackBlitz templates to create a reproduction with canary from scratch.

My issue has been open for a long time, why do I need to verify canary now?

Next.js does not backport bug fixes to older versions of Next.js. Instead, we are trying to introduce only a minimal amount of breaking changes between major releases.

What happens if I don't verify against the canary version of Next.js?

An issue with the please verify canary that receives no meaningful activity (e.g. new comments that acknowledge verification against canary) will be automatically closed and locked after 30 days.

If your issue has not been resolved in that time and it has been closed/locked, please open a new issue, with the required reproduction, using next@canary.

I did not open this issue, but it is relevant to me, what can I do to help?

Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps. Furthermore, you can upvote the issue using the 👍 reaction on the topmost comment (please do not comment "I have the same issue" without repro steps). Then, we can sort issues by votes to prioritize.

I think my reproduction is good enough, why aren't you looking into it quicker?

We look into every Next.js issue and constantly monitor open issues for new comments.

However, sometimes we might miss one or two due to the popularity/high traffic of the repository. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.

Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.

Useful Resources

@nopelluhh
Copy link
Author

hey @jankaifer, i've verified that this is still a problem with the latest canary.

new sandbox: https://stackblitz.com/edit/vercel-next-js-cpvefa

repro steps:

  1. observe that npx tsc succeeds
  2. observe that npm run build fails type checking (it also seems oddly slow given the project size but that's unrelated)

@jankaifer jankaifer added kind: bug and removed please verify canary The issue should be verified against next@canary. It will be closed after 30 days of inactivity type: needs triage labels Jan 18, 2023
@github-actions github-actions bot added the linear: next Confirmed issue that is tracked by the Next.js team. label Jan 18, 2023
@qrohlf
Copy link
Contributor

qrohlf commented Feb 8, 2023

I have spun up a new PR that aims to resolve this issue: #45670

shuding added a commit that referenced this issue Feb 15, 2023
#45670)

## Bug

The `next build` command is silently overriding the user's tsconfig when
it shouldn't be; this results in mismatched behavior between `tsc
--noEmit` and `yarn build` and user confusion.

For example, a configuration option like `"moduleResolution":
"nodenext"`, which is preserved and respected by `next dev`, will be
silently overridden to `"moduleResolution": "node"` during `next build`.

This change:
- Fixes #38854
- (probably fixes) #45452 (I have not verified)
- (probably fixes) #41189 (I have not verified)

## Details

Next has a concept of both _defaults_ and _permitted options_ when
modifying/validating the user's tsconfig. The user's config is only
modified if it does not match the _permitted options_. This means that
if the user has specified a permitted value like `"moduleResolution":
"nodenext"`, it will not be overwritten in the user's config file.

However, there was some logic in `runTypeCheck.ts` that did not
adequately capture this nuance – instead, it spread all of the defaults
into the tsconfig it was building before running typecheck, which meant
that if a user had specified an option that was _permitted_ but
_non-default_, it would be overwritten, silently, during `yarn build`
only.

Because Next is already (1) rewriting the TSconfig in
`writeConfigurationDefaults` when the user's config doesn't line up with
what we're expecting and (2) verifying the user's TSConfig remains
correct (in `verifyTypeScriptSetup`) during a `next build`, I believe
that it is safe to remove this config-steamrolling behavior.

## Documentation / Examples

I believe this is strictly a bugfix; it updates the behavior of `next
build` to conform to the same configuration behavior exhibited by `tsc
--noEmit` and `next dev`. Since this is already the user expectation, it
should not require documentation changes.

---------

Co-authored-by: Shu Ding <g@shud.in>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. TypeScript Related to types with Next.js.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants