Looks like currently we can define just one transform script for specified file type. It would be nice to be able to define more than one.
When we use ts-jest for typescript files, we cannot define second transform script that will do some extra stuff for us.
"transform": {
"\\.(ts)$": "<rootDir>/myTransformer.js",
"^.+\\.ts$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
So I would like to define myTransformer.js that will preprocess typescript files before ts-jest do this.
As an alternative, you could call ts-jest from the transformer script to combine both transforms into one.
I have a similar use case. My front-end JS interpolates some configuration information from the back-end Rails app. I want Jest to transform foo.js.erb first with ERB, and then with Babel.
At the moment, I have one custom transform that first calls the ERB transformer and then Babel transformer directly, but it doesn't seem very DRY to have to do that.
I don't think it makes sense for us to compose this for you, so I'm inclined to say what @jeysal suggests is the correct solution - compose them yourself. Stitching things together yourself seems like a safer solution without the possibility of messing up, and way easier to debug if things are behaving oddly. Relying on insertion order in the object is not something we want to do - the config gets serialized and deserialized all the time. Having 2 regexes match the same file works _now_, but that's an implementation detail you shouldn't care about. Assigning semantic meaning seems suboptimal to me.
Example of using a custom transformer together with babel-jest:
import { createHash } from 'crypto';
import babelJest = require('babel-jest');
export = {
getCacheKey(fileData, filename, ...rest) {
const babelCacheKey = babelJest.getCacheKey(fileData, filename, ...rest);
return createHash('md5')
.update(babelCacheKey)
.update('my custom cache key thing')
.digest('hex');
},
process(src, filename, ...rest) {
const transformedContent = myCustomTransform(src, filename);
return babelJest.process(transformedContent, filename, ...rest);
},
};
I'll close this since I don't think we should do this, but feel free to continue discussing. It might make sense for some sort of combineTransformers transform to exist in user land which just pipes things between each transform.
I understand your reasoning. Thanks @SimenB, and thanks for the example too.
@SimenB What do you think of supporting it like Karma preprocessors config does (see the "Order of execution" section)?
So instead of having:
transform [object
We extend it to:
transform [object
So that we can do:
transform: {
'^.+\\.ts$': ['custom-transformer', 'ts-jest']
}
Neat idea, but we have an array there now already, which is used to pass config to the transformer
@SimenB to expand on the suggestion from @dwiyatci: I think it would be possible to keep the current logic while combining it with the existing syntax.
transform: {
'^.+\\.ts$': ['custom-transformer', { options }, 'ts-jest']
}
The options would just be optional to each pathToTransformer.
If it's a string it's a transformer and if it's an object it's options to the previous transformer? I guess we could do something like that.
Not sure it's better than a custom transform, though?
Yes, exactly that. It would be an intuitive API in my opinion. It was what I immediately thought as possibility. That's why I'd say it's better than the custom transformer. It's less work for the user.
Someone could create a chainTransformers(...transformerPackageNames) utility to make writing the custom transformer easier
Yeah, I think something like this should work?
"transform": {
'^.+\\.ts$': ['jest-chain-transformer', {
transformers: ['custom-transformer', 'ts-jest']
}]
}
We could link it from the docs.
(On mobile, sorry about formatting)
Even better! Perfect for this to be implemented in a package, would like to avoid adapting our config shape in a weird way to provide both backward compatibility and new features
Most helpful comment
As an alternative, you could call ts-jest from the transformer script to combine both transforms into one.