scripts/jest/preprocessor.js (87 lines of code) (raw):

'use strict'; const path = require('path'); const babel = require('@babel/core'); const coffee = require('coffee-script'); const tsPreprocessor = require('./typescript/preprocessor'); const createCacheKeyFunction = require('fbjs-scripts/jest/createCacheKeyFunction'); const pathToBabel = path.join( require.resolve('@babel/core'), '../..', 'package.json' ); const pathToBabelPluginReplaceConsoleCalls = require.resolve( '../babel/transform-replace-console-calls' ); const pathToBabelPluginAsyncToGenerator = require.resolve( '@babel/plugin-transform-async-to-generator' ); const pathToTransformInfiniteLoops = require.resolve( '../babel/transform-prevent-infinite-loops' ); const pathToTransformTestGatePragma = require.resolve( '../babel/transform-test-gate-pragma' ); const pathToBabelrc = path.join(__dirname, '..', '..', 'babel.config.js'); const pathToErrorCodes = require.resolve('../error-codes/codes.json'); const babelOptions = { plugins: [ // For Node environment only. For builds, Rollup takes care of ESM. require.resolve('@babel/plugin-transform-modules-commonjs'), // Keep stacks detailed in tests. // Don't put this in .babelrc so that we don't embed filenames // into ReactART builds that include JSX. // TODO: I have not verified that this actually works. require.resolve('@babel/plugin-transform-react-jsx-source'), pathToTransformInfiniteLoops, pathToTransformTestGatePragma, // This optimization is important for extremely performance-sensitive (e.g. React source). // It's okay to disable it for tests. [ require.resolve('@babel/plugin-transform-block-scoping'), {throwIfClosureRequired: false}, ], ], retainLines: true, }; module.exports = { process: function(src, filePath) { if (filePath.match(/\.css$/)) { // Don't try to parse CSS modules; they aren't needed for tests anyway. return ''; } if (filePath.match(/\.coffee$/)) { return coffee.compile(src, {bare: true}); } if (filePath.match(/\.ts$/) && !filePath.match(/\.d\.ts$/)) { return tsPreprocessor.compile(src, filePath); } if (filePath.match(/\.json$/)) { return src; } if (!filePath.match(/\/third_party\//)) { // for test files, we also apply the async-await transform, but we want to // make sure we don't accidentally apply that transform to product code. const isTestFile = !!filePath.match(/\/__tests__\//); const isInDevToolsPackages = !!filePath.match( /\/packages\/react-devtools.*\// ); const testOnlyPlugins = [pathToBabelPluginAsyncToGenerator]; const sourceOnlyPlugins = []; if (process.env.NODE_ENV === 'development' && !isInDevToolsPackages) { sourceOnlyPlugins.push(pathToBabelPluginReplaceConsoleCalls); } const plugins = (isTestFile ? testOnlyPlugins : sourceOnlyPlugins).concat( babelOptions.plugins ); return babel.transform( src, Object.assign( {filename: path.relative(process.cwd(), filePath)}, babelOptions, { plugins, } ) ); } return src; }, getCacheKey: createCacheKeyFunction([ __filename, pathToBabel, pathToBabelrc, pathToTransformInfiniteLoops, pathToTransformTestGatePragma, pathToErrorCodes, ]), };