1. 'use strict';
    
  2. 
    
  3. const path = require('path');
    
  4. 
    
  5. const babel = require('@babel/core');
    
  6. const coffee = require('coffee-script');
    
  7. const hermesParser = require('hermes-parser');
    
  8. 
    
  9. const tsPreprocessor = require('./typescript/preprocessor');
    
  10. const createCacheKeyFunction = require('fbjs-scripts/jest/createCacheKeyFunction');
    
  11. 
    
  12. const pathToBabel = path.join(
    
  13.   require.resolve('@babel/core'),
    
  14.   '../..',
    
  15.   'package.json'
    
  16. );
    
  17. const pathToBabelPluginReplaceConsoleCalls = require.resolve(
    
  18.   '../babel/transform-replace-console-calls'
    
  19. );
    
  20. const pathToTransformInfiniteLoops = require.resolve(
    
  21.   '../babel/transform-prevent-infinite-loops'
    
  22. );
    
  23. const pathToTransformTestGatePragma = require.resolve(
    
  24.   '../babel/transform-test-gate-pragma'
    
  25. );
    
  26. const pathToTransformReactVersionPragma = require.resolve(
    
  27.   '../babel/transform-react-version-pragma'
    
  28. );
    
  29. const pathToBabelrc = path.join(__dirname, '..', '..', 'babel.config.js');
    
  30. const pathToErrorCodes = require.resolve('../error-codes/codes.json');
    
  31. 
    
  32. const babelOptions = {
    
  33.   plugins: [
    
  34.     // For Node environment only. For builds, Rollup takes care of ESM.
    
  35.     require.resolve('@babel/plugin-transform-modules-commonjs'),
    
  36. 
    
  37.     // Keep stacks detailed in tests.
    
  38.     // Don't put this in .babelrc so that we don't embed filenames
    
  39.     // into ReactART builds that include JSX.
    
  40.     // TODO: I have not verified that this actually works.
    
  41.     require.resolve('@babel/plugin-transform-react-jsx-source'),
    
  42. 
    
  43.     pathToTransformInfiniteLoops,
    
  44.     pathToTransformTestGatePragma,
    
  45. 
    
  46.     // This optimization is important for extremely performance-sensitive (e.g. React source).
    
  47.     // It's okay to disable it for tests.
    
  48.     [
    
  49.       require.resolve('@babel/plugin-transform-block-scoping'),
    
  50.       {throwIfClosureRequired: false},
    
  51.     ],
    
  52.   ],
    
  53.   retainLines: true,
    
  54. };
    
  55. 
    
  56. module.exports = {
    
  57.   process: function (src, filePath) {
    
  58.     if (filePath.match(/\.css$/)) {
    
  59.       // Don't try to parse CSS modules; they aren't needed for tests anyway.
    
  60.       return {code: ''};
    
  61.     }
    
  62.     if (filePath.match(/\.coffee$/)) {
    
  63.       return {code: coffee.compile(src, {bare: true})};
    
  64.     }
    
  65.     if (filePath.match(/\.ts$/) && !filePath.match(/\.d\.ts$/)) {
    
  66.       return {code: tsPreprocessor.compile(src, filePath)};
    
  67.     }
    
  68.     if (filePath.match(/\.json$/)) {
    
  69.       return {code: src};
    
  70.     }
    
  71.     if (!filePath.match(/\/third_party\//)) {
    
  72.       // for test files, we also apply the async-await transform, but we want to
    
  73.       // make sure we don't accidentally apply that transform to product code.
    
  74.       const isTestFile = !!filePath.match(/\/__tests__\//);
    
  75.       const isInDevToolsPackages = !!filePath.match(
    
  76.         /\/packages\/react-devtools.*\//
    
  77.       );
    
  78.       const testOnlyPlugins = [];
    
  79.       const sourceOnlyPlugins = [];
    
  80.       if (process.env.NODE_ENV === 'development' && !isInDevToolsPackages) {
    
  81.         sourceOnlyPlugins.push(pathToBabelPluginReplaceConsoleCalls);
    
  82.       }
    
  83.       const plugins = (isTestFile ? testOnlyPlugins : sourceOnlyPlugins).concat(
    
  84.         babelOptions.plugins
    
  85.       );
    
  86.       if (isTestFile && isInDevToolsPackages) {
    
  87.         plugins.push(pathToTransformReactVersionPragma);
    
  88.       }
    
  89.       let sourceAst = hermesParser.parse(src, {babel: true});
    
  90.       return {
    
  91.         code: babel.transformFromAstSync(
    
  92.           sourceAst,
    
  93.           src,
    
  94.           Object.assign(
    
  95.             {filename: path.relative(process.cwd(), filePath)},
    
  96.             babelOptions,
    
  97.             {
    
  98.               plugins,
    
  99.               sourceMaps: process.env.JEST_ENABLE_SOURCE_MAPS
    
  100.                 ? process.env.JEST_ENABLE_SOURCE_MAPS
    
  101.                 : false,
    
  102.             }
    
  103.           )
    
  104.         ).code,
    
  105.       };
    
  106.     }
    
  107.     return {code: src};
    
  108.   },
    
  109. 
    
  110.   getCacheKey: createCacheKeyFunction(
    
  111.     [
    
  112.       __filename,
    
  113.       pathToBabel,
    
  114.       pathToBabelrc,
    
  115.       pathToTransformInfiniteLoops,
    
  116.       pathToTransformTestGatePragma,
    
  117.       pathToTransformReactVersionPragma,
    
  118.       pathToErrorCodes,
    
  119.     ],
    
  120.     [
    
  121.       (process.env.REACT_VERSION != null).toString(),
    
  122.       (process.env.NODE_ENV === 'development').toString(),
    
  123.     ]
    
  124.   ),
    
  125. };