Skip to content

Commit 62031ff

Browse files
authored
Move next-codemod to Next.js monorepo (#15536)
1 parent f4433ce commit 62031ff

File tree

99 files changed

+2565
-49
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+2565
-49
lines changed

.eslintignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ packages/next/compiled/**/*
88
packages/react-refresh-utils/**/*.js
99
packages/react-dev-overlay/lib/**
1010
**/__tmp__/**
11-
.github/actions/next-stats-action/.work
11+
.github/actions/next-stats-action/.work
12+
packages/next-codemod/transforms/__testfixtures__/**/*
13+
packages/next-codemod/transforms/__tests__/**/*
14+
packages/next-codemod/**/*.js
15+
packages/next-codemod/**/*.d.ts

.prettierignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ packages/react-refresh-utils/**/*.d.ts
88
packages/react-dev-overlay/lib/**
99
**/__tmp__/**
1010
lerna.json
11-
.github/actions/next-stats-action/.work
11+
.github/actions/next-stats-action/.work
12+
packages/next-codemod/transforms/__testfixtures__/**/*
13+
packages/next-codemod/transforms/__tests__/**/*
14+
packages/next-codemod/**/*.js
15+
packages/next-codemod/**/*.d.ts

.prettierignore_staged

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
**/dist/**
44
packages/next/compiled/**/*
55
lerna.json
6+
packages/next-codemod/transforms/__testfixtures__/**/*
7+
packages/next-codemod/transforms/__tests__/**/*

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"testsafari": "cross-env BROWSER_NAME=safari yarn testonly",
1414
"testfirefox": "cross-env BROWSER_NAME=firefox yarn testonly",
1515
"testie": "cross-env BROWSER_NAME=\"internet explorer\" yarn testonly",
16-
"testall": "yarn run testonly -- --ci --forceExit",
16+
"testall": "yarn run testonly -- --ci --forceExit && lerna run --scope @next/codemod test",
1717
"genstats": "cross-env LOCAL_STATS=true node .github/actions/next-stats-action/src/index.js",
1818
"pretest": "yarn run lint",
1919
"git-reset": "git reset --hard HEAD",

packages/next-codemod/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.d.ts
2+
*.js
3+
*.js.map
4+
!transforms/__tests__/**/*.js
5+
!transforms/__testfixtures__/**/*.js

packages/next-codemod/README.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# Next.js Codemod
2+
3+
This repository contains Codemod transformations to help upgrade Next.js codebases.
4+
5+
## v9
6+
7+
### `name-default-component`
8+
9+
Transforms anonymous components into named components to make sure they work with [Fast Refresh](https://nextjs.org/blog/next-9-4#fast-refresh).
10+
11+
For example
12+
13+
```jsx
14+
// my-component.js
15+
export default function () {
16+
return <div>Hello World</div>
17+
}
18+
```
19+
20+
Transforms into:
21+
22+
```jsx
23+
// my-component.js
24+
export default function MyComponent() {
25+
return <div>Hello World</div>
26+
}
27+
```
28+
29+
The component will have a camel cased name based on the name of the file, and it also works with arrow functions.
30+
31+
#### Usage
32+
33+
Go to your project
34+
35+
```
36+
cd path-to-your-project/
37+
```
38+
39+
Download the codemod:
40+
41+
```
42+
curl -L https://github.com/zeit/next-codemod/archive/master.tar.gz | tar -xz --strip=2 next-codemod-master/transforms/name-default-component.js
43+
```
44+
45+
Run the transformation:
46+
47+
```
48+
npx jscodeshift -t ./name-default-component.js components/**/*.js
49+
```
50+
51+
TypeScript files can use this codemod too:
52+
53+
```
54+
npx jscodeshift -t ./name-default-component.js --parser=tsx components/**/*.tsx
55+
```
56+
57+
If you have components in multiple folders, change the path to `**/*.js` and add `--ignore-pattern="**/node_modules/**"`.
58+
59+
After the transformation is done the `name-default-component.js` file in the root of your project can be removed.
60+
61+
### `withamp-to-config`
62+
63+
Transforms the `withAmp` HOC into Next.js 9 page configuration.
64+
65+
For example:
66+
67+
```js
68+
// Before
69+
import { withAmp } from 'next/amp'
70+
71+
function Home() {
72+
return <h1>My AMP Page</h1>
73+
}
74+
75+
export default withAmp(Home)
76+
```
77+
78+
```js
79+
// After
80+
export default function Home() {
81+
return <h1>My AMP Page</h1>
82+
}
83+
84+
export const config = {
85+
amp: true,
86+
}
87+
```
88+
89+
#### Usage
90+
91+
Go to your project
92+
93+
```
94+
cd path-to-your-project/
95+
```
96+
97+
Download the codemod:
98+
99+
```
100+
curl -L https://github.com/zeit/next-codemod/archive/master.tar.gz | tar -xz --strip=2 next-codemod-master/transforms/withamp-to-config.js
101+
```
102+
103+
Run the transformation:
104+
105+
```
106+
npx jscodeshift -t ./withamp-to-config.js pages/**/*.js
107+
```
108+
109+
After the transformation is done the `withamp-to-config.js` file in the root of your project can be removed.
110+
111+
## v6
112+
113+
### `url-to-withrouter`
114+
115+
Tranforms the deprecated automatically injected `url` property on top level pages to using `withRouter` and the `router` property it injects. Read more here: [err.sh/next.js/url-deprecated](https://err.sh/next.js/url-deprecated)
116+
117+
For example:
118+
119+
```js
120+
// From
121+
import React from 'react'
122+
export default class extends React.Component {
123+
render() {
124+
const { pathname } = this.props.url
125+
return <div>Current pathname: {pathname}</div>
126+
}
127+
}
128+
```
129+
130+
```js
131+
// To
132+
import React from 'react'
133+
import { withRouter } from 'next/router'
134+
export default withRouter(
135+
class extends React.Component {
136+
render() {
137+
const { pathname } = this.props.router
138+
return <div>Current pathname: {pathname}</div>
139+
}
140+
}
141+
)
142+
```
143+
144+
This is just one case. All the cases that are transformed (and tested) can be found in the [`__testfixtures__` directory](./transforms/__testfixtures__/url-to-withrouter).
145+
146+
#### Usage
147+
148+
Go to your project
149+
150+
```
151+
cd path-to-your-project/
152+
```
153+
154+
Download the codemod:
155+
156+
```
157+
curl -L https://github.com/zeit/next-codemod/archive/master.tar.gz | tar -xz --strip=2 next-codemod-master/transforms/url-to-withrouter.js
158+
```
159+
160+
Run the transformation:
161+
162+
```
163+
npx jscodeshift -t ./url-to-withrouter.js pages/**/*.js
164+
```
165+
166+
After the transformation is done the `url-to-withrouter.js` file in the root of your project can be removed.
167+
168+
## Authors
169+
170+
- Tim Neutkens ([@timneutkens](https://twitter.com/timneutkens)) – [ZEIT](https://zeit.co)
171+
- Joe Haddad ([@timer150](https://twitter.com/timer150)) - [ZEIT](https://zeit.co)

packages/next-codemod/license.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2020 Vercel, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/next-codemod/package.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "@next/codemod",
3+
"version": "1.1.0",
4+
"license": "MIT",
5+
"dependencies": {
6+
"jscodeshift": "^0.6.4"
7+
},
8+
"scripts": {
9+
"prepublish": "tsc -d -p tsconfig.json",
10+
"build": "tsc -d -w -p tsconfig.json",
11+
"test": "jest"
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default () => <div>Anonymous function</div>;

packages/next-codemod/transforms/__testfixtures__/name-default-component/1-starts-with-number.output.js

Whitespace-only changes.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class ExistingName2Input {
2+
render() {}
3+
}
4+
5+
class nested {
6+
render() {
7+
const ExistingName2InputComponent = null;
8+
}
9+
}
10+
11+
export default () => <div>Anonymous function</div>;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class ExistingName2Input {
2+
render() {}
3+
}
4+
5+
class nested {
6+
render() {
7+
const ExistingName2InputComponent = null;
8+
}
9+
}
10+
11+
const ExistingName2InputComponent = () => <div>Anonymous function</div>;
12+
13+
export default ExistingName2InputComponent;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
function ExistingName3Input() {}
2+
3+
function nested() {
4+
const ExistingName3InputComponent = null;
5+
}
6+
7+
export default () => <div>Anonymous function</div>;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function ExistingName3Input() {}
2+
3+
function nested() {
4+
const ExistingName3InputComponent = null;
5+
}
6+
7+
const ExistingName3InputComponent = () => <div>Anonymous function</div>;
8+
9+
export default ExistingName3InputComponent;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const ExistingNameIgnoreInput = null;
2+
const ExistingNameIgnoreInputComponent = null;
3+
4+
export default () => <div>Anonymous function</div>;

packages/next-codemod/transforms/__testfixtures__/name-default-component/existing-name-ignore.output.js

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const ExistingNameInput = null;
2+
3+
function nested() {
4+
const ExistingNameInputComponent = null;
5+
}
6+
7+
export default () => <div>Anonymous function</div>;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const ExistingNameInput = null;
2+
3+
function nested() {
4+
const ExistingNameInputComponent = null;
5+
}
6+
7+
const ExistingNameInputComponent = () => <div>Anonymous function</div>;
8+
9+
export default ExistingNameInputComponent;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default () => <div>Anonymous function</div>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
const FunctionComponent2Input = () => <div>Anonymous function</div>;
2+
export default FunctionComponent2Input;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default () => {
2+
const x = 'y';
3+
if (true) {
4+
return '';
5+
}
6+
return null;
7+
};

packages/next-codemod/transforms/__testfixtures__/name-default-component/function-component-ignore.output.js

Whitespace-only changes.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default () => {
2+
const x = 'y';
3+
if (true) {
4+
return <div>Anonymous function</div>;
5+
}
6+
return null;
7+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const FunctionComponentInput = () => {
2+
const x = 'y';
3+
if (true) {
4+
return <div>Anonymous function</div>;
5+
}
6+
return null;
7+
};
8+
9+
export default FunctionComponentInput;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function Name() {
2+
const x = 'y';
3+
if (true) {
4+
return <div>Anonymous function</div>;
5+
}
6+
return null;
7+
}

packages/next-codemod/transforms/__testfixtures__/name-default-component/function-expression-ignore.output.js

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function () {
2+
const x = 'y';
3+
if (true) {
4+
return <div>Anonymous function</div>;
5+
}
6+
return null;
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function FunctionExpressionInput() {
2+
const x = 'y';
3+
if (true) {
4+
return <div>Anonymous function</div>;
5+
}
6+
return null;
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default () => <div>Anonymous function</div>;

packages/next-codemod/transforms/__testfixtures__/name-default-component/[email protected]

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {withRouter} from 'next/router'
2+
3+
export default withRouter(class extends React.Component {
4+
render() {
5+
const test = this.props.url
6+
}
7+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import {withRouter} from 'next/router'
2+
3+
export default withRouter(class extends React.Component {
4+
render() {
5+
const test = this.props.router
6+
}
7+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default withAppContainer(withAuth(props => {
2+
const test = props.url
3+
}))

0 commit comments

Comments
 (0)