Repository navigation
Expand file tree
/
Copy pathbabel.ts
More file actions
149 lines (135 loc) · 4.58 KB
/
Copy pathbabel.ts
File metadata and controls
149 lines (135 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import { dirname } from 'path';
import { parse } from 'semver';
import { logger } from '@nx/devkit';
/*
* Babel preset to provide TypeScript support and module/nomodule for Nx.
*/
export interface NxWebBabelPresetOptions {
useBuiltIns?: boolean | string;
decorators?: {
decoratorsBeforeExport?: boolean;
legacy?: boolean;
};
loose?: boolean;
/** @deprecated Use `loose` option instead of `classProperties.loose`
*/
classProperties?: {
loose?: boolean;
};
}
module.exports = function (api: any, options: NxWebBabelPresetOptions = {}) {
api.assertVersion(7);
const isModern = api.caller((caller) => caller?.isModern);
// use by @nx/cypress react component testing to prevent core js build issues
const isTest = api.caller((caller) => caller?.isTest);
// This is set by `@nx/rollup:rollup` executor
const isNxPackage = api.caller((caller) => caller?.isNxPackage);
const emitDecoratorMetadata = api.caller(
(caller) => caller?.emitDecoratorMetadata ?? true
);
// Determine settings for `@babel//babel-plugin-transform-class-properties`,
// so that we can sync the `loose` option with `@babel/preset-env`.
// TODO(v21): Remove classProperties since it's no longer needed, now that the class props transform is in preset-env.
const loose = options.classProperties?.loose ?? options.loose ?? true;
if (options.classProperties) {
logger.warn(
`Use =\`loose\` option instead of \`classProperties.loose\`. The \`classProperties\` option will be removed in Nx 20`
);
}
const plugins = [
!isNxPackage
? [
require.resolve('@babel/plugin-transform-runtime'),
{
corejs: false,
helpers: true,
regenerator: true,
useESModules: isModern,
absoluteRuntime: dirname(
require.resolve('@babel/runtime/package.json')
),
},
]
: null,
require.resolve('babel-plugin-macros'),
emitDecoratorMetadata
? require.resolve('babel-plugin-transform-typescript-metadata')
: undefined,
// Must use legacy decorators to remain compatible with TypeScript.
[
require.resolve('@babel/plugin-proposal-decorators'),
options.decorators ?? { legacy: true },
],
[require.resolve('@babel/plugin-transform-class-properties'), { loose }],
].filter(Boolean);
return {
presets: [
// Support module/nomodule pattern.
[
require.resolve('@babel/preset-env'),
// For Jest tests, NODE_ENV is set as 'test' and we only want to set target as Node.
// All other options will fail in Jest since Node does not support some ES features
// such as import syntax.
isTest || process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID
? { targets: { node: 'current' }, loose }
: createBabelPresetEnvOptions(options.useBuiltIns, isModern, loose),
],
[
require.resolve('@babel/preset-typescript'),
{
allowDeclareFields: true,
},
],
],
plugins,
overrides: [
// Convert `const enum` to `enum`. The former cannot be supported by babel
// but at least we can get it to not error out.
{
test: /\.tsx?$/,
plugins: [
[
require.resolve('babel-plugin-const-enum'),
{
transform: 'removeConst',
},
],
],
},
],
};
};
function createBabelPresetEnvOptions(
useBuiltIns: string | boolean,
isModern: boolean,
loose: boolean
) {
const presetOptions: any = {
// Do not transform modules to CJS
modules: false,
targets: isModern ? { esmodules: 'intersect' } : undefined,
bugfixes: true,
// Exclude transforms that make all code slower
exclude: ['transform-typeof-symbol'],
// This must match the setting for `@babel/plugin-proposal-class-properties`
loose,
};
// If core-js is installed then set corresponding options, otherwise don't use core-js.
// Previously, core-js was required for all projects, but it is not longer required when using only stable JS features that does not need to be transpiled.
const coreJsVersion = findCoreJsVersion();
if (coreJsVersion) {
presetOptions.useBuiltIns = useBuiltIns ?? 'entry';
presetOptions.corejs = useBuiltIns !== false ? coreJsVersion : null;
}
return presetOptions;
}
function findCoreJsVersion(): string | null {
try {
// nx-ignore-next-line
const v = require('core-js/package.json').version;
const { major, minor } = parse(v);
return `${major}.${minor}`;
} catch (e) {
return null;
}
}