-
Notifications
You must be signed in to change notification settings - Fork 28k
/
Copy pathnext-babel.test.ts
195 lines (164 loc) · 6.27 KB
/
next-babel.test.ts
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/* eslint-env jest */
import { transformSync } from '@babel/core'
const trim = (s) => s.join('\n').trim().replace(/^\s+/gm, '')
const babel = (code, esm = false, presetOptions = {}, filename = 'noop.js') =>
transformSync(code, {
filename,
presets: [[require('next/dist/build/babel/preset'), presetOptions]],
babelrc: false,
configFile: false,
sourceType: 'module',
compact: true,
caller: {
name: 'tests',
supportsStaticESM: esm,
isDev: false,
},
} as any).code
describe('next/babel', () => {
describe('jsx-pragma', () => {
it('should transform JSX to use a local identifier in modern mode', () => {
const output = babel(`const a = () => <a href="/">home</a>;`, true)
// it should add a React import:
expect(output).toMatch(`import React from"react"`)
// it should hoist JSX factory to a module level variable:
expect(output).toMatch(`var __jsx=React.createElement`)
// it should use that factory for all JSX:
expect(output).toMatch(`__jsx("a",{href:"/"`)
expect(
babel(`const a = ()=><a href="/">home</a>`, true)
).toMatchInlineSnapshot(
`"import React from"react";var __jsx=React.createElement;var a=function a(){return __jsx("a",{href:"/"},"home");};"`
)
})
it('should transform JSX to use a local identifier in CommonJS mode', () => {
const output = babel(trim`
const a = () => <React.Fragment><a href="/">home</a></React.Fragment>;
`)
// Grab generated names from the compiled output.
// It looks something like this:
// var _react = _interopRequireDefault(require("react"));
// var __jsx = _react["default"].createElement;
// react: _react
// reactNamespace: _react["default"]
const [, react, reactNamespace] = output.match(
/(([a-z0-9_]+)(\[[^\]]*?\]|\.[a-z0-9_]+)*?)\.Fragment/i
)
expect(output).toMatch(`var ${reactNamespace}=`)
expect(output).toMatch(`require("react")`)
expect(output).toMatch(`var __jsx=${react}.createElement`)
// Fragment should use the same React namespace import:
expect(output).toMatch(`__jsx(${react}.Fragment`)
expect(output).toMatch(`__jsx("a",{href:"/"`)
expect(babel(`const a = ()=><a href="/">home</a>`)).toMatchInlineSnapshot(
`""use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");var _react=_interopRequireDefault(require("react"));var __jsx=_react["default"].createElement;var a=function a(){return __jsx("a",{href:"/"},"home");};"`
)
})
it('should support Fragment syntax', () => {
const output = babel(`const a = () => <>hello</>;`, true)
expect(output).toMatch(`React.Fragment`)
expect(babel(`const a = () => <>hello</>;`, true)).toMatchInlineSnapshot(
`"import React from"react";var __jsx=React.createElement;var a=function a(){return __jsx(React.Fragment,null,"hello");};"`
)
})
it('should support commonjs', () => {
const output = babel(
trim`
const React = require('react');
module.exports = () => <div>test2</div>;
`,
true
)
expect(output).toMatchInlineSnapshot(
`"var React=require('react');var __jsx=React.createElement;module.exports=function(){return __jsx("div",null,"test2");};"`
)
})
})
describe('optimize-hook-destructuring', () => {
it('should transform Array-destructured hook return values use object destructuring', () => {
const output = babel(
trim`
import { useState } from 'react';
const [count, setCount] = useState(0);
`,
true
)
expect(output).toMatch(trim`
var _useState=useState(0),count=_useState[0],setCount=_useState[1];
`)
expect(output).toMatchInlineSnapshot(
`"import{useState}from'react';var _useState=useState(0),count=_useState[0],setCount=_useState[1];"`
)
})
it('should be able to ignore some Array-destructured hook return values', () => {
const output = babel(
trim`
import { useState } from 'react';
const [, setCount] = useState(0);
`,
true
)
expect(output).toMatch(trim`
var _useState=useState(0),setCount=_useState[1];
`)
expect(output).toMatchInlineSnapshot(
`"import{useState}from'react';var _useState=useState(0),setCount=_useState[1];"`
)
})
})
describe('@babel/preset-typescript', () => {
describe('should allow passing options', () => {
const code = trim`
import { Tesla } from "./tesla";
import { Car } from "./car";
const benediktsDreamCar: Car = new Tesla();
`
function compileMyCar(options) {
return babel(
code,
false,
{
'preset-typescript': options,
},
'my-car.ts'
)
}
describe('when setting { onlyRemoveTypeImports: true }', () => {
it('should not elide import', () => {
const output = compileMyCar({ onlyRemoveTypeImports: true })
expect(output).toContain('require("./car")')
})
})
describe('when setting { onlyRemoveTypeImports: false }', () => {
it('should elide import', () => {
const output = compileMyCar({ onlyRemoveTypeImports: false })
expect(output).not.toContain('require("./car")')
})
})
})
})
describe('respect preset-react runtime', () => {
it('should allow forcing on automatic mode', () => {
const code = trim`const a = ()=><a href="/">home</a>`
const output = babel(code, true, {
'preset-react': {
runtime: 'automatic',
},
})
expect(output).toMatchInlineSnapshot(
`"import{jsx as _jsx}from"react/jsx-runtime";var a=function a(){return/*#__PURE__*/_jsx("a",{href:"/",children:"home"});};"`
)
})
it('should allow forcing on classic mode', () => {
const code = trim`const a = ()=><a href="/">home</a>`
const output = babel(code, true, {
'preset-react': {
runtime: 'classic',
},
})
expect(output).toMatchInlineSnapshot(
`"import React from"react";var __jsx=React.createElement;var a=function a(){return __jsx("a",{href:"/"},"home");};"`
)
})
})
})