plugins icon indicating copy to clipboard operation
plugins copied to clipboard

Typescript plugin behaves differently depending on whether the `include` option is a string or a regular expression

Open ericmorand opened this issue 2 years ago • 1 comments

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 include option 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 include option is a string, the test function is constructed by the createFilter method based on the passed include value 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 .ts and 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.

ericmorand avatar Dec 14 '23 19:12 ericmorand

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;
    });
}

ericmorand avatar Dec 24 '23 11:12 ericmorand