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

Missing imports when using NodeNext moduleResolution #657

Closed
cusxio opened this issue Jan 18, 2023 · 8 comments
Closed

Missing imports when using NodeNext moduleResolution #657

cusxio opened this issue Jan 18, 2023 · 8 comments

Comments

@cusxio
Copy link

cusxio commented Jan 18, 2023

Describe the bug

There are missing imports when moduleReslution: NodeNext is used.

CleanShot 2023-01-18 at 15 57 09@2x

Your Example Website or App

https://stackblitz.com/edit/github-gtcsmu?file=tsconfig.json,src%2Froot.tsx

Steps to Reproduce the Bug or Issue

  1. Go to the stackblitz provided.
  2. Make sure to change the moduleResolution in tsconfig.json to NodeNext.
  3. Go to the file root.tsx, noticed that some imports are broken.

Expected behavior

Users should be able to import any solid-js packages without any problems when moduleResolution: NodeNext is used.

Screenshots or Videos

No response

Platform

  • OS: macOS 13.1
  • Browser: Brave
  • Version: 1.47.171

Additional context

No response

@ryansolid ryansolid transferred this issue from solidjs/solid Jan 18, 2023
@ryansolid
Copy link
Member

How peculiar. The exports are there in the TS code. They just come in from a different source than the others. Very strange.

@cusxio
Copy link
Author

cusxio commented Jan 19, 2023

Very strange indeed.


export * from "./router";

I updated the line above to include the file extension, and it seems to fix the typing issue.

i.e.

export * from "./router.jsx"; 

I added it because Typescript was emitting the following error,

Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Consider adding an extension to the import path.

@ryansolid
Copy link
Member

I see. Its interesting that some of the relative local paths work without the extension. Maybe it is related to it being an export * as well. Atleast that gives us a direction for the fix.

@cusxio
Copy link
Author

cusxio commented Jan 19, 2023

Further investigation seems to indicate that solid-start package.json does not seem to handle the types correctly for both cjs and esm modules.

See discussion below,
microsoft/TypeScript#50466 (comment)

Semi related blog post,
https://blog.axlight.com/posts/how-jotai-specifies-package-entry-points/

Working examples in the wild,
https://unpkg.com/browse/hono@2.7.3/package.json
https://unpkg.com/browse/jotai@1.13.1/package.json

@marbemac
Copy link
Contributor

export * from "./router";

Indeed I just ran into this on a separate project that uses @solidjs/router directly. Can reproduce by creating a new vanilla solid typescript project (so, I do not think that this is solid-start specific), add @solidjs/router, import Outlet or anything that comes form the ./router file, and switch moduleResolution to nodenext in your tsconfig file.

@peterhirn
Copy link

peterhirn commented Jul 26, 2023

I think there are two options to add support for nodenext / node16 module resolution:
a) Add .js / .jsx to all imports
b) Compile the library to .js + d.ts before shipping it (solid-start ships raw typescript, eg. node_modules/solid-start/entry-server/index.ts)

I'm using nodenext in one of my monorepo projects and love it. Imports + types finally fucking work ootb without the need to build project dependencies upfront.

A partial patch

diff --git a/entry-server/index.ts b/entry-server/index.ts
index 0f964ff2aff7c86693ac4a2af1f0d3633841a625..4877c4cd885dc8485b4f21d9b7a3fdc3b7842d68 100644
--- a/entry-server/index.ts
+++ b/entry-server/index.ts
@@ -1,4 +1,4 @@
-export * from "./render";
+export * from "./render.js";
 // server-side only exports
-export { composeMiddleware, createHandler, default as StartServer } from "./StartServer";
-export type { Middleware, MiddlewareFn, MiddlewareInput } from "./StartServer";
+export { composeMiddleware, createHandler, default as StartServer } from "./StartServer.jsx";
+export type { Middleware, MiddlewareFn, MiddlewareInput } from "./StartServer.jsx";
diff --git a/index.tsx b/index.tsx
index 74f088b550d05a49f1dcd83cf13bf4f9c20e65c6..0794b203d35954cb5ac5da679e1d1b655658b8f4 100644
--- a/index.tsx
+++ b/index.tsx
@@ -13,7 +13,7 @@ export {
   type RouteDataFunc,
   type RouteDataFuncArgs as RouteDataArgs
 } from "@solidjs/router";
-export type { APIEvent as APIEvent } from "./api";
+export type { APIEvent as APIEvent } from "./api/index.js";
 export {
   createRouteAction,
   createRouteData,
@@ -21,15 +21,15 @@ export {
   FormError,
   refetchRouteData,
   ServerError
-} from "./data";
-export type { FormAction, FormMethod, FormProps, SubmitOptions } from "./data";
-export { default, ErrorBoundary, ErrorMessage } from "./error-boundary";
-export { clientOnly as unstable_clientOnly, island as unstable_island } from "./islands";
-export { Body, Head, Html, Scripts } from "./root";
-export * from "./router";
-export * from "./server/responses";
-export { ServerContext, useRequest as useServerContext } from "./server/ServerContext";
-export type { FetchEvent, PageEvent, ServerFunctionEvent } from "./server/types";
+} from "./data/index.js";
+export type { FormAction, FormMethod, FormProps, SubmitOptions } from "./data/index.js";
+export { default, ErrorBoundary, ErrorMessage } from "./error-boundary/index.js";
+export { clientOnly as unstable_clientOnly, island as unstable_island } from "./islands/index.js";
+export { Body, Head, Html, Scripts } from "./root/index.js";
+export * from "./router.jsx";
+export * from "./server/responses.js";
+export { ServerContext, useRequest as useServerContext } from "./server/ServerContext.jsx";
+export type { FetchEvent, PageEvent, ServerFunctionEvent } from "./server/types.jsx";
 export {
   createCookie,
   createCookieSessionStorage,
@@ -41,7 +41,7 @@ export {
   type CookieSerializeOptions,
   type SessionIdStorageStrategy,
   type SessionStorage
-} from "./session";
+} from "./session/index.js";
 import { JSX } from "solid-js";
-import "./types";
+import "./types.js";
 export declare function FileRoutes(): JSX.Element;
diff --git a/server/index.ts b/server/index.ts
index e3a17c6cbd5577bb7f1e2b92d2a9c6d1f51d6c2e..262670c9f5b68e5e955cdba6d27a84c39039c150 100644
--- a/server/index.ts
+++ b/server/index.ts
@@ -1,5 +1,5 @@
 // This file only exists to make the TypeScript tsconfig setting `"moduleResolution": "node"` work.
 // See ./server.ts for the server entrypoint and ./browser.ts for the browser entrypoint
-import server$ from "./server";
+import server$ from "./server.js";
 export default server$;
-export * from "./server";
+export * from "./server.js";
diff --git a/server/server.ts b/server/server.ts
index 832b5cb0c8319efda5b9941269b0613cca48d226..592eca1b6aee5647eb3ee370d92a514d910da8be 100644
--- a/server/server.ts
+++ b/server/server.ts
@@ -1,5 +1,5 @@
-import { server$ } from "./server-functions/server";
+import { server$ } from "./server-functions/server.js";
 
 export default server$;
 
-export * from "./shared";
+export * from "./shared.js";
diff --git a/server/shared.ts b/server/shared.ts
index 79bf4402dd2048f4f7fb703e9502a9a8917814f3..df2ce46b132d309369c7088fe4ca30c82727441b 100644
--- a/server/shared.ts
+++ b/server/shared.ts
@@ -1,7 +1,7 @@
-export { HttpHeader } from "./components/HttpHeader";
-export { HttpStatusCode } from "./components/HttpStatusCode";
-export { createServerAction$, createServerData$, createServerMultiAction$, ServerError } from "./data";
-export * from "./responses";
-export * from "./ServerContext";
-export * from "./types";
+export { HttpHeader } from "./components/HttpHeader.jsx";
+export { HttpStatusCode } from "./components/HttpStatusCode.jsx";
+export { createServerAction$, createServerData$, createServerMultiAction$, ServerError } from "./data.js";
+export * from "./responses.js";
+export * from "./ServerContext.jsx";
+export * from "./types.jsx";
 
diff --git a/virtual/entry-server.tsx b/virtual/entry-server.tsx
index 4e4a3cefb478c59568070fc89dae6489d9dc2f55..0a2159291d73efeb48b4e5f1406f8853bbee16b5 100644
--- a/virtual/entry-server.tsx
+++ b/virtual/entry-server.tsx
@@ -1,3 +1,3 @@
-import { createHandler, renderAsync, StartServer } from "../entry-server";
+import { createHandler, renderAsync, StartServer } from "../entry-server/index.js";
 
 export default createHandler(renderAsync(event => <StartServer event={event} />));

Update: I just checked that applying this patch to a project which uses "moduleResolution": "node" still works as expected.

@marbemac
Copy link
Contributor

@peterhirn does "moduleResolution": "bundler" work for you? This is my new go-to setting, because it finally supports the package.json#exports property in local mono-repos 🎉.

@ryansolid
Copy link
Member

In setting up for SolidStarts next Beta Phase built on Nitro and Vinxi we are closing all PRs/Issues that will not be merged due to the system changing. If you feel your issue was closed by mistake. Feel free to re-open it after updating/testing against 0.4.x release. Thank you for your patience.

See #1139 for more details.

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

No branches or pull requests

4 participants