Anton Gilgur 61d78bd2f3
test: add initial integration test suite (#371)
* 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
2022-07-05 22:14:33 -06:00
2022-06-06 17:59:45 -06:00
2017-06-21 22:33:55 -06:00
2017-02-01 21:02:22 -07:00
2020-08-07 12:04:35 -06:00
2017-10-24 10:08:16 -06:00
2020-10-02 10:49:00 -06:00
2017-10-24 10:08:16 -06:00

rollup-plugin-typescript2

npm-version npm-monthly-downloads Node.js CI

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: false
  • importHelpers: true
  • noResolve: false
  • noEmit: false (Rollup controls emit)
  • noEmitOnError: false (Rollup controls emit. See #254 and the abortOnError plugin option below)
  • inlineSourceMap: false (see #71)
  • outDir: ./placeholder in cache root (see #83 and Microsoft/TypeScript#24715)
  • declarationDir: Rollup's output.file or output.dir (unless useTsconfigDeclarationDir is true in the plugin options)
  • moduleResolution: node (classic is deprecated. It also breaks this plugin, see #12 and #14)
  • allowNonTsExtensions: true to let other plugins on the chain generate typescript; update plugin's include filter to pick them up (see #111)

Some compiler options have more than one compatible value

  • module: defaults to ES2015. Other valid values are ES2020 and ESNext (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's include option to add "*.js+(|x)", "**/*.js+(|x)" (might also want to exclude "**/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: string

    The current working directory. Defaults to process.cwd().

  • tsconfigDefaults: {}

    The object passed as tsconfigDefaults will be merged with the loaded tsconfig.json. The final config passed to TypeScript will be the result of values in tsconfigDefaults replaced by values in the loaded tsconfig.json, replaced by values in tsconfigOverride, and then replaced by forced compilerOptions overrides 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.json file (tsconfigs can themselves be chained with extends, 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 verbosity to 3 and look for parsed tsconfig if you get something unexpected.

  • tsconfig: undefined

    Path to tsconfig.json. Set this if your tsconfig has 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: true

    Set to false to avoid doing any diagnostic checks on the code.

  • verbosity: 1

    • 0 -- Error
    • 1 -- Warning
    • 2 -- Info
    • 3 -- Debug
  • clean: false

    Set to true for clean build (wipes out cache on every build).

  • cacheRoot: node_modules/.cache/rollup-plugin-typescript2

    Path 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: true

    Bail 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: false

    Deprecated. OS native paths are now always used since 0.30.0 (see #251), so this no longer has any effect -- as if it is always true.

  • objectHashIgnoreUnknownHack: false

    The plugin uses your Rollup config as part of its cache key. object-hash is used to generate a hash, but it can have trouble with some uncommon types of elements. Setting this option to true will make object-hash ignore 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 with clean: true once in a while and definitely before a release. (See #105 and #203)

  • useTsconfigDeclarationDir: false

    If true, declaration files will be emitted in the declarationDir given in the tsconfig. 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: peerDependency

    If 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: undefined

    experimental, TypeScript 2.4.1+

    Transformers will likely be available in tsconfig eventually, 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

Description
Rollup plugin for typescript with compiler errors.
Readme MIT 21 MiB
Languages
TypeScript 96.9%
JavaScript 3.1%