Using together with Babel plugins and `emitDeclarationOnly` overwrites output files with no content
See original GitHub issueHey, thanks for this great plugin. Always use it but this time I have to compile the code with babel and just use this for declarations and it doesn’t work for that.
What happens and why it is wrong
Environment
Using babel to compile files since I need to run code through a plugin:
babel({ extensions, babelHelpers: 'bundled', exclude: 'node_modules/**' }),
typescript(),
Tried setting emitDeclarationOnly
in tsconfig.json
and above e.g.:
typescript({
tsconfigOverride: {
compilerOptions: {
emitDeclarationOnly: true,
},
},
})
Also tried putting typescript()
before babel()
and it still somehow overrides the output files.
Versions
rollup: ^2.45.2 => 2.45.2
rollup-plugin-typescript2: ^0.30.0 => 0.30.0
typescript: ^4.2.4 => 4.2.4
rollup.config.js
/* eslint-env node */
import replace from '@rollup/plugin-replace'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import { babel } from '@rollup/plugin-babel'
import { terser } from 'rollup-plugin-terser'
import minifyHTML from 'rollup-plugin-minify-html-literals'
import typescript from 'rollup-plugin-typescript2'
const globals = {}
const external = Object.keys(globals)
const isProd = process.env.NODE_ENV === 'production'
const extensions = ['.js', '.jsx', '.ts', '.tsx']
const output = [
{
file: 'dist/index.js',
format: 'esm',
globals,
},
]
if (isProd) {
output.push({
name: 'myAppName',
file: 'dist/index.umd.js',
format: 'umd',
globals,
})
}
export default {
input: 'src/index.ts',
output,
external,
plugins: [
minifyHTML(),
replace({
preventAssignment: true,
values: {
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
},
}),
commonjs(),
nodeResolve({
extensions,
browser: true,
}),
babel({ extensions, babelHelpers: 'bundled', exclude: 'node_modules/**' }),
typescript({
tsconfigOverride: {
compilerOptions: {
emitDeclarationOnly: true,
},
},
}),
process.env.NODE_ENV === 'production' &&
terser({
module: true,
output: {
comments: false,
},
}),
],
}
#### .babelrc.json
{
"presets": ["@babel/preset-typescript", "babel-preset-solid"]
}
tsconfig.json
{
"compilerOptions": {
"target": "es2018",
"module": "esnext",
"lib": ["es2018", "dom", "dom.iterable"],
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"emitDeclarationOnly": true,
"esModuleInterop": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"jsx": "preserve",
"jsxImportSource": "solid-js"
},
"include": ["src"],
"exclude": ["node_modules"]
}
plugin output with verbosity 3
plugin output with verbosity 3:
src/index.ts → dist/index.js, dist/index.umd.js...
rpt2: built-in options overrides: {
"noEmitHelpers": false,
"importHelpers": true,
"noResolve": false,
"noEmit": false,
"inlineSourceMap": false,
"outDir": "/Users/infensus/Projects/lightfin/packages/core/node_modules/.cache/rollup-plugin-typescript2/placeholder",
"moduleResolution": 2,
"allowNonTsExtensions": true
}
rpt2: parsed tsconfig: {
"options": {
"target": 5,
"module": 99,
"lib": [
"lib.es2018.d.ts",
"lib.dom.d.ts",
"lib.dom.iterable.d.ts"
],
"declaration": true,
"outDir": "/Users/infensus/Projects/lightfin/packages/core/node_modules/.cache/rollup-plugin-typescript2/placeholder",
"rootDir": "/Users/infensus/Projects/lightfin/packages/core/src",
"strict": true,
"emitDeclarationOnly": true,
"esModuleInterop": true,
"moduleResolution": 2,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"jsx": 1,
"jsxImportSource": "solid-js",
"configFilePath": "/Users/infensus/Projects/lightfin/packages/core/tsconfig.json",
"noEmitHelpers": false,
"importHelpers": true,
"noResolve": false,
"noEmit": false,
"inlineSourceMap": false,
"allowNonTsExtensions": true
},
"fileNames": [
"/Users/infensus/Projects/lightfin/packages/core/src/index.ts",
"/Users/infensus/Projects/lightfin/packages/core/src/components/grid.tsx",
"/Users/infensus/Projects/lightfin/packages/core/src/components/index.ts",
"/Users/infensus/Projects/lightfin/packages/core/src/components/registerGridElements.ts",
"/Users/infensus/Projects/lightfin/packages/core/src/utils/css.ts",
"/Users/infensus/Projects/lightfin/packages/core/src/utils/index.ts"
],
"typeAcquisition": {
"enable": false,
"include": [],
"exclude": []
},
"raw": {
"compilerOptions": {
"target": "es2018",
"module": "esnext",
"lib": [
"es2018",
"dom",
"dom.iterable"
],
"declaration": true,
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"emitDeclarationOnly": true,
"esModuleInterop": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"jsx": "preserve",
"jsxImportSource": "solid-js"
},
"include": [
"src"
],
"exclude": [
"node_modules"
],
"compileOnSave": false
},
"errors": [],
"wildcardDirectories": {
"/users/infensus/projects/lightfin/packages/core/src": 1
},
"compileOnSave": false
}
rpt2: typescript version: 4.2.4
rpt2: tslib version: 2.1.0
rpt2: rollup version: 2.45.2
rpt2: rollup-plugin-typescript2 version: 0.30.0
rpt2: plugin options:
{
"verbosity": 3,
"tsconfigOverride": {
"compilerOptions": {
"emitDeclarationOnly": true
}
},
"check": true,
"clean": false,
"cacheRoot": "/Users/infensus/Projects/lightfin/packages/core/node_modules/.cache/rollup-plugin-typescript2",
"include": [
"*.ts+(|x)",
"**/*.ts+(|x)"
],
"exclude": [
"*.d.ts",
"**/*.d.ts"
],
"abortOnError": true,
"rollupCommonJSResolveHack": false,
"useTsconfigDeclarationDir": false,
"transformers": [],
"tsconfigDefaults": {},
"objectHashIgnoreUnknownHack": false,
"cwd": "/Users/infensus/Projects/lightfin/packages/core",
"typescript": "version 4.2.4"
}
rpt2: rollup config:
{
"external": [],
"input": "src/index.ts",
"plugins": [
{
"name": "minify-html-literals"
},
{
"name": "replace"
},
{
"name": "commonjs"
},
{
"name": "node-resolve"
},
{
"name": "babel"
},
{
"name": "rpt2"
},
{
"name": "terser"
},
{
"name": "stdin"
}
],
"output": [
{
"file": "dist/index.js",
"format": "esm",
"globals": {},
"plugins": []
},
{
"file": "dist/index.umd.js",
"format": "umd",
"globals": {},
"name": "lightfin",
"plugins": []
}
]
}
rpt2: tsconfig path: /Users/infensus/Projects/lightfin/packages/core/tsconfig.json
rpt2: included:
[
"*.ts+(|x)",
"**/*.ts+(|x)"
]
rpt2: excluded:
[
"*.d.ts",
"**/*.d.ts"
]
dist/index.js
becomes empty if typescript plugin is loaded and dist/index.umd.js
just has a stub - var e;e=function(){},"function"==typeof define&&define.amd&&define(e);
Thanks!
Issue Analytics
- State:
- Created 2 years ago
- Reactions:9
- Comments:8 (1 by maintainers)
Top Results From Across the Web
Options - Babel
Placement: Allowed in Babel's programmatic options, or inside of the loaded configFile . A programmatic option will override a config file one. By...
Read more >TSConfig Reference - Docs on every TSConfig option
Intro to the TSConfig Reference. A TSConfig file in a directory indicates that the directory is the root of a TypeScript or JavaScript...
Read more >@rollup/plugin-typescript - npm
A picomatch pattern, or array of patterns, which specifies the files in the build the plugin should ignore. By default no files are...
Read more >Codemods with Babel Plugins - Egghead.io
We want to use vanilla Babel to write a custom plugin that will transform our code ... Egghead is no longer just for...
Read more >rollup-plugin-ts | Yarn - Package Manager
A TypeScript Rollup plugin that bundles declarations, respects Browserslists, and enables seamless integration with transpilers such as babel and swc.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Doesnt Work for me either with babel 7
Output:
root cause analysis
So I dug a bit more into this and found an interesting result when logging out
output
from this line while havingemitDeclarationOnly
set:Some key pieces:
declaration: true
anddeclarationMap: true
, respectively), but notably there is no JS code returned from the TS Compiler (theLanguageService
API’sgetEmitOutput
method, to be specific). This is whyemitDeclarationOnly
causes an empty chunk with “no content” to be returned to Rollup (and subsequent plugins).emitSkipped
is false. This is an important difference from #338, as if it weretrue
, rpt2 would error out instead (this what is used to determine if a fatal error occurred).feature incoming!
Changing the code to instead
return undefined
in the case ofemitDeclarationOnly
will allow other plugins on the chain to process/transform/compile the TS. So there is indeed a missing feature needed to supportemitDeclarationOnly
! (note that rpt2 was used before theemitDeclarationOnly
compilerOption
even existed)I wrote up the code for this and already tested it and confirmed that is working! It’s actually a very small feature that opens up quite a bit of new use-cases (which is why I wanted to prioritize it after joining on as a maintainer!) 🙂
For instance, you can use with Babel as mentioned here, but also with other tools that can compile TS like ESBuild and
swc
etc. So rpt2 does the type-checking and declaration generation, while Babel (with its various plugins, such asbabel-plugin-typescript-to-proptypes
as the use-case downstream in TSDX asks for) or others do the TS -> JS compilation (or JS -> JS transpilation whenallowJs
). Note that rpt2 will have to come before those plugins in the chain (as I mentioned 2 comments above), so that it actually reads TS and produces declarations based on source TS and not compiled JS that is lacking types.I’ll have a PR out for this tomorrow (heading to bed now) 🚀 EDIT: see #366