main
js 145 lines 4.63 KB
Raw
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 const {ReactVersion} = require('../../ReactVersions');
12 const semver = require('semver');
13
14 const pathToBabel = path.join(
15 require.resolve('@babel/core'),
16 '../..',
17 'package.json'
18 );
19 const pathToTransformInfiniteLoops = require.resolve(
20 '../babel/transform-prevent-infinite-loops'
21 );
22 const pathToTransformTestGatePragma = require.resolve(
23 '../babel/transform-test-gate-pragma'
24 );
25 const pathToTransformReactVersionPragma = require.resolve(
26 '../babel/transform-react-version-pragma'
27 );
28 const pathToTransformLazyJSXImport = require.resolve(
29 '../babel/transform-lazy-jsx-import'
30 );
31 const pathToBabelrc = path.join(__dirname, '..', '..', 'babel.config.js');
32 const pathToErrorCodes = require.resolve('../error-codes/codes.json');
33
34 const ReactVersionTestingAgainst = process.env.REACT_VERSION || ReactVersion;
35
36 const babelOptions = {
37 plugins: [
38 // For Node environment only. For builds, Rollup takes care of ESM.
39 require.resolve('@babel/plugin-transform-modules-commonjs'),
40
41 pathToTransformInfiniteLoops,
42 pathToTransformTestGatePragma,
43
44 // This optimization is important for extremely performance-sensitive (e.g. React source).
45 // It's okay to disable it for tests.
46 [
47 require.resolve('@babel/plugin-transform-block-scoping'),
48 {throwIfClosureRequired: false},
49 ],
50 ],
51 retainLines: true,
52 };
53
54 module.exports = {
55 process: function (src, filePath) {
56 if (filePath.match(/\.css$/)) {
57 // Don't try to parse CSS modules; they aren't needed for tests anyway.
58 return {code: ''};
59 }
60 if (filePath.match(/\.coffee$/)) {
61 return {code: coffee.compile(src, {bare: true})};
62 }
63 if (filePath.match(/\.ts$/) && !filePath.match(/\.d\.ts$/)) {
64 return {code: tsPreprocessor.compile(src, filePath)};
65 }
66 if (filePath.match(/\.json$/)) {
67 return {code: src};
68 }
69 if (!filePath.match(/\/third_party\//)) {
70 // for test files, we also apply the async-await transform, but we want to
71 // make sure we don't accidentally apply that transform to product code.
72 const isTestFile = !!filePath.match(/\/__tests__\//);
73 const isInDevToolsPackages = !!filePath.match(
74 /\/packages\/react-devtools.*\//
75 );
76 const plugins = [].concat(babelOptions.plugins);
77 if (isTestFile && isInDevToolsPackages) {
78 plugins.push(pathToTransformReactVersionPragma);
79 }
80
81 // This is only for React DevTools tests with React 16.x
82 // `react/jsx-dev-runtime` and `react/jsx-runtime` are included in the package starting from v17
83 // Technically 16.14 and 15.7 have the new runtime but we're not testing those versions.
84 if (
85 semver.gte(ReactVersionTestingAgainst, '15.0.0') &&
86 semver.lt(ReactVersionTestingAgainst, '17.0.0')
87 ) {
88 plugins.push(
89 [
90 require.resolve('@babel/plugin-transform-react-jsx'),
91 {runtime: 'classic'},
92 ],
93 require.resolve('@babel/plugin-transform-react-jsx-source')
94 );
95 } else {
96 plugins.push([
97 process.env.NODE_ENV === 'development'
98 ? require.resolve('@babel/plugin-transform-react-jsx-development')
99 : require.resolve('@babel/plugin-transform-react-jsx'),
100 // The "automatic" runtime corresponds to react/jsx-runtime. "classic"
101 // would be React.createElement.
102 {runtime: 'automatic'},
103 ]);
104 }
105
106 plugins.push(pathToTransformLazyJSXImport);
107
108 let sourceAst = hermesParser.parse(src, {babel: true});
109 return {
110 code: babel.transformFromAstSync(
111 sourceAst,
112 src,
113 Object.assign(
114 {filename: path.relative(process.cwd(), filePath)},
115 babelOptions,
116 {
117 plugins,
118 sourceMaps: process.env.JEST_ENABLE_SOURCE_MAPS
119 ? process.env.JEST_ENABLE_SOURCE_MAPS
120 : false,
121 }
122 )
123 ).code,
124 };
125 }
126 return {code: src};
127 },
128
129 getCacheKey: createCacheKeyFunction(
130 [
131 __filename,
132 pathToBabel,
133 pathToBabelrc,
134 pathToTransformInfiniteLoops,
135 pathToTransformTestGatePragma,
136 pathToTransformReactVersionPragma,
137 pathToTransformLazyJSXImport,
138 pathToErrorCodes,
139 ],
140 [
141 (process.env.REACT_VERSION != null).toString(),
142 (process.env.NODE_ENV === 'development').toString(),
143 ]
144 ),
145 };