QwikDev / qwik

Instant-loading web apps, without effort
https://qwik.dev
MIT License
20.54k stars 1.28k forks source link

[🐞] Support Typescript "moduleResolution": "node16" and "bundler" #4689

Open ziimakc opened 1 year ago

ziimakc commented 1 year ago

Which component is affected?

Qwik Rollup / Vite plugin

Describe the bug

When using esm import .js or .jsx extensions is required. Trying to follow this requirement qwik fails to build with the following error:

Could not resolve "./components/router-head/router-head.jsx" from "src/s_qn6vsz8sp28.js"

error during build:
RollupError: Could not resolve "./components/router-head/router-head.jsx" from "src/s_qn6vsz8sp28.js"
    at error (file:///home/app/node_modules/.pnpm/rollup@3.25.1/node_modules/rollup/dist/es/shared/node-entry.js:2213:30)
    at ModuleLoader.handleInvalidResolvedId (file:///home/app/node_modules/.pnpm/rollup@3.25.1/node_modules/rollup/dist/es/shared/node-entry.js:24219:24)
    at file:///home/app/node_modules/.pnpm/rollup@3.25.1/node_modules/rollup/dist/es/shared/node-entry.js:24181:26
// root.tsx
import { RouterHead } from "./components/router-head/router-head.jsx";

Reproduction

Steps to reproduce

No response

System Info

System:
    OS: Linux 5.15 Ubuntu 22.04.1 LTS 22.04.1 LTS (Jammy Jellyfish)
    CPU: (8) x64 Intel(R) Core(TM) i5-9300H CPU @ 2.40GHz
    Memory: 5.29 GB / 7.68 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 18.16.1 - /usr/bin/node
    npm: 9.5.1 - /usr/bin/npm

Additional Information

No response

manucorporat commented 1 year ago

When using esm import .js or .jsx extensions is required

Not sure i understand

manucorporat commented 1 year ago

Tried and it works, can you provide a full repo that reprodices the issue?

ziimakc commented 1 year ago

@manucorporat

Here is example:

Problem is because of .jsx suffix import { RouterHead } from "./components/router-head/router-head.jsx";

ziimakc commented 1 year ago

Probably related: https://github.com/rollup/rollup/issues/4917

ziimakc commented 1 year ago

See also https://github.com/vitejs/vite/issues/8993

ziimakc commented 1 year ago

Temporary solution:

import { defineConfig } from "vite";
import { qwikVite } from "@builder.io/qwik/optimizer";
import { qwikCity } from "@builder.io/qwik-city/vite";
import pluginTypescript from "@rollup/plugin-typescript";

export default defineConfig(() => {
  return {
    plugins: [qwikCity(), qwikVite()],
    build: {
      rollupOptions: {
        plugins: [pluginTypescript()],
      },
    },
  };
});

Also remove outDir and declaration from tsconfig

octet-stream commented 6 months ago

I have the same issue. Here's minimal repro on StackBlitz: https://stackblitz.com/edit/qwik-starter-rfjklh?file=src%2Froot.tsx

Just run npm run build in the terminal and you'll get the error.

octet-stream commented 6 months ago

From what I can tell, it is possible to use .js extensions when importing modules within .ts files. At least this is possible for server-side code. You can see that in src/routes/plugin.ts file: if you remove .js from src/root.tsx, but keep one in src/routes/plugin.tsx then npm run build will build the project successfully. I have tried to import the same file (src/lib/add) in home page module. It shows the error even with npm run dev if I use add function imported from this module in useTask$. On the server this code will be imported and executed without any problem, but then on the client it doesn't work.

PatrickJS commented 2 months ago

̶t̶h̶i̶s̶ ̶s̶e̶e̶m̶s̶ ̶t̶o̶ ̶w̶o̶r̶k̶ ̶n̶o̶w̶ ̶a̶s̶ ̶w̶e̶ ̶a̶r̶e̶ ̶o̶n̶ ̶d̶i̶f̶f̶e̶r̶e̶n̶t̶ ̶T̶y̶p̶e̶S̶c̶r̶i̶p̶t̶ ̶v̶e̶r̶s̶i̶o̶n̶ ̶a̶n̶d̶ ̶n̶o̶d̶e̶ ̶r̶e̶q̶u̶i̶r̶e̶m̶e̶n̶t̶ ̶n̶o̶w̶.̶ ̶p̶l̶e̶a̶s̶e̶ ̶m̶a̶k̶e̶ ̶a̶ ̶n̶e̶w̶ ̶i̶s̶s̶u̶e̶ ̶i̶f̶ ̶t̶h̶e̶r̶e̶ ̶i̶s̶ ̶s̶t̶i̶l̶l̶ ̶a̶n̶ ̶i̶s̶s̶u̶e̶

octet-stream commented 2 months ago

@PatrickJS is there any estimate date for this fix to be released? Because I still get the same error in 1.5.3, so it's not fixed yet.

PatrickJS commented 2 months ago

I need a repro repo the one provided is not public and is it only this version of TypeScript or can we use latest version?

octet-stream commented 2 months ago

Sure, here you go: https://github.com/octet-stream/qwik-typescript-js-extension-issue

PatrickJS commented 2 months ago

well it's .tsx and you need allowImportingTsExtensions: true in tsconfig

octet-stream commented 2 months ago

This doesn't solve the issue, I just get different error if I replace .js with .ts/.tsx:

vite v5.2.11 building for production...
✓ 46 modules transformed.
/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:10103
    throw new Error("start < 0");
    ^

Error: start < 0
    at createTextSpan (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:10103:11)
    at createTextSpanFromBounds (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:10111:10)
    at getErrorSpanForNode (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:12660:10)
    at createDiagnosticForNodeFromMessageChain (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:12497:16)
    at resolveExternalModule (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:47034:31)
    at resolveExternalModuleNameWorker (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:46928:61)
    at resolveExternalModuleName (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:46925:12)
    at getSymbolAtLocation (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:82585:18)
    at Object.getSymbolAtLocation (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:43783:21)
    at getReferencedFilesFromImportLiteral (/Users/octetstream/projects/qwik-test/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/tsc.js:120886:28)

Node.js v20.11.1
rendering chunks (19)... ELIFECYCLE  Command failed with exit code 1.
computing gzip size (0)...

 ELIFECYCLE  Command failed

It is important to mention that I need the .js extension, because I might need run parts of my code with ts-node. Case it: Mikro ORM cli support, which is relying on ts-node. TypeScript allows this extension and Node.js requires it for ESM paths. And this is why I set moduleResolution to node16 and not bundler.

PatrickJS commented 2 months ago

oh yeah I see there were changing in tsconfig. I don't know enough about TypeScript to help with this maybe someone else can

ok it looks like we need to work on updating our "moduleResolution"

this seems like an optimizer issue. maybe @wmertens something with the optimizer to detect or ignore .js https://github.com/PatrickJS/qwik-typescript-js-extension-issue/tree/moduleResolution-bundler

image

PatrickJS commented 2 months ago

yeah the quick fix might be a plugin to remap the .js to the correct files before qwik takes over

ziimakc commented 1 month ago

For anyone who want to use proper .js extension, install @rollup/plugin-typescript and use following config as example:

tsconfig.json

{
    "extends": "../../other/tsconfig.base.json",
    "compilerOptions": {
        "target": "ES2022",
        "module": "ES2022",
        "lib": ["es2022", "DOM", "WebWorker", "DOM.Iterable"],
        "jsx": "react-jsx",
        "jsxImportSource": "@builder.io/qwik",
        "moduleResolution": "Bundler",
        "esModuleInterop": true,
        "incremental": true,
        "outDir": "dist",
        "noEmit": true
    },
    "include": ["src", "./*.d.ts", "./*.config.ts"]
}

vite.config.ts:

import { qwikCity } from "@builder.io/qwik-city/vite";
import { qwikVite } from "@builder.io/qwik/optimizer";
import pluginTypescript from "@rollup/plugin-typescript";
import { defineConfig, type UserConfig } from "vite";

export default defineConfig(({ command, mode }): UserConfig => {
    const config: UserConfig = {
        plugins: [qwikCity(), qwikVite()],
        build: {
            rollupOptions: {
                plugins: [pluginTypescript()],
            },
        },
    };

    return config;
});
wmertens commented 1 month ago

I don't understand, doesn't ts-node look at tsconfig? We recommend using module resolution Bundler.