Skip to content

Commit 52db787

Browse files
Merge pull request #24 from CodeshiftCommunity/emotion11
Adds codemod to migration from @emotion 10 to 11
2 parents dae3b6c + 6ef7d5f commit 52db787

File tree

9 files changed

+134
-18
lines changed

9 files changed

+134
-18
lines changed

community/@emotion_monorepo/11.0.0/motions/.gitkeep

Whitespace-only changes.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { applyTransform } from '@codeshift/test-utils';
2+
import * as transformer from './transform';
3+
4+
describe('@emotion@11.0.0 transform', () => {
5+
it('should transform imports correctly', () => {
6+
const result = applyTransform(
7+
transformer,
8+
`
9+
import * as core from '@emotion/core';
10+
import * as emotion from 'emotion';
11+
import * as emotionTheming from 'emotion-theming';
12+
import * as emotionServer from 'emotion-server';
13+
import * as createEmotion from 'create-emotion';
14+
import * as createEmotionServer from 'create-emotion-server';
15+
import * as babelPlugin from 'babel-plugin-emotion';
16+
import * as eslintPlugin from 'eslint-plugin-emotion';
17+
import * as jestEmotion from 'jest-emotion';
18+
`,
19+
{ parser: 'tsx' },
20+
);
21+
22+
expect(result).toMatchInlineSnapshot(`
23+
"import * as core from \\"@emotion/react\\";
24+
import * as emotion from \\"@emotion/css\\";
25+
import * as emotionTheming from \\"@emotion/react\\";
26+
import * as emotionServer from \\"@emotion/server\\";
27+
import * as createEmotion from \\"@emotion/css/create-instance\\";
28+
import * as createEmotionServer from \\"@emotion/server/create-instance\\";
29+
import * as babelPlugin from \\"@emotion/babel-plugin\\";
30+
import * as eslintPlugin from \\"@emotion/eslint-plugin\\";
31+
import * as jestEmotion from \\"@emotion/jest\\";"
32+
`);
33+
});
34+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { API, FileInfo, Options } from 'jscodeshift';
2+
import {
3+
hasImportDeclaration,
4+
renameImportDeclaration,
5+
} from '@codeshift/utils';
6+
7+
const importMap = {
8+
'@emotion/core': '@emotion/react',
9+
emotion: '@emotion/css',
10+
'emotion-theming': '@emotion/react',
11+
'emotion-server': '@emotion/server',
12+
'create-emotion': '@emotion/css/create-instance',
13+
'create-emotion-server': '@emotion/server/create-instance',
14+
'babel-plugin-emotion': '@emotion/babel-plugin',
15+
'eslint-plugin-emotion': '@emotion/eslint-plugin',
16+
'jest-emotion': '@emotion/jest',
17+
};
18+
19+
export default function transformer(
20+
file: FileInfo,
21+
{ jscodeshift: j }: API,
22+
options: Options,
23+
) {
24+
const source = j(file.source);
25+
26+
if (
27+
!Object.keys(importMap).some(importSource =>
28+
hasImportDeclaration(j, source, importSource),
29+
)
30+
) {
31+
return file.source;
32+
}
33+
34+
Object.entries(importMap).forEach(([key, value]) =>
35+
renameImportDeclaration(j, source, key, value),
36+
);
37+
38+
return source.toSource(options.printOptions);
39+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
maintainers: ['danieldelcore'],
3+
transforms: {
4+
'11.0.0': require('./11.0.0/transform'),
5+
},
6+
};

packages/initializer/src/index.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@ import fs from 'fs-extra';
22
import semver from 'semver';
33
import * as recast from 'recast';
44

5-
function transformPackageName(packageName: string) {
6-
return packageName.replace('/', '__');
7-
}
8-
95
function main(packageName: string, version: string) {
106
if (!packageName) throw new Error('Package name was not provided');
117
if (!version) throw new Error('Version was not provided');
@@ -17,23 +13,30 @@ function main(packageName: string, version: string) {
1713
}
1814

1915
const communityDirectoryPath = `${__dirname}/../../../community`;
20-
const safePackageName = transformPackageName(packageName);
16+
const safePackageName = packageName.replace('/', '__');
2117
const codemodBasePath = `${communityDirectoryPath}/${safePackageName}`;
2218
const codemodPath = `${codemodBasePath}/${version}`;
2319
const configPath = `${codemodBasePath}/codeshift.config.js`;
24-
const testsPath = `${codemodPath}/_tests_`;
2520
const motionsPath = `${codemodPath}/motions`;
2621

2722
fs.mkdirSync(codemodPath, { recursive: true });
23+
24+
fs.copyFileSync(
25+
`${__dirname}/../template/transform.spec.ts`,
26+
`${codemodPath}/transform.spec.ts`,
27+
);
28+
fs.copyFileSync(
29+
`${__dirname}/../template/transform.ts`,
30+
`${codemodPath}/transform.ts`,
31+
);
2832
fs.copySync(`${__dirname}/../template/motions`, motionsPath);
29-
fs.copySync(`${__dirname}/../template/_tests_`, testsPath);
3033

3134
const testFile = fs
32-
.readFileSync(`${testsPath}/transform.spec.ts`, 'utf8')
35+
.readFileSync(`${codemodPath}/transform.spec.ts`, 'utf8')
3336
.replace('<% packageName %>', packageName)
3437
.replace('<% version %>', version);
3538

36-
fs.writeFileSync(`${testsPath}/transform.spec.ts`, testFile);
39+
fs.writeFileSync(`${codemodPath}/transform.spec.ts`, testFile);
3740

3841
if (!fs.existsSync(configPath)) {
3942
fs.writeFileSync(
@@ -86,11 +89,6 @@ function main(packageName: string, version: string) {
8689
);
8790
}
8891

89-
fs.copyFileSync(
90-
`${__dirname}/../template/transform.ts`,
91-
`${codemodPath}/transform.ts`,
92-
);
93-
9492
console.log(
9593
`🚚 New codemod package created at: community/${safePackageName}/${version}`,
9694
);

packages/initializer/template/_tests_/transform.spec.ts renamed to packages/initializer/template/transform.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { applyTransform } from '@codeshift/test-utils';
2-
import * as transformer from '../transform';
2+
import * as transformer from './transform';
33

44
describe('<% packageName %>@<% version %> transform', () => {
55
it('should transform correctly', () => {

packages/initializer/template/transform.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { API, FileInfo, Options } from 'jscodeshift';
22

33
export default function transformer(
4-
fileInfo: FileInfo,
4+
file: FileInfo,
55
{ jscodeshift: j }: API,
66
options: Options,
77
) {
8-
const source = j(fileInfo.source);
8+
const source = j(file.source);
99

1010
/**
1111
* Early exit condition
@@ -16,7 +16,7 @@ export default function transformer(
1616
* https://codeshiftcommunity.github.io/CodeshiftCommunity/docs/your-first-codemod#output
1717
*/
1818
if (/* Some condition here */ true) {
19-
return fileInfo.source;
19+
return file.source;
2020
}
2121

2222
/**

packages/utils/src/imports.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ export function removeImportDeclaration(
3232
getImportDeclaration(j, source, sourcePath).remove();
3333
}
3434

35+
export function renameImportDeclaration(
36+
j: core.JSCodeshift,
37+
source: Collection<any>,
38+
sourcePath: string,
39+
newSourcePath: string,
40+
) {
41+
getImportDeclaration(j, source, sourcePath).forEach(
42+
importDeclaration =>
43+
(importDeclaration.node.source = j.stringLiteral(newSourcePath)),
44+
);
45+
}
46+
3547
export function getDefaultImportSpecifier(
3648
j: core.JSCodeshift,
3749
source: Collection<any>,

website/docs/api/codeshift-utils.mdx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,33 @@ removeImportDeclaration(j, source, 'react');
8585
-import React, { useEffect } from 'react';
8686
```
8787

88+
### `renameImportDeclaration(j, source, sourcePath, newSourcePath)`
89+
90+
Renames an import declaration by source name
91+
92+
**Returns**
93+
94+
`void`
95+
96+
**Example**
97+
98+
```jsx
99+
// src/App.js
100+
import React from 'react';
101+
```
102+
103+
```js
104+
import { renameImportDeclaration } from '@codeshift/utils';
105+
106+
renameImportDeclaration(j, source, 'react', 'preact');
107+
```
108+
109+
```diff
110+
// src/App.js
111+
-import React, { useEffect } from 'react';
112+
+import React, { useEffect } from 'preact';
113+
```
114+
88115
### `getDefaultImportSpecifier(j, source, sourcePath)`
89116

90117
Finds a default import specifier

0 commit comments

Comments
 (0)