* test: add initial integration test harness
- some additional ts-jest config is needed to parse `index.ts`
- since Rollup isn't used when importing files during testing, we need to enable `esModuleInterop`
- the import of `findCacheDir` was immediately erroring without this (and maybe more, but `esModuleInterop` made the import work)
- add `tsconfig.test.json` for this purpose
- use `ts-jest` JSDoc types to get types for the ts-jest config as well
- add an integration/ dir in the __tests__/ dir for all integration tests
- add a fixtures/ dir in there as well for integration test fixtures
- add a `tsconfig.json` for all fixtures to use
- basically so that rpt2 source code is not `include`d, though also bc this may be good to customize for fixtures
- add a simple fixture with "no-errors" that does an import and a type-only import
- add a simple integration test that just ensures that all files are part of the bundle
- the bundled `index` file and each file's declaration and declaration map
- and no _other_ files!
- for Rollup, need to use paths relative to the root of the whole project
- probably because that is `cwd` when running `jest` from root
- will probably abstract out helpers here in the future as the test suite grows
- 70% coverage of `index.ts` with just this one test!
- update CONTRIBUTING.md now that an integration test exists
* refactor: use `local` func for path resolution
- similar to the unit test suite
- also remove the `.only` that I was using during development
* add comparison test for cache / no cache
- should probably do this for each integration test suite
- refactor: split out a `genBundle` func to DRY things up
- this was bound to happen eventually
- don't think testing other output formats is necessary since we don't have any specific logic for that, so that is just Rollup behavior
- take `input` path and rpt2 options as params
- and add the `tsconfig` as a default
- add a hacky workaround so that Rollup doesn't output a bunch of warnings in the logs
- format: use double quotes for strings consistently (my bad, I normally use single quotes in my own repos)
* refactor: use a temp cacheRoot
- so we can clean it up after testing to ensure consistency
- and so we're not filling up the cache in `node_modules` with testing caches
- also add a comment to one the of the tests
* test: check w/ and w/o declarations + declaration maps
- make sure they don't get output when not asked for
* fix(test): actually test the cache
- `clean: true` also means that no cache is created
- which is a bit confusing naming, but was requested by a few users and implemented in f15cb84dcc99a0bd20f3afce101c0991683010b6
- so have to create the bundle one _more_ time to create the cache
- note that `tscache`'s `getCached` and `isDirty` functions are now actually covered in the coverage report
* fix(ci): increase integration test timeout
- double it bc it was occassionally failing on CI due to timeouts
* test: ensure that JS files are part of bundle too
- ensures that TS understands the JS w/ DTS w/o error
- and that rpt2 filters out JS while Rollup still resolves it on its own (since Rollup understands ESM)
- similar to testing w/ a different plugin (i.e. literally testing an "integration"), but this is native Rollup behavior in this case where it doesn't need a plugin to understand ESM
- also the first test of actual code contents
- reformat the cache test a bit into its own block since we now have ~3 different sets of tests in the suite
* optim(test): don't need to check cache each time
- this doesn't test a new code path and the first test already tests the entire bundle for the fixture, so the other tests just repeat that
* test: add initial error checking integration tests
- refactor: rename `integration/index.spec` -> `integration/no-errors.spec`
- refactor: split `genBundle` func out into a helper file to be used by multiple integration test suites
- simplify the `genBundle` within `no-errors` as such
- create new `errors` fixture just with some simple code that doesn't type-check for now
- add test to check that the exact semantic error pops up
- and it even tests colors 😮 ...though I was confused for some time why the strings weren't matching... 😐
- add test to make sure it doesn't pop up when `check: false` or `abortOnError: false`
- when `abortOnError: false`, detect that a warning is created instead
- due to the new `errors` dir in the fixtures dir, the fixtures `tsconfig` now picks up two dirs
- which changes the `rootDir` etc
- so create two tiny `tsconfig`s in both fixture dirs that just extend that one
- and now tests all run simiarly to before
* fix(ci): increase integration test `errors` timeout
- this too timed out, probably due to the checks that _don't_ error
* optim(test): split non-erroring error tests into a different suite
- so that Jest can parallelize these
- CI was timing out on this, so splitting it out should help as it'll be 10s each
* fix(ci): bump integration test timeout to 15s
- bc it was still timing out in some cases 😕
- this time the `no-errors` suite was timing out, so just increase all around
* fix(test): output a `.js` bundle, not `.ts`
- woooops... was wondering why it was `.ts`; turns out because I wrote the `output.file` setting that way 😅 😅 😅
- also add a missing comment in errors for consistency
- and put code checks _after_ file structure checks, since that's a deeper check
* test: check that `emitDeclarationOnly` works as expected
- should output declaration and declaration map for file
- code + declaration should contain the one-line function
- code _shouldn't_ contain anything from TS files
- since this is plain ESM code, we don't need another plugin to process this
- nice workaround to installing another plugin that I hadn't thought of till now!
* test: add a syntactic error, refactor a bit
- add a file to `errors` with a syntax error in it
- apparently this does throw syntax err, but does not cause `emitSkipped: true`... odd...
- so may need another test for that...
- `abortOnError: false` / `check: false` both cause Rollup to error out instead
- rename `errors/index` -> `errors/semantic` since we have different kinds now
- change the `include` to only take a single file, so that we don't unnecessarily generate declarations or type-check other error files
- refactor(test): rewrite `genBundle` in both files to take a relative path to a file
- simplifies the `emitDeclarationOnly` test as we can now just reuse the local `genBundle` instead of calling `helpers.genBundle` directly
- use the same structure for `errors`'s different files as well
- refactor(test): split `errors.spec` into `tsconfig` errors, semantic errors, and syntactic errors (for now)
- add a slightly hacky workaround to get `fs.remove` to not error
- seems to be a race condition due to the thrown errors and file handles not being closed immediately on throw (seems like they close during garbage collection instead?)
- see linked issue in the comment; workaround is to just give it some more time
- not sure that there is a true fix for this, since an improper close may cause indeterminate behavior
* fix(test): normalize as arguments to `include`
- got a Windows error in CI for the `errors` test suite
rollup-plugin-typescript2
Rollup plugin for typescript with compiler errors.
This is a rewrite of the original rollup-plugin-typescript, starting and borrowing from this fork.
This version is somewhat slower than the original, but it will print out TypeScript syntactic and semantic diagnostic messages (the main reason for using TypeScript after all).
Installation
# with npm
npm install rollup-plugin-typescript2 typescript tslib --save-dev
# with yarn
yarn add rollup-plugin-typescript2 typescript tslib --dev
Usage
// rollup.config.js
import typescript from 'rollup-plugin-typescript2';
export default {
input: './main.ts',
plugins: [
typescript(/*{ plugin options }*/)
]
}
This plugin inherits all compiler options and file lists from your tsconfig.json file.
If your tsconfig has another name or another relative path from the root directory, see tsconfigDefaults, tsconfig, and tsconfigOverride options below.
This also allows for passing in different tsconfig files depending on your build target.
Some compiler options are forced
noEmitHelpers: falseimportHelpers: truenoResolve: falsenoEmit: false (Rollup controls emit)noEmitOnError: false (Rollup controls emit. See #254 and theabortOnErrorplugin option below)inlineSourceMap: false (see #71)outDir:./placeholderin cache root (see #83 and Microsoft/TypeScript#24715)declarationDir: Rollup'soutput.fileoroutput.dir(unlessuseTsconfigDeclarationDiris true in the plugin options)moduleResolution:node(classicis deprecated. It also breaks this plugin, see #12 and #14)allowNonTsExtensions: true to let other plugins on the chain generate typescript; update plugin'sincludefilter to pick them up (see #111)
Some compiler options have more than one compatible value
module: defaults toES2015. Other valid values areES2020andESNext(required for dynamic imports, see #54).
Some options need additional configuration on plugin side
allowJs: lets TypeScript process JS files as well. If you use it, modify this plugin'sincludeoption to add"*.js+(|x)", "**/*.js+(|x)"(might also want toexclude"**/node_modules/**/*", as it can slow down the build significantly).
Compatibility
@rollup/plugin-node-resolve
Must be before rollup-plugin-typescript2 in the plugin list, especially when the browser: true option is used (see #66).
@rollup/plugin-commonjs
See the explanation for rollupCommonJSResolveHack option below.
@rollup/plugin-babel
This plugin transpiles code, but doesn't change file extensions. @rollup/plugin-babel only looks at code with these extensions by default: .js,.jsx,.es6,.es,.mjs. To workaround this, add .ts and .tsx to its list of extensions.
// ...
import { DEFAULT_EXTENSIONS } from '@babel/core';
// ...
babel({
extensions: [
...DEFAULT_EXTENSIONS,
'.ts',
'.tsx'
]
}),
// ...
See #108
Plugin options
-
cwd:stringThe current working directory. Defaults to
process.cwd(). -
tsconfigDefaults:{}The object passed as
tsconfigDefaultswill be merged with the loadedtsconfig.json. The final config passed to TypeScript will be the result of values intsconfigDefaultsreplaced by values in the loadedtsconfig.json, replaced by values intsconfigOverride, and then replaced by forcedcompilerOptionsoverrides on top of that (see above).For simplicity and other tools' sake, try to minimize the usage of defaults and overrides and keep everything in a
tsconfig.jsonfile (tsconfigs can themselves be chained withextends, so save some turtles).let defaults = { compilerOptions: { declaration: true } }; let override = { compilerOptions: { declaration: false } }; // ... plugins: [ typescript({ tsconfigDefaults: defaults, tsconfig: "tsconfig.json", tsconfigOverride: override }) ]This is a deep merge: objects are merged, arrays are merged by index, primitives are replaced, etc. Increase
verbosityto3and look forparsed tsconfigif you get something unexpected. -
tsconfig:undefinedPath to
tsconfig.json. Set this if yourtsconfighas another name or relative location from the project directory.By default, will try to load
./tsconfig.json, but will not fail if the file is missing, unless the value is explicitly set. -
tsconfigOverride:{}See
tsconfigDefaults. -
check: trueSet to false to avoid doing any diagnostic checks on the code.
-
verbosity: 1- 0 -- Error
- 1 -- Warning
- 2 -- Info
- 3 -- Debug
-
clean: falseSet to true for clean build (wipes out cache on every build).
-
cacheRoot:node_modules/.cache/rollup-plugin-typescript2Path to cache. Defaults to a folder in node_modules.
-
include:[ "*.ts+(|x)", "**/*.ts+(|x)" ]By default passes all .ts files through typescript compiler.
-
exclude:[ "*.d.ts", "**/*.d.ts" ]But excludes type definitions.
-
abortOnError: trueBail out on first syntactic or semantic error. In some cases, setting this to false will result in an exception in Rollup itself (for example, unresolvable imports).
-
rollupCommonJSResolveHack: falseDeprecated. OS native paths are now always used since
0.30.0(see #251), so this no longer has any effect -- as if it is alwaystrue. -
objectHashIgnoreUnknownHack: falseThe plugin uses your Rollup config as part of its cache key.
object-hashis used to generate a hash, but it can have trouble with some uncommon types of elements. Setting this option to true will makeobject-hashignore unknowns, at the cost of not invalidating the cache if ignored elements are changed.Only enable this option if you need it (e.g. if you get
Error: Unknown object type "xxx") and make sure to run withclean: trueonce in a while and definitely before a release. (See #105 and #203) -
useTsconfigDeclarationDir: falseIf true, declaration files will be emitted in the
declarationDirgiven in thetsconfig. If false, declaration files will be placed inside the destination directory given in the Rollup configuration.Set to false if any other Rollup plugins need access to declaration files.
-
typescript: peerDependencyIf you'd like to use a different version of TS than the peerDependency, you can import a different TypeScript module and pass it in as
typescript: require("path/to/other/typescript").Must be TS 2.0+; things might break if the compiler interfaces changed enough from what the plugin was built against.
-
transformers:undefinedexperimental, TypeScript 2.4.1+
Transformers will likely be available in
tsconfigeventually, so this is not a stable interface (see Microsoft/TypeScript#14419).For example, integrating kimamula/ts-transformer-keys:
const keysTransformer = require('ts-transformer-keys/transformer').default; const transformer = (service) => ({ before: [ keysTransformer(service.getProgram()) ], after: [] }); // ... plugins: [ typescript({ transformers: [transformer] }) ]
Declarations
This plugin respects declaration: true in your tsconfig.json file.
When set, it will emit *.d.ts files for your bundle.
The resulting file(s) can then be used with the types property in your package.json file as described here.
By default, the declaration files will be located in the same directory as the generated Rollup bundle.
If you want to override this behavior and instead use declarationDir, set useTsconfigDeclarationDir: true in the plugin options.
The above also applies to declarationMap: true and *.d.ts.map files for your bundle.
This plugin also respects emitDeclarationOnly: true and will only emit declarations (and declaration maps, if enabled) if set in your tsconfig.json.
If you use emitDeclarationOnly, you will need another plugin to compile any TypeScript sources, such as @rollup/plugin-babel, rollup-plugin-esbuild, rollup-plugin-swc, etc.
When composing Rollup plugins this way, rollup-plugin-typescript2 will perform type-checking and declaration generation, while another plugin performs the TypeScript to JavaScript compilation.
Some scenarios where this can be particularly useful: you want to use Babel plugins on TypeScript source, or you want declarations and type-checking for your Vite builds (NOTE: this space has not been fully explored yet).
Watch mode
The way TypeScript handles type-only imports and ambient types effectively hides them from Rollup's watch mode, because import statements are not generated and changing them doesn't trigger a rebuild.
Otherwise the plugin should work in watch mode. Make sure to run a normal build after watch session to catch any type errors.
Requirements
- TypeScript
2.4+ - Rollup
1.26.3+ - Node
6.4.0+(basic ES6 support)
Reporting bugs and Contributing
See CONTRIBUTING.md