Typescript plugin behaves differently depending on whether the `include` option is a string or a regular expression
This is a follow-up to #1650.
Rollup Plugin Name: @rollup/plugin-typescript Rollup Plugin Version: 11.1.5 Rollup Version: 4.9.0 Operating System (or Browser): Ubuntu Node Version: 16.20 Link to reproduction: https://github.com/ericmorand/rollup-plugin-typescript-issue
Expected Behavior
Passing a regular expression or a string representation of the regular expression should gives the same result.
Said differently, passing /\.ts$/ or './ts$' should gives the same result.
Actual Behavior
After investigating on #1650, I discovered that the Typescript plugin behaves differently depending on whether the include option is a string or a regular expression:
- If the
includeoption is a regular expression, the regular expression is used as-is to test the module id received by the plugin in order to decide if the plugin must or must not handle it - If the
includeoption is a string, the test function is constructed by thecreateFiltermethod based on the passedincludevalue and the current working directory
Hence:
- Passing
/\.ts$/would match every file that ends with.ts - Passing
'.ts$'would only match files that ends with.tsand are located in the current working directory
Which is unexpected as both are strictly identical from the point of view of picomatch.
I think that either the bug should be fixed, or the documentation of the plugin should clearly express the difference of behaviour instead of just saying:
A picomatch pattern, or array of patterns, which specifies the files in the build the plugin should operate on. By default all .ts and .tsx files are targeted.
Actually, it seems to come from @rollup/pluginutils itself:
https://github.com/rollup/plugins/blob/33174f956304ab4aad4bbaba656f627c31679dc5/packages/pluginutils/src/createFilter.ts#L30
There, the createFilter method behaves differently depending on the type of the pattern: if it is a regular expression, it is used as-is; if it is a string, a regular expression is created from it and the current working directory, hence preventing plugins to handle files located outside of the working directory.
Is this a deliberate move or a bug? If it is a deliberate move, what is the rational?
For information, it forces plugin developers to transform the passed options to regular expressions to make sure that their plugin works in every situation, for example my own TypeScript plugin:
options.include = options.include || /\.(cts|mts|ts|tsx)$/;
if (typeof options.include === "string") {
options.include = [options.include];
}
if (Array.isArray(options.include)) {
options.include = options.include.map((include) => {
if (typeof include === "string") {
return new RegExp(include);
}
return include;
});
}