Skip to content

Commit 31d676c

Browse files
Merge branch 'canary' into base-server/remove-path
2 parents 97e2ac2 + 9fe2f26 commit 31d676c

File tree

7 files changed

+257
-21
lines changed

7 files changed

+257
-21
lines changed

examples/cms-wordpress/pages/index.js

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,25 @@ export default function Index({ allPosts: { edges }, preview }) {
1212
const morePosts = edges.slice(1)
1313

1414
return (
15-
<>
16-
<Layout preview={preview}>
17-
<Head>
18-
<title>Next.js Blog Example with {CMS_NAME}</title>
19-
</Head>
20-
<Container>
21-
<Intro />
22-
{heroPost && (
23-
<HeroPost
24-
title={heroPost.title}
25-
coverImage={heroPost.featuredImage}
26-
date={heroPost.date}
27-
author={heroPost.author}
28-
slug={heroPost.slug}
29-
excerpt={heroPost.excerpt}
30-
/>
31-
)}
32-
{morePosts.length > 0 && <MoreStories posts={morePosts} />}
33-
</Container>
34-
</Layout>
35-
</>
15+
<Layout preview={preview}>
16+
<Head>
17+
<title>Next.js Blog Example with {CMS_NAME}</title>
18+
</Head>
19+
<Container>
20+
<Intro />
21+
{heroPost && (
22+
<HeroPost
23+
title={heroPost.title}
24+
coverImage={heroPost.featuredImage}
25+
date={heroPost.date}
26+
author={heroPost.author}
27+
slug={heroPost.slug}
28+
excerpt={heroPost.excerpt}
29+
/>
30+
)}
31+
{morePosts.length > 0 && <MoreStories posts={morePosts} />}
32+
</Container>
33+
</Layout>
3634
)
3735
}
3836

packages/next/build/swc/options.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ function getBaseSWCOptions({
4040
const emitDecoratorMetadata = Boolean(
4141
jsConfig?.compilerOptions?.emitDecoratorMetadata
4242
)
43+
const useDefineForClassFields = Boolean(
44+
jsConfig?.compilerOptions?.useDefineForClassFields
45+
)
4346
return {
4447
jsc: {
4548
...(resolvedBaseUrl && paths
@@ -63,6 +66,7 @@ function getBaseSWCOptions({
6366
: {}),
6467
legacyDecorator: enableDecorators,
6568
decoratorMetadata: emitDecoratorMetadata,
69+
useDefineForClassFields: useDefineForClassFields,
6670
react: {
6771
importSource:
6872
jsConfig?.compilerOptions?.jsxImportSource ??
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { join } from 'path'
2+
import webdriver from 'next-webdriver'
3+
import { createNext, FileRef } from 'e2e-utils'
4+
import { NextInstance } from 'test/lib/next-modes/base'
5+
import { check } from 'next-test-utils'
6+
7+
describe('useDefineForClassFields SWC option', () => {
8+
let next: NextInstance
9+
10+
beforeAll(async () => {
11+
next = await createNext({
12+
files: {
13+
'tsconfig.json': new FileRef(
14+
join(__dirname, 'define-class-fields/tsconfig.json')
15+
),
16+
pages: new FileRef(join(__dirname, 'define-class-fields/pages')),
17+
},
18+
dependencies: {
19+
mobx: '6.3.7',
20+
typescript: '*',
21+
'@types/react': '*',
22+
'@types/node': '*',
23+
'mobx-react': '7.2.1',
24+
},
25+
})
26+
})
27+
28+
afterAll(() => next.destroy())
29+
30+
it('tsx should compile with useDefineForClassFields enabled', async () => {
31+
let browser
32+
try {
33+
browser = await webdriver(next.appPort, '/')
34+
await browser.elementByCss('#action').click()
35+
await check(
36+
() => browser.elementByCss('#name').text(),
37+
/this is my name: next/
38+
)
39+
} finally {
40+
if (browser) {
41+
await browser.close()
42+
}
43+
}
44+
})
45+
46+
it("Initializes resident to undefined after the call to 'super()' when with useDefineForClassFields enabled", async () => {
47+
let browser
48+
try {
49+
browser = await webdriver(next.appPort, '/animal')
50+
expect(await browser.elementByCss('#dog').text()).toBe('')
51+
expect(await browser.elementByCss('#dogDecl').text()).toBe('dog')
52+
} finally {
53+
if (browser) {
54+
await browser.close()
55+
}
56+
}
57+
})
58+
59+
async function matchLogs$(browser) {
60+
let data_foundLog = false
61+
let name_foundLog = false
62+
63+
const browserLogs = await browser.log('browser')
64+
65+
browserLogs.forEach((log) => {
66+
if (log.message.includes('data changed')) {
67+
data_foundLog = true
68+
}
69+
if (log.message.includes('name changed')) {
70+
name_foundLog = true
71+
}
72+
})
73+
return [data_foundLog, name_foundLog]
74+
}
75+
76+
it('set accessors from base classes won’t get triggered with useDefineForClassFields enabled', async () => {
77+
let browser
78+
try {
79+
browser = await webdriver(next.appPort, '/derived')
80+
await matchLogs$(browser).then(([data_foundLog, name_foundLog]) => {
81+
expect(data_foundLog).toBe(true)
82+
expect(name_foundLog).toBe(false)
83+
})
84+
} finally {
85+
if (browser) {
86+
await browser.close()
87+
}
88+
}
89+
})
90+
})
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React from 'react'
2+
3+
interface Animal {
4+
animalStuff: any
5+
}
6+
interface Dog extends Animal {
7+
dogStuff: any
8+
}
9+
10+
class AnimalHouse {
11+
resident: Animal
12+
constructor(animal: Animal) {
13+
this.resident = animal
14+
}
15+
}
16+
class DogHouse extends AnimalHouse {
17+
// Initializes 'resident' to 'undefined'
18+
// after the call to 'super()' when
19+
// using 'useDefineForClassFields'!
20+
// @ts-ignore
21+
resident: Dog
22+
// useless constructor only for type checker
23+
/* eslint-disable @typescript-eslint/no-useless-constructor */
24+
constructor(dog: Dog) {
25+
super(dog)
26+
}
27+
}
28+
29+
class DogHouseWithDeclare extends AnimalHouse {
30+
declare resident: Dog
31+
// useless constructor only for type checker
32+
/* eslint-disable @typescript-eslint/no-useless-constructor */
33+
constructor(dog: Dog) {
34+
super(dog)
35+
}
36+
}
37+
38+
export default function AnimalView() {
39+
const dog = new DogHouse({
40+
animalStuff: 'animal',
41+
dogStuff: 'dog',
42+
})
43+
const dogDeclare = new DogHouseWithDeclare({
44+
animalStuff: 'animal',
45+
dogStuff: 'dog',
46+
})
47+
return (
48+
<>
49+
<div id={'dog'}>{dog.resident}</div>
50+
<div id={'dogDecl'}>{dogDeclare.resident?.dogStuff}</div>
51+
</>
52+
)
53+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from 'react'
2+
3+
class Base {
4+
set data(value: number) {
5+
console.log('data changed to ' + value)
6+
}
7+
8+
set name(value: number) {
9+
console.log('name changed to ' + value)
10+
}
11+
}
12+
13+
class Derived extends Base {
14+
// No longer triggers a 'console.log'
15+
// when using 'useDefineForClassFields'.
16+
// @ts-ignore
17+
name = 10
18+
constructor() {
19+
super()
20+
//triggers a 'console.log'
21+
this.data = 10
22+
}
23+
}
24+
25+
export default function DerivedView() {
26+
const obj = new Derived()
27+
return (
28+
<>
29+
<div id={'data'}>{obj.data}</div>
30+
<div id={'name'}>{obj.name}</div>
31+
</>
32+
)
33+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// @ts-ignore
2+
import { makeObservable, observable } from 'mobx'
3+
// @ts-ignore
4+
import { observer } from 'mobx-react'
5+
import React from 'react'
6+
7+
class Person {
8+
//Declarations are initialized with Object.defineProperty.
9+
10+
// @ts-ignore
11+
name: string
12+
13+
constructor() {
14+
//without useDefineForClassFields it will be error
15+
makeObservable(this, {
16+
name: observable,
17+
})
18+
}
19+
}
20+
21+
const person = new Person()
22+
23+
const PersonView = observer(() => {
24+
const changeName = () => {
25+
person.name = 'next'
26+
}
27+
return (
28+
<>
29+
<div id="name">this is my name: {person.name}</div>
30+
<button id="action" onClick={changeName}>
31+
Change Name
32+
</button>
33+
</>
34+
)
35+
})
36+
37+
export default function Home() {
38+
return <PersonView />
39+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"compilerOptions": {
3+
"useDefineForClassFields": true,
4+
"esModuleInterop": true,
5+
"module": "esnext",
6+
"jsx": "preserve",
7+
"target": "es5",
8+
"lib": ["dom", "dom.iterable", "esnext"],
9+
"allowJs": true,
10+
"skipLibCheck": false,
11+
"strict": true,
12+
"forceConsistentCasingInFileNames": true,
13+
"noEmit": true,
14+
"incremental": true,
15+
"moduleResolution": "node",
16+
"resolveJsonModule": true,
17+
"isolatedModules": true
18+
}
19+
}

0 commit comments

Comments
 (0)