Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

codemod: make parser more comptible #71122

Merged
merged 4 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/next-codemod/lib/cra-to-next/global-css-transform.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import nodePath from 'path'
import type { API, FileInfo, Options } from 'jscodeshift'
import { createParserFromPath } from '../parser'

export const globalCssContext = {
cssImports: new Set<string>(),
Expand All @@ -9,10 +10,10 @@ const globalStylesRegex = /(?<!\.module)\.(css|scss|sass)$/i

export default function transformer(
file: FileInfo,
api: API,
_api: API,
options: Options
) {
const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(file.path)
const root = j(file.source)
let hasModifications = false

Expand Down
5 changes: 3 additions & 2 deletions packages/next-codemod/lib/cra-to-next/index-to-component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { API, FileInfo, JSXElement, Options } from 'jscodeshift'
import { createParserFromPath } from '../parser'

export const indexContext = {
multipleRenderRoots: false,
Expand All @@ -7,10 +8,10 @@ export const indexContext = {

export default function transformer(
file: FileInfo,
api: API,
_api: API,
options: Options
) {
const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(file.path)
const root = j(file.source)
let hasModifications = false
let foundReactRender = 0
Expand Down
24 changes: 24 additions & 0 deletions packages/next-codemod/lib/parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import j from 'jscodeshift'
import babylonParse from 'jscodeshift/parser/babylon'
import tsOptions from 'jscodeshift/parser/tsOptions'

const dtsOptions = {
...tsOptions,
plugins: [
...tsOptions.plugins.filter((plugin) => plugin !== 'typescript'),
['typescript', { dts: true }],
],
}

function createParserFromPath(filePath: string): j.JSCodeshift {
const isTypeFile = /\.d\.(m|c)?ts$/.test(filePath)
if (isTypeFile) {
huozhi marked this conversation as resolved.
Show resolved Hide resolved
return j.withParser(babylonParse(dtsOptions))
}
// In Next.js js files could also contain jsx syntax, applying with tsx parser is most compatible.
huozhi marked this conversation as resolved.
Show resolved Hide resolved
// This is similar to how Next.js itself handles tsx and ts files with SWC.
const isTs = filePath.endsWith('.ts')
huozhi marked this conversation as resolved.
Show resolved Hide resolved
return isTs ? j.withParser('ts') : j.withParser('tsx')
}

export { createParserFromPath }
4 changes: 0 additions & 4 deletions packages/next-codemod/lib/run-jscodeshift.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ export default function runJscodeshift(
'**/node_modules/**',
'**/.next/**',
'**/build/**',
// type files
'**/*.d.ts',
'**/*.d.cts',
'**/*.d.mts',
// test files
'**/*.test.*',
'**/*.spec.*',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { cookies } from 'next/headers'

export {
cookies
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { cookies } from 'next/headers'

export {
cookies
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { JSX } from 'react'
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(
() => import('./component').then(mod => {
return mod.default;
})
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { JSX } from 'react'
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(
() => import('./component').then(mod => {
return {
default: mod.default
};
})
)
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ const { join } = require('path')
const fixtureDir = 'next-dynamic-access-named-export'
const fixtureDirPath = join(__dirname, '..', '__testfixtures__', fixtureDir)
const fixtures = readdirSync(fixtureDirPath)
.filter(file => file.endsWith('.input.js'))
.map(file => file.replace('.input.js', ''))
.filter(file => /\.input\.(js|tsx)$/.test(file))


for (const fixture of fixtures) {
for (const file of fixtures) {
const fixture = file.replace(/\.input\.(js|tsx)/, '');
const isTsx = file.endsWith('.tsx')
const prefix = `${fixtureDir}/${fixture}`;
defineTest(__dirname, fixtureDir, null, prefix, { parser: 'js' });
defineTest(__dirname, fixtureDir, null, prefix, { parser: isTsx ? 'tsx' : 'babel' });
}
5 changes: 3 additions & 2 deletions packages/next-codemod/transforms/add-missing-react-import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
JSCodeshift,
Options,
} from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

function addReactImport(j: JSCodeshift, root: Collection) {
// We create an import specifier, this is the value of an import, eg:
Expand Down Expand Up @@ -49,10 +50,10 @@ function addReactImport(j: JSCodeshift, root: Collection) {

export default function transformer(
file: FileInfo,
api: API,
_api: API,
options: Options
) {
const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(file.path)
const root = j(file.source)

const hasReactImport = (r) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import type { API, FileInfo } from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

export default function transformer(file: FileInfo, api: API) {
export default function transformer(file: FileInfo, _api: API) {
if (
process.env.NODE_ENV !== 'test' &&
!/[/\\]app[/\\].*?(page|layout|route)\.[^/\\]+$/.test(file.path)
) {
return file.source
}

const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(file.path)
const root = j(file.source)

const runtimeExport = root.find(j.ExportNamedDeclaration, {
Expand Down
5 changes: 3 additions & 2 deletions packages/next-codemod/transforms/built-in-next-font.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { API, FileInfo, Options } from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

export default function transformer(
file: FileInfo,
api: API,
_api: API,
options: Options
) {
const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(file.path)
const root = j(file.source)
let hasChanges = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
insertCommentOnce,
NEXTJS_ENTRY_FILES,
} from './utils'
import { createParserFromPath } from '../../../lib/parser'

const DYNAMIC_IMPORT_WARN_COMMENT = ` Next.js Dynamic Async API Codemod: The APIs under 'next/headers' are async now, need to be manually awaited. `

Expand Down Expand Up @@ -42,11 +43,11 @@ function findDynamicImportsAndComment(root: Collection<any>, j: API['j']) {

export function transformDynamicAPI(
source: string,
api: API,
_api: API,
filePath: string
) {
const isEntryFile = NEXTJS_ENTRY_FILES.test(filePath)
const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(filePath)
const root = j(source)
let modified = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
getVariableDeclaratorId,
NEXTJS_ENTRY_FILES,
} from './utils'
import { createParserFromPath } from '../../../lib/parser'

const PAGE_PROPS = 'props'

Expand Down Expand Up @@ -348,7 +349,7 @@ function modifyTypes(

export function transformDynamicProps(
source: string,
api: API,
_api: API,
filePath: string
) {
const isEntryFile = NEXTJS_ENTRY_FILES.test(filePath)
Expand All @@ -358,7 +359,7 @@ export function transformDynamicProps(

let modified = false
let modifiedPropArgument = false
const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(filePath)
const root = j(source)
// Check if 'use' from 'react' needs to be imported
let needsReactUseImport = false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { API, FileInfo } from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

export default function transformer(file: FileInfo, api: API) {
const j = api.jscodeshift
export default function transformer(file: FileInfo, _api: API) {
const j = createParserFromPath(file.path)
const root = j(file.source)

// Find the metadata export
Expand Down
5 changes: 3 additions & 2 deletions packages/next-codemod/transforms/name-default-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
Options,
} from 'jscodeshift'
import { basename, extname } from 'path'
import { createParserFromPath } from '../lib/parser'

const camelCase = (value: string): string => {
const val = value.replace(/[-_\s.]+(.)?/g, (_match, chr) =>
Expand All @@ -21,10 +22,10 @@ const isValidIdentifier = (value: string): boolean =>

export default function transformer(
file: FileInfo,
api: API,
_api: API,
options: Options
) {
const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(file.path)
const root = j(file.source)

let hasModifications: boolean
Expand Down
5 changes: 3 additions & 2 deletions packages/next-codemod/transforms/new-link.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// x-ref: https://github.com/facebook/jscodeshift/issues/534

import type { API, FileInfo } from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

export default function transformer(file: FileInfo, api: API) {
const j = api.jscodeshift.withParser('tsx')
export default function transformer(file: FileInfo, _api: API) {
const j = createParserFromPath(file.path)

const $j = j(file.source)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { FileInfo, API, ImportDeclaration } from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

export default function transformer(file: FileInfo, api: API) {
const j = api.jscodeshift
export default function transformer(file: FileInfo, _api: API) {
const j = createParserFromPath(file.path)
const root = j(file.source)

// Find the import declaration for 'next/dynamic'
Expand Down
5 changes: 3 additions & 2 deletions packages/next-codemod/transforms/next-image-experimental.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
JSXAttribute,
Options,
} from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

function findAndReplaceProps(
j: JSCodeshift,
Expand Down Expand Up @@ -255,10 +256,10 @@ function nextConfigTransformer(

export default function transformer(
file: FileInfo,
api: API,
_api: API,
options: Options
) {
const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(file.path)
const root = j(file.source)

const parsed = parse(file.path || '/')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { API, FileInfo, Options } from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

export default function transformer(
file: FileInfo,
api: API,
_api: API,
options: Options
) {
const j = api.jscodeshift.withParser('tsx')
const j = createParserFromPath(file.path)
const root = j(file.source)

// Before: import Image from "next/image"
Expand Down
5 changes: 3 additions & 2 deletions packages/next-codemod/transforms/next-og-import.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { API, FileInfo } from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

const importToChange = 'ImageResponse'

export default function transformer(file: FileInfo, api: API) {
const j = api.jscodeshift
export default function transformer(file: FileInfo, _api: API) {
const j = createParserFromPath(file.path)

// Find import declarations that match the pattern
file.source = j(file.source)
Expand Down
11 changes: 6 additions & 5 deletions packages/next-codemod/transforms/next-request-geo-ip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@ import type {
ImportSpecifier,
Identifier,
} from 'jscodeshift'
import { createParserFromPath } from '../lib/parser'

const GEO = 'geo'
const IP = 'ip'
const GEOLOCATION = 'geolocation'
const IP_ADDRESS = 'ipAddress'
const GEO_TYPE = 'Geo'

export default function (fileInfo: FileInfo, api: API) {
const j = api.jscodeshift.withParser('tsx')
const root = j(fileInfo.source)
export default function (file: FileInfo, _api: API) {
const j = createParserFromPath(file.path)
const root = j(file.source)

if (!root.length) {
return fileInfo.source
return file.source
}

const nextReqType = root
Expand Down Expand Up @@ -97,7 +98,7 @@ export default function (fileInfo: FileInfo, api: API) {
hasChangedIpType

if (!needChanges) {
return fileInfo.source
return file.source
}

// Even if there was a change above, if there's an existing import,
Expand Down
Loading