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

failed to transpile tslib.es6.js after update to v0.30.0 #264

Closed
rafgraph opened this issue Mar 21, 2021 · 7 comments
Closed

failed to transpile tslib.es6.js after update to v0.30.0 #264

rafgraph opened this issue Mar 21, 2021 · 7 comments
Labels
kind: support Asking for support with something or a specific use case problem: removed issue template OP removed the issue template without good cause solution: invalid This doesn't seem right topic: TS Compiler API Docs Related to the severely lacking TS Compiler API Docs

Comments

@rafgraph
Copy link

rafgraph commented Mar 21, 2021

What happens and why it is wrong

failed to transpile '[...]/node_modules/tslib/tslib.es6.js'

rollup-plugin-typescript2 v0.29.0 works fine, v0.30.0 introduces this error.

The setup is a bit complex because it happened as part of Rollpkg. It happens when tsconfig target: es5 (so tslib is needed). I was alerted to it from this issue. Rollpkg v0.5.0 has the bug, v0.5.1 fixes it by downgrading rollup-plugin-typescript2 to v0.29.0.

I'm using TypeScript v4.2.3.

@rafgraph
Copy link
Author

You can reproduce it in this repo branch (it uses Rollpkg v0.5.0): https://github.com/rafgraph/react-router-hash-link/tree/rollpkg-0.5.0, just run npm i && npm run build to see the error. The main branch is fixed and uses Rollpkg v0.5.1.

@ezolenko
Copy link
Owner

ezolenko commented Mar 23, 2021

I get this error when trying to do npm run build on that branch:


✓ Cleaning dist folder 7 ms
✓ Checking rollpkg invariants 3 ms
✓ Creating rollup config 0 ms
✓ Creating esm, cjs builds 815 ms
✓ Writing esm, cjs builds 217 ms
✓ ROLLPKG BUILD SUCCESS 😁😘 0 ms
✗ FAILED AT: Calculating Bundlephobia stats 

Bundlephobia Error: InstallError

Is this before rollup-plugin-typescript2 error?

I just updated node to latest to get there, otherwise it was erroring out on new JS syntax somewhere much earlier.

@rafgraph
Copy link
Author

rafgraph commented Mar 23, 2021

Thanks for looking into this issue. The error is before this. I just created a fresh clone and install and got the error. Weird that you're not getting the error too. Just to make to sure, you're on the branch rollpkg-0.5.0?

node v14.15.4
npm v7.6.3

react-router-hash-link on  remotes/origin/rollpkg-0.5.0 is 📦 v2.4.0 via ⬢ v14.15.4 took 12s
➜ npm run build

> [email protected] build
> rollpkg build

✓ Cleaning dist folder 1 ms
✓ Checking rollpkg invariants 3 ms
✓ Creating rollup config 0 ms
✗ FAILED AT: Creating esm, cjs builds

TypeScript Error: failed to transpile '/Users/rafael/dev/react-router-hash-link/node_modules/tslib/tslib.es6.js'

@ezolenko
Copy link
Owner

Yeah

git branch
  main
* rollpkg-0.5.0

node v14.16.0
npm 6.14.11

I'm on windows if that makes a difference.

@rafgraph
Copy link
Author

rafgraph commented Mar 23, 2021

That could be it. I'm on a Mac v11.2.3. I upgraded to node 14.16 and set verbosity to 3. Here's the log:

plugin output with verbosity 3:
➜ npm run build      

> [email protected] build
> rollpkg build

✓ Cleaning dist folder 1 ms
✓ Checking rollpkg invariants 4 ms
✓ Creating rollup config 0 ms
rpt2: built-in options overrides: {
    "noEmitHelpers": false,
    "importHelpers": true,
    "noResolve": false,
    "noEmit": false,
    "inlineSourceMap": false,
    "outDir": "/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/placeholder",
    "moduleResolution": 2,
    "allowNonTsExtensions": true
}
rpt2: parsed tsconfig: {
    "options": {
        "target": 1,
        "module": 99,
        "moduleResolution": 2,
        "esModuleInterop": true,
        "allowJs": true,
        "jsx": 2,
        "noEmit": false,
        "skipLibCheck": true,
        "strict": true,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": true,
        "forceConsistentCasingInFileNames": true,
        "types": [],
        "declaration": false,
        "rootDir": "/Users/rafael/dev/react-router-hash-link/src",
        "sourceMap": true,
        "configFilePath": "/Users/rafael/dev/react-router-hash-link/tsconfig.json",
        "noEmitHelpers": false,
        "importHelpers": true,
        "noResolve": false,
        "inlineSourceMap": false,
        "outDir": "/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/placeholder",
        "allowNonTsExtensions": true
    },
    "fileNames": [
        "/Users/rafael/dev/react-router-hash-link/src/HashLink.jsx",
        "/Users/rafael/dev/react-router-hash-link/src/index.ts",
        "/Users/rafael/dev/react-router-hash-link/node_modules/rollpkg/configs/types/global.d.ts"
    ],
    "typeAcquisition": {
        "enable": false,
        "include": [],
        "exclude": []
    },
    "raw": {
        "compilerOptions": {
            "target": "ES5",
            "types": [],
            "declaration": false,
            "rootDir": "./src",
            "module": "ESNext",
            "sourceMap": true
        },
        "include": [
            "src",
            "./node_modules/rollpkg/configs/types"
        ],
        "exclude": [
            "**/__tests__",
            "**/__mocks__",
            "**/__snapshots__",
            "**/*.test.*",
            "**/*.spec.*",
            "**/*.mock.*"
        ],
        "extends": "rollpkg/configs/tsconfig.json",
        "compileOnSave": false
    },
    "errors": [],
    "wildcardDirectories": {
        "/users/rafael/dev/react-router-hash-link/src": 1,
        "/users/rafael/dev/react-router-hash-link/node_modules/rollpkg/configs/types": 1
    },
    "compileOnSave": false
}
rpt2: typescript version: 4.2.3
rpt2: tslib version: 2.1.0
rpt2: rollup version: 2.42.1
rpt2: rollup-plugin-typescript2 version: 0.30.0
rpt2: plugin options:
{
    "verbosity": 3,
    "tsconfigDefaults": {
        "compilerOptions": {
            "target": "ES2018",
            "types": [],
            "declaration": true,
            "rootDir": "./src"
        },
        "include": [
            "src",
            "./node_modules/rollpkg/configs/types"
        ],
        "exclude": [
            "**/__tests__",
            "**/__mocks__",
            "**/__snapshots__",
            "**/*.test.*",
            "**/*.spec.*",
            "**/*.mock.*"
        ]
    },
    "tsconfigOverride": {
        "compilerOptions": {
            "module": "ESNext",
            "sourceMap": true
        }
    },
    "include": [
        "**/*.ts+(|x)",
        "**/*.js+(|x)"
    ],
    "check": true,
    "clean": false,
    "cacheRoot": "/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2",
    "exclude": [
        "*.d.ts",
        "**/*.d.ts"
    ],
    "abortOnError": true,
    "rollupCommonJSResolveHack": false,
    "useTsconfigDeclarationDir": false,
    "transformers": [],
    "objectHashIgnoreUnknownHack": false,
    "cwd": "/Users/rafael/dev/react-router-hash-link",
    "typescript": "version 4.2.3"
}
rpt2: rollup config:
{
    "external": [
        "prop-types",
        "react",
        "react-router-dom"
    ],
    "input": "/Users/rafael/dev/react-router-hash-link/src/index.ts",
    "treeshake": {
        "annotations": true,
        "moduleSideEffects": false,
        "propertyReadSideEffects": false,
        "tryCatchDeoptimization": false,
        "unknownGlobalSideEffects": false
    },
    "plugins": [
        {
            "name": "node-resolve"
        },
        {
            "name": "commonjs"
        },
        {
            "name": "json"
        },
        {
            "name": "rpt2"
        },
        {
            "name": "sourcemaps"
        },
        {
            "name": "replace"
        }
    ]
}
rpt2: tsconfig path: /Users/rafael/dev/react-router-hash-link/tsconfig.json
rpt2: included:
[
    "**/*.ts+(|x)",
    "**/*.js+(|x)"
]
rpt2: excluded:
[
    "*.d.ts",
    "**/*.d.ts"
]
rpt2: built-in options overrides: {
    "noEmitHelpers": false,
    "importHelpers": true,
    "noResolve": false,
    "noEmit": false,
    "inlineSourceMap": false,
    "outDir": "/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/placeholder",
    "moduleResolution": 2,
    "allowNonTsExtensions": true
}
rpt2: parsed tsconfig: {
    "options": {
        "target": 1,
        "module": 99,
        "moduleResolution": 2,
        "esModuleInterop": true,
        "allowJs": true,
        "jsx": 2,
        "noEmit": false,
        "skipLibCheck": true,
        "strict": true,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": true,
        "forceConsistentCasingInFileNames": true,
        "types": [],
        "declaration": false,
        "rootDir": "/Users/rafael/dev/react-router-hash-link/src",
        "sourceMap": true,
        "configFilePath": "/Users/rafael/dev/react-router-hash-link/tsconfig.json",
        "noEmitHelpers": false,
        "importHelpers": true,
        "noResolve": false,
        "inlineSourceMap": false,
        "outDir": "/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/placeholder",
        "allowNonTsExtensions": true
    },
    "fileNames": [
        "/Users/rafael/dev/react-router-hash-link/src/HashLink.jsx",
        "/Users/rafael/dev/react-router-hash-link/src/index.ts",
        "/Users/rafael/dev/react-router-hash-link/node_modules/rollpkg/configs/types/global.d.ts"
    ],
    "typeAcquisition": {
        "enable": false,
        "include": [],
        "exclude": []
    },
    "raw": {
        "compilerOptions": {
            "target": "ES5",
            "types": [],
            "declaration": false,
            "rootDir": "./src",
            "module": "ESNext",
            "sourceMap": true
        },
        "include": [
            "src",
            "./node_modules/rollpkg/configs/types"
        ],
        "exclude": [
            "**/__tests__",
            "**/__mocks__",
            "**/__snapshots__",
            "**/*.test.*",
            "**/*.spec.*",
            "**/*.mock.*"
        ],
        "extends": "rollpkg/configs/tsconfig.json",
        "compileOnSave": false
    },
    "errors": [],
    "wildcardDirectories": {
        "/users/rafael/dev/react-router-hash-link/src": 1,
        "/users/rafael/dev/react-router-hash-link/node_modules/rollpkg/configs/types": 1
    },
    "compileOnSave": false
}
rpt2: typescript version: 4.2.3
rpt2: tslib version: 2.1.0
rpt2: rollup version: 2.42.1
rpt2: rollup-plugin-typescript2 version: 0.30.0
rpt2: plugin options:
{
    "verbosity": 3,
    "tsconfigDefaults": {
        "compilerOptions": {
            "target": "ES2018",
            "types": [],
            "declaration": true,
            "rootDir": "./src"
        },
        "include": [
            "src",
            "./node_modules/rollpkg/configs/types"
        ],
        "exclude": [
            "**/__tests__",
            "**/__mocks__",
            "**/__snapshots__",
            "**/*.test.*",
            "**/*.spec.*",
            "**/*.mock.*"
        ]
    },
    "tsconfigOverride": {
        "compilerOptions": {
            "module": "ESNext",
            "sourceMap": true
        }
    },
    "include": [
        "**/*.ts+(|x)",
        "**/*.js+(|x)"
    ],
    "check": true,
    "clean": false,
    "cacheRoot": "/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2",
    "exclude": [
        "*.d.ts",
        "**/*.d.ts"
    ],
    "abortOnError": true,
    "rollupCommonJSResolveHack": false,
    "useTsconfigDeclarationDir": false,
    "transformers": [],
    "objectHashIgnoreUnknownHack": false,
    "cwd": "/Users/rafael/dev/react-router-hash-link",
    "typescript": "version 4.2.3"
}
rpt2: rollup config:
{
    "external": [
        "prop-types",
        "react",
        "react-router-dom"
    ],
    "input": "/Users/rafael/dev/react-router-hash-link/src/index.ts",
    "treeshake": {
        "annotations": true,
        "moduleSideEffects": false,
        "propertyReadSideEffects": false,
        "tryCatchDeoptimization": false,
        "unknownGlobalSideEffects": false
    },
    "plugins": [
        {
            "name": "node-resolve"
        },
        {
            "name": "commonjs"
        },
        {
            "name": "json"
        },
        {
            "name": "rpt2"
        },
        {
            "name": "sourcemaps"
        },
        {
            "name": "replace"
        },
        {
            "name": "replace"
        }
    ]
}
rpt2: tsconfig path: /Users/rafael/dev/react-router-hash-link/tsconfig.json
rpt2: included:
[
    "**/*.ts+(|x)",
    "**/*.js+(|x)"
]
rpt2: excluded:
[
    "*.d.ts",
    "**/*.d.ts"
]
🌏 Creating esm, cjs builds
rpt2: Ambient types:
rpt2:     /Users/rafael/dev/react-router-hash-link/node_modules/rollpkg/configs/types/global.d.ts
rpt2: ambient types changed, redoing all semantic diagnostics
rpt2: transpiling '/Users/rafael/dev/react-router-hash-link/src/index.ts'
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/code/cache/f7f0c04e781e1e31e7fd9db39d406bedbdac1adf'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/syntacticDiagnostics/cache/f7f0c04e781e1e31e7fd9db39d406bedbdac1adf'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/semanticDiagnostics/cache/f7f0c04e781e1e31e7fd9db39d406bedbdac1adf'
rpt2:     cache miss
rpt2: transpiling '/Users/rafael/dev/react-router-hash-link/src/index.ts'
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/code/cache/f7f0c04e781e1e31e7fd9db39d406bedbdac1adf'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/syntacticDiagnostics/cache/f7f0c04e781e1e31e7fd9db39d406bedbdac1adf'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/semanticDiagnostics/cache/f7f0c04e781e1e31e7fd9db39d406bedbdac1adf'
rpt2:     cache miss
rpt2: dependency '/Users/rafael/dev/react-router-hash-link/src/HashLink.jsx'
rpt2:     imported by '/Users/rafael/dev/react-router-hash-link/src/index.ts'
rpt2: resolving './HashLink' imported by '/Users/rafael/dev/react-router-hash-link/src/index.ts'
rpt2:     to '/Users/rafael/dev/react-router-hash-link/src/HashLink.jsx'
rpt2: dependency '/Users/rafael/dev/react-router-hash-link/src/HashLink.jsx'
rpt2:     imported by '/Users/rafael/dev/react-router-hash-link/src/index.ts'
rpt2: resolving './HashLink' imported by '/Users/rafael/dev/react-router-hash-link/src/index.ts'
rpt2:     to '/Users/rafael/dev/react-router-hash-link/src/HashLink.jsx'
rpt2: transpiling '/Users/rafael/dev/react-router-hash-link/src/HashLink.jsx'
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/code/cache/5f9503964a437ea32f78aefb79766c47f2089ee4'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/syntacticDiagnostics/cache/5f9503964a437ea32f78aefb79766c47f2089ee4'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/semanticDiagnostics/cache/5f9503964a437ea32f78aefb79766c47f2089ee4'
🌍 Creating esm, cjs builds
rpt2: transpiling '/Users/rafael/dev/react-router-hash-link/src/HashLink.jsx'
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/code/cache/5f9503964a437ea32f78aefb79766c47f2089ee4'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/syntacticDiagnostics/cache/5f9503964a437ea32f78aefb79766c47f2089ee4'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/semanticDiagnostics/cache/5f9503964a437ea32f78aefb79766c47f2089ee4'
rpt2:     cache miss
rpt2: transpiling '/Users/rafael/dev/react-router-hash-link/node_modules/tslib/tslib.es6.js'
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/code/cache/00b643a8eda2397d9119fe625f93d1531d1a1616'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/syntacticDiagnostics/cache/00b643a8eda2397d9119fe625f93d1531d1a1616'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/semanticDiagnostics/cache/00b643a8eda2397d9119fe625f93d1531d1a1616'
rpt2:     cache miss
✗ FAILED AT: Creating esm, cjs builds 

TypeScript Error: failed to transpile '/Users/rafael/dev/react-router-hash-link/node_modules/tslib/tslib.es6.js' 

rpt2: transpiling '/Users/rafael/dev/react-router-hash-link/node_modules/tslib/tslib.es6.js'
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/code/cache/00b643a8eda2397d9119fe625f93d1531d1a1616'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/syntacticDiagnostics/cache/00b643a8eda2397d9119fe625f93d1531d1a1616'
rpt2:     cache miss
rpt2:     cache: '/Users/rafael/dev/react-router-hash-link/node_modules/.cache/rollup-plugin-typescript2/rpt2_41e39e1ba39f2217f8bc6fb36fef2cfc9e4eafcb/semanticDiagnostics/cache/00b643a8eda2397d9119fe625f93d1531d1a1616'
rpt2:     cache miss
rpt2: rolling caches
npm ERR! code 1
npm ERR! path /Users/rafael/dev/react-router-hash-link
npm ERR! command failed
npm ERR! command sh -c rollpkg build

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/rafael/.npm/_logs/2021-03-23T17_12_01_735Z-debug.log

@ezolenko
Copy link
Owner

Surprising that there are no other errors, just failed to transpile. Usually there are typescript errors (semantic or diagnostic) printed before that, which caused typescript language service to not emit output .

@agilgur5 agilgur5 changed the title Fails to transpile tslib.es6.js Failed to transpile tslib.es6.js Jun 20, 2022
@agilgur5 agilgur5 changed the title Failed to transpile tslib.es6.js Failed to transpile tslib.es6.js after update to v0.30.0 Jun 20, 2022
@agilgur5 agilgur5 added the problem: removed issue template OP removed the issue template without good cause label Jun 24, 2022
@agilgur5
Copy link
Collaborator

agilgur5 commented Jun 28, 2022

So, I took a look at this issue and this was a doozy to figure out, but eventually got to the root cause

initial investigation

The setup is a bit complex because it happened as part of Rollpkg. It happens when tsconfig target: es5 (so tslib is needed). I was alerted to it from this issue. Rollpkg v0.5.0 has the bug, v0.5.1 fixes it by downgrading rollup-plugin-typescript2 to v0.29.0.

This took a decent bit more time & effort to investigate as this is not a minimal reproduction -- in general, a minimal repro makes it significantly easier to investigate any issue. Given that most maintainers are volunteers with severely limited time, making it as easy possible for them to investigate should be the goal.
The permalinks that you gave (and which are still available!) are still helpful that being said.

It so happens that I solo-maintained TSDX for ~1.5 years (that's how I originally became a contributor here), so reading through rollpkg's code was measuredly simpler, as they have somewhat similar layouts.

Sidebar: TSDX comparison flaws

(Also your TSDX comparison is flawed, as TSDX actually uses both TypeScript (via rpt2) and Babel (basically: ts -> esnext -> preset-env), and, again, that's how I found myself here.

Otherwise, the comparison is more or less accurate. See jaredpalmer/tsdx#634 and jaredpalmer/tsdx#635 as the two main RFCs I was pushing to get out of the configuration and compatibility hell.
size-limit was (partly) intentional though, given the various trade-offs I analyzed. One was that there's no reason that stats should be tied to the build or slow it down).

Anyway, there were two things that stood out to me initially:

  1. The error is failing to transpile tslib, which, well, shouldn't be transpiled in the first place, for a number of reasons
    • For instance, it's in node_modules and should be an external
  2. This only occurred after updating to 0.30.0
    • As I've investigated in a number of different issues, the main change there was a breaking dependency upgrade of @rollup/pluginutils to v4, which included fix(pluginutils)!: don't add cwd to absolute or patterns that start with a glob rollup/plugins#517
    • pluginutils is responsible for filtering, i.e. include and exclude in most Rollup plugins' options.
    • Can read Is it possible to make this plugin transpile files from outside the root of the package (f. ex. in a monorepo setup)? #216 (comment) and linked comments for more details, but v4 removed the process.cwd() that was added in front of any glob patterns given to it
    • Which means that files outside of the project dir could now be included without changing the default settings. So this change ended up unintentionally solving lots of monorepo issues. And also caused this issue, as it means things like node_modules can also be included by default.
    • This is most plugins' default too, and is normally not an issue. Especially as unbundled deps get listed out in externals, and because rpt2's default include only has TS files, which are not often present and not meant to be import'd from node_modules

You can probably see where I'm going from here, but therein lies the problem.

root cause analysis

rollpkg's tsconfig sets allowJs: true and sets rpt2's include to also process JS files.

Notably, what's missing is a changed exclude. rpt2's docs do point out that you probably want to add node_modules to your exclude if you're setting allowJs and includeing JS files.

(Your external configuration is also a bit problematic in that it'll miss submodule deps, similar to stevenbenisek/rollup-plugin-auto-external#16. I personally use rollup-plugin-node-externals, which doesn't have this issue)

So, with that, the problem becomes a lot more straightforward. HashLink.jsx gets processed by rpt2 (logged on this line) and it returns this code at the top of the file:

import { __rest } from "tslib";
import React from "react";
import PropTypes from "prop-types";
import { Link, NavLink } from "react-router-dom";

Note, of course, the presence of tslib.

So when rpt2 gives this ESM code to Rollup, it parses it and tries to resolve, and if configured to do so, transform, all the imports.
Given the lack of tslib in your deps, this means that rollpkg doesn't add it to your externals list, meaning that tslib ends up getting processed by your Rollup plugins.
And, given the lack of exclude, that means rpt2 tries processing tslib.

So the solution therein is to add tslib to your deps. You probably also want to add node_modules to rollpkg's rpt2's plugin options exclude. The specific glob that worked for me during testing was exclude: ['**/node_modules/**/*'].

what about the lacking error though?

Surprising that there are no other errors, just failed to transpile. Usually there are typescript errors (semantic or diagnostic) printed before that, which caused typescript language service to not emit output .

I dug a bit more to really understand this though, in particular as the lack of syntactic or semantic errors is still pretty strange. This is where things start to get complicated... especially as we get into the lacking TS Compiler docs 😕

The failed to transpile error message means that rpt2 hit what it currently considers a fatal error somewhere. This results in TS skipping emit of files.

Normally, this is caused either by a compiler option error (i.e. tsconfig configuration issue) or a syntactic or semantic error (i.e. type-checking issue). The fact that neither was printed out in this case is strange, and often indicative of a bug.

I did some logging and that did not make things any less confusing, unfortunately...

emitSkipped and no files, but id clearly exists:

rpt2: transpiling '/rpt2-issue-264/node_modules/tslib/tslib.es6.js'
{
  outputFiles: [],
  emitSkipped: true,
  diagnostics: [],
  exportedModulesFromDeclarationEmit: undefined
}

no semantic or syntactic errors (which is to be expected, given that this is compiled tslib helper code):

[]
[]

snapshot exists and is correct (matches the exact source code of tslib.es6.js):

StringScriptSnapshot {
  text: '/*! *****************************************************************************\r\n' +
    'Copyright (c) Microsoft Corporation.\r\n' +
    '....'
}

So that's odd. I've never seen emitSkipped in a scenario like this (and I don't think ezolenko has either).

figuring out emitSkipped

So I decided to look into emitSkipped in more detail.

Unfortunately, as usual, the TS Compiler API Docs don't elaborate in any way on this. It's just used in 2 examples there, and that's what most TS Compiler integrations base their implementation on, including rpt2. Based on that example, I didn't see anything strange about rpt2's usage (which I've already read through dozens of times too).

So I did some more searching about emitSkipped. I stumbled upon this issue in ts-node: TypeStrong/ts-node#693 . That happened to get some explanatory comments on it literally yesterday. Per that comment, it turns out this a rootDir issue.

From the TSConfig Reference on rootDir:

Note that TypeScript will never write an output file to a directory outside of outDir, and will never skip emitting a file. For this reason, rootDir also enforces that all files which need to be emitted are underneath the rootDir path.

So, it turns out (basically through reverse-engineering as the TS Compiler Docs don't remotely go into this), that a compiled file will have emitSkipped set when that file is outside of the rootDir.

And indeed, rollpkg (similarly to TSDX), sets a default rootDir of ./src.
./node_modules/tslib/tslib.es6.js is clearly outside of ./src and so outside of your rootDir and hence its emit gets skipped.

But normally a rootDir issue will throw a compiler options error (c.f. jaredpalmer/tsdx#638 (comment)), such as:

rpt2: options error TS6059: File '/project/test/testUtils.ts' is not under 'rootDir' '/project/src'. 'rootDir' is expected to contain all source files.

But it doesn't here.

Well that's because TS doesn't know what all the files are ahead-of-time.
tsc only reads the tsconfig include and bases it off that. But with Rollup and plugins, your files get transformed along the way.
In this case, the tslib import was added during compilation (wasn't there before) and then the lack of external and plugin exclude meant that tslib got passed to rpt2.
So the compiler, at run-time, is given a file outside of rootDir that it didn't know about beforehand. There's no compiler options error as this is after parsing the compiler opts and not expected based on the tsconfig.json. So the compiler just returns an empty file with emitSkipped .... which apparently can indicate that there's a previously undetected rootDir issue that isn't documented in the TS Compiler API docs.

Root cause found.

next steps

For @rafgraph , the next steps are fairly straightforward, add tslib to deps in react-router-hash-link, and, ideally, exclude: ['**/node_modules/**/*'] in rollpkg when it configures rpt2's plugin options. Could also add tslib manually to externals in rollpkg. (maybe modify the TSDX comparison section too 😉 )

For rpt2, the next steps are more opaque. This is the only time this issue has occurred too, so it's pretty rare.

ts-node addressed this in an intriguing way in TypeStrong/ts-node#1629 which implements TypeStrong/ts-node#1345. Basically, when emitSkipped, ts-node will switch to the simpler transpileModule API, which just does TS -> JS with no type-checking (i.e. similar to Babel and isolatedModules).

I'm not sure if that is ideal behavior for rpt2 though, which does not have as general a use-case as ts-node.
rpt2 is only meant to compile projects (not arbitrary code, which is one of ts-node's capabilities and purposes) and so should respect tsconfig.json as much as possible within the constraints of Rollup semantics.

This does hit a Rollup boundary, but I think in this case, throwing a rootDir compiler options error would be the most accurate behavior and is closest to what tsc would do, which we try to follow to aim for the "principle of least surprise".

I pasted the text of the rootDir error above, which we could copy+paste, but ideally, we should pull that from the TS API somewhere, which would also make it more resilient to error code / error message changes.

The one caveat is that given that emitSkipped is mostly undocumented, it's difficult to tell if there are other scenarios where emitSkipped would be hit but there are no syntactic or semantic errors. The only other one I've heard of so far (have not confirmed) is when TS skips emit instead of overwriting an existing file, which is usually only hit if allowJs and no outDir.
(I also checked the TS source code references to emitSkipped and that did not help my understanding much... there's only a dozen or so references in the source though (not including tests etc), that being said).

So what we could do is, if emitSkipped and no diagnostics, check the id of the file currently being processed (i.e. its path) against the rootDir, which we have access to. If it's not within rootDir, we could conclude that it is indeed a rootDir issue, and throw the rootDir error. Basically re-implementing some simple TS logic.
Otherwise, we leave it as just failed to transpile, as it would therefore be an unknown error (as in, if it is none of syntactic, semantic, or rootDir error).

Low priority given the rarity of the issue and that this change just improves DX (it's not a bugfix in that sense, more a feature), but, that being said, it should be fairly simple to implement.

@agilgur5 agilgur5 added solution: invalid This doesn't seem right kind: support Asking for support with something or a specific use case topic: TS Compiler API Docs Related to the severely lacking TS Compiler API Docs labels Jun 28, 2022
@agilgur5 agilgur5 changed the title Failed to transpile tslib.es6.js after update to v0.30.0 failed to transpile tslib.es6.js after update to v0.30.0 Jun 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: support Asking for support with something or a specific use case problem: removed issue template OP removed the issue template without good cause solution: invalid This doesn't seem right topic: TS Compiler API Docs Related to the severely lacking TS Compiler API Docs
Projects
None yet
Development

No branches or pull requests

3 participants