ezolenko / rollup-plugin-typescript2

Rollup plugin for typescript with compiler errors.
MIT License
819 stars 71 forks source link

watch doesn't update TS files when `check: false` or within Vue files #433

Open mav-rik opened 1 year ago

mav-rik commented 1 year ago

What happens and why it is incorrect

When running rollup.watch (programmatically) only the first build goes well. All the following builds result in the same output for .ts files. I've added a .js file and only that .js file gets changes on every re-build. None of the .ts files get an update after re-build.

Same for .vue files. When using <script setup lang="ts"> - it doesn't get updates after re-builds. When using <script setup> - works fine. But I guess there is a single cause for both.

Yes I pass clean: true option.

Environment

WSL 2

Versions

rollup-plugin-typescript2 v0.34.1

  System:
    OS: Linux 5.10 Ubuntu 20.04 LTS (Focal Fossa)
    CPU: (12) x64 12th Gen Intel(R) Core(TM) i7-1265U
    Memory: 15.76 GB / 24.62 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 18.12.1 - /usr/local/bin/node
    npm: 8.19.2 - /usr/local/bin/npm
  npmPackages:
    rollup: ^3.10.0 => 3.10.0 

rollup.config.js

:
```json "plugins": [ { "name": "virtual" }, { "name": "node-resolve", "version": "15.0.1", "resolveId": { "order": "post" } }, { "name": "rpt2" }, { "name": "vue" }, { "name": "scss" } ] ```

plugin output with verbosity 3

:
```text rpt2: parsed tsconfig: { "options": { "moduleResolution": 2, "esModuleInterop": true, "target": 2, "module": 99, "lib": [ "lib.esnext.d.ts", "lib.dom.d.ts", "lib.dom.iterable.d.ts" ], "noUnusedLocals": true, "declaration": false, "resolveJsonModule": true, "downlevelIteration": true, "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitAny": false, "skipLibCheck": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "configFilePath": ".../tsconfig.json", "noEmitHelpers": false, "importHelpers": true, "noResolve": false, "noEmit": false, "noEmitOnError": false, "inlineSourceMap": false, "allowNonTsExtensions": true }, rpt2: typescript version: 4.9.4 rpt2: tslib version: 2.4.1 rpt2: rollup version: 3.10.0 rpt2: rollup-plugin-typescript2 version: 0.34.1 rpt2: plugin options: { "check": false, "verbosity": 3, "clean": true, "cacheRoot": ".../node_modules/.cache/rollup-plugin-typescript2", "include": [ "*.ts+(|x)", "**/*.ts+(|x)" ], "exclude": [ "*.d.ts", "**/*.d.ts" ], "abortOnError": true, "rollupCommonJSResolveHack": false, "useTsconfigDeclarationDir": false, "tsconfigOverride": { "compilerOptions": { "noImplicitAny": false, "noUnusedLocals": true, "declaration": false } }, "transformers": [], "tsconfigDefaults": {}, "objectHashIgnoreUnknownHack": false, "cwd": "...", "typescript": "version 4.9.4" } ```
mav-rik commented 1 year ago

Created minimum reproduction repo

mav-rik commented 1 year ago

@agilgur5 my repro helped me to narrow down the issue. I found out that only when I set plugin option check: false the issue occurs for TS and Vue files. If I set check: true, the issue only occurs for Vue files. TS files update well in that case.

agilgur5 commented 1 year ago

reproduction

When running rollup.watch (programmatically)

For some context, the codebase has watch mode integration tests that pass successfully and similarly use the Rollup API.

So a failing test case or minimum repro would be necessary as such, so thanks for updating with one.

@agilgur5 my repro helped me to narrow down the issue.

That is one of the reasons the issue template asks for a repro 😉

Vue integration

So Vue SFCs are pretty convoluted and have some issues with them per #129. That and the fact that rollup-plugin-vue has been unmaintained for >2 years now makes the Vue integration pretty tricky, to say the least.

check: false

Now this sounds like a possible cache bug. I actually have an old WIP branch where I added more watch mode tests -- including the case of check: false -- that I couldn't get working due to bugs (see #386 for some details) and wasn't able to fix all of them as of yet.

The interesting thing here is that you're using clean: true and still getting a stale cache. This I think is because of staleness in Rollup's own watch cache (separate from rpt2's internal cache). I mentioned this in https://github.com/ezolenko/rollup-plugin-typescript2/pull/386#issuecomment-1192121874 that we probably need to implement the relatively new shouldTransformCachedModule hook to handle some use-cases.... and that I was surprised so few watch mode bugs had been filed in this repo's history -- it's definitely buggy 😅

agilgur5 commented 1 year ago

This is a relatively complex issue to debug and fix, so I would suggest working around this (check: true or no watch mode) for now, as I don't think I'll have the time commitment needed to get to this soon.

ezolenko commented 1 year ago

This might be fixed by 0.35.0, since the cache is not used in watch mode anymore after #452

agilgur5 commented 1 year ago

@ezolenko can you test this with the provided repro before closing?

Per my previous comment, given that this was happening with clean: true, I suspect this might be due to Rollup's own watch mode cache and may require implementing shouldTransformCachedModule.

agilgur5 commented 1 year ago

Unfortunately I was indeed able to reproduce this with 0.35.0, so it likely does require implementing shouldTransformCachedModule. I added a PR to the repro repo: https://github.com/mav-rik/rollup-plugin-typescript2-issue-433/pull/1

Great repro with some logging to easily show if it's still broken or not!

ukhan commented 3 months ago

I came across the same problem and tried to understand the reason.

The interesting thing here is that you're using clean: true and still getting a stale cache. This I think is because of staleness in Rollup's own watch cache (separate from rpt2's internal cache).

The issue is not with the Rollup cache but with the same DocumentRegistry between watch cycles.

Here is a repository with hypothesis confirmation.

That and the fact that rollup-plugin-vue has been unmaintained for >2 years now makes the Vue integration pretty tricky, to say the least.

You can use the actual @vitejs/plugin-vue instead of the unmaintained rollup-plugin-vue.