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

Next.js compiles .ts files outside of the application directory, but not .tsx files #19928

Closed
goloroden opened this issue Dec 7, 2020 · 9 comments
Assignees
Milestone

Comments

@goloroden
Copy link

Bug report

Describe the bug

Next.js supports TypeScript, which means that it is able to load .ts and .tsx files from within the application directory. In addition, Next.js also supports loading files from outside the application directory, e.g. to be able to use shared components. However, this only works for .ts files, not for .tsx files. This is unexpected and makes it hard to work with re-usable UI components, without having to come up with a separate npm module for them, which is often not what you need.

To Reproduce

We have set up a sample repository with a small, but complete example to reproduce the issue. Please see https://github.com/thenativeweb/temp--next-issue for details. The README.md file contains the detailed description on how to reproduce the issue.

Expected behavior

Next.js should not only support .ts files from outside the application directory, but .tsx files as well.

System information

  • OS: macOS Big Sur (11.0.1)
  • Version of Next.js: 10.0.3
  • Version of Node.js: 14.14.0
  • Deployment: npx next

Additional context

Setting up a separate npm module for the shared components is definitely not what we want to use. Even the various Next.js applications we have shall be in a single npm module, as they get started altogether using a custom server. So in the end, although our "real" repository contains multiple Next.js applications, there is only one actual application in the end. This is also the reason why we don't want to go down the next-transpile-modules road (it would force us to introduce separate modules as well).

Given that Next.js is able without any ado to handle .ts files from outside the application directory, we assume that the same should be possible for .tsx files.

@goloroden goloroden added the bug Issue was opened via the bug report template. label Dec 7, 2020
@Timer
Copy link
Member

Timer commented Dec 8, 2020

Next.js does not support importing .ts OR .tsx outside of the app, by design. The only way this would work is due to custom configuration, which you have:
https://github.com/thenativeweb/temp--next-issue/blob/master/applications/one/next.config.js

Please file this issue with the unofficial plugin you're using!

@Timer Timer closed this as completed Dec 8, 2020
@goloroden
Copy link
Author

@Timer Thanks for taking the time to look into this issue!

We have removed the custom configuration with the plugin, and the behavior stays exactly the same – Next.js compiles .ts files from outside the application folder, but not .tsx files. So the problem is not related to the unofficial plugin, but from our point of view directly to Next.js.

Please find the updated demo code here: https://github.com/thenativeweb/temp--next-issue/tree/3b50a30c5dd634f95bd0828b573b073e3b9bf7db

@Timer
Copy link
Member

Timer commented Dec 8, 2020

We shouldn't support importing .ts files, so we probably need to fix this behavior to be in line with .tsx.

@Timer Timer reopened this Dec 8, 2020
@Timer Timer added kind: bug and removed bug Issue was opened via the bug report template. labels Dec 8, 2020
@Timer Timer modified the milestones: iteration 15, iteration 14 Dec 8, 2020
@goloroden
Copy link
Author

Of course, if the entire answer is "we don't support that", then it's like that – but given that the question for shared files across multiple Next.js applications has been more than once (e.g., see #3018), it may be a helpful feature for lots of developers.

Besides, given that it is possible with Next.js applications hosted on Vercel, it has to work somehow (see https://vercel.com/blog/monorepos#faq, "Can I share source files between projects? Are Yarn & Lerna Workspaces supported?").

@goloroden
Copy link
Author

@Timer After I slept again on the matter, I would like to leave a somewhat longer comment.

But first of all I would like to emphasize that Vercel is doing a great job with Next.js: Next.js is a great platform that really speeds up the development of React applications. The React ecosystem would not be the same without Next.js. So, first of all, thanks a lot for all you have done so far 🦄

Since we (my company and I) also do a lot of open source ourselves, we know that sometimes there are users who expect to have a "right" to demand certain features or bug fixes, but forget that you get the software for free, basically as a gift. I don't want to be such a user. I don't want do be disrespectful, and I don't want to demand that you do something for free. This is, of course, your very own decision.

We use Next.js for numerous projects, small and large ones, and we like to use Next.js modularly, i.e. as part of a custom server. For this it is sometimes important to be able to access files / components that are outside the application root. Apparently we are not alone with this, as the following issues show:

But as I said, I also know that we have no right to demand that Next.js supports this. So I respect the decision to not support this feature, of course. But it would be nice to be able to understand the decision. It's one thing if someone tells you "we won't do that", and another if someone tells you "we won't do that because ...".

But this is exactly what's missing here, the reasons. This is unsatisfactory for us as part of the community, and for this very reason - because of not being able to understand your decision - this issue returns again and again from time to time. This is unnecessary for everyone involved, especially for you: I can imagine that you have better things to do than answer the same question over and over again.

Hence the question: Could you perhaps explain what the reasons are for not wanting to support this feature? Are there technical reasons? If so, which ones? Are there business reasons? If so, which ones? As said, I'm not asking you to add the feature, that's not up to me. I would just like to understand why you decide to do like you do, because as an outsider it is very difficult to understand from what we know right now.

Oh, and by the way: Of course it would be pretty awesome if you added this feature, because it would turn Next.js into an even greater platform 😊

@Timer
Copy link
Member

Timer commented Dec 9, 2020

I'll provide additional background:

Next.js currently only compiles assets that it considers to be first-party to your application.
i.e. packages within the project root where next build is invoked from.

This was an intentional design decision and is in-line with other tools like Create React App (FWIW CRA has an even stricter restriction of forbidding even .js outside of root).

The thought process behind this decision is that code outside of your project's directory may be on different version(s) of packages or using different syntax features not yet supported by Next.js, e.g. React 16 vs 17 (using the new JSX transform) or TypeScript 3 vs 4 (using new syntax features).

The code for projects outside of Next.js' project root, even in the same monorepo, should be precompiled with their own tooling (e.g. tsdx) so that Next.js can consume it as it would something from node_modules.

This eliminates the need for you to upgrade all your Next/React/TypeScript/etc versions in tandem across a potentially large monorepo, i.e. it provides isolation by ensuring assets are compiled down to a common interop language: ESLatest JS (same as node_modules).


With the above background stated, I'm treating this issue as a bug report because the current design intent is not to allow .ts imports (or .tsx) outside of the project root.

This doesn't mean we're not considering allowing this, and we have an issue open to track allowing this behavior:
#9474

We realize that small monorepos / certain organizations are ok with having to update all their TypeScript/etc versions in tandem, so we'll let people opt-into this behavior.

You can track this issue (#9474) which would be the feature request version of this issue: to allow importing .ts and .tsx outside of project root.

@goloroden
Copy link
Author

@Timer Thanks a lot for replying that quick, and thanks for the detailed explanation! Once you know this background, your decision absolutely makes sense, and I understand now why you have insisted on this behavior in the past.

As said before, of course it would be awesome if there was a great solution for this (I suppose we are one of those companies not having a problem with updating all-at-once 😉), but then we'll do as you suggested, and track the progress in #9474

Once again, thanks a lot for your quick answer! This definitely helped to make things clearer 😊

@Timer Timer self-assigned this Dec 31, 2020
kodiakhq bot pushed a commit that referenced this issue Mar 19, 2021
…of the root directory (#22867)

This PR attempts to provide an option to allow importing TS/TSX from outside of the current Next.js project root directory. Although this goes against the design decision that no source code should be imported from outside of root and [might bring tons of issues](#19928 (comment)), it will still be helpful in some monorepo use cases.

This PR assumes that the external files are following the same language syntax rules and under the same tooling versions as the source code inside your project root. And it's also not allowed to enable the `baseUrl` feature in the external directory (as the project should only have 1 import base URL).

X-ref: #9474, #15569, #19928, #20374.
@timneutkens timneutkens modified the milestones: Iteration 18, Iteration 19 Apr 8, 2021
flybayer pushed a commit to blitz-js/next.js that referenced this issue Apr 29, 2021
…of the root directory (vercel#22867)

This PR attempts to provide an option to allow importing TS/TSX from outside of the current Next.js project root directory. Although this goes against the design decision that no source code should be imported from outside of root and [might bring tons of issues](vercel#19928 (comment)), it will still be helpful in some monorepo use cases.

This PR assumes that the external files are following the same language syntax rules and under the same tooling versions as the source code inside your project root. And it's also not allowed to enable the `baseUrl` feature in the external directory (as the project should only have 1 import base URL).

X-ref: vercel#9474, vercel#15569, vercel#19928, vercel#20374.
@timneutkens
Copy link
Member

We've landed an experimental feature for this, please try it out: #22867

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants