Skip to content

Commit

Permalink
fix(remix-dev/cli/migrate): fix convert-to-javascript migration (#3987
Browse files Browse the repository at this point in the history
)
  • Loading branch information
MichaelDeBoey committed Aug 15, 2022
1 parent 01317cc commit 81bec18
Show file tree
Hide file tree
Showing 7 changed files with 314 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,26 @@ const checkMigrationRanSuccessfully = async (projectDir: string) => {
cwd: config.rootDirectory,
ignore: [`./${config.appDirectory}/**/*`],
});
let result = shell.grep("-l", 'from "', JSFiles);
expect(result.stdout.trim()).toBe("");
expect(result.stderr).toBeNull();
expect(result.code).toBe(0);
let importResult = shell.grep("-l", 'from "', JSFiles);
expect(importResult.stdout.trim()).toBe("");
expect(importResult.stderr).toBeNull();
expect(importResult.code).toBe(0);
let exportDefaultResult = shell.grep("-l", 'export default "', JSFiles);
expect(exportDefaultResult.stdout.trim()).toBe("");
expect(exportDefaultResult.stderr).toBeNull();
expect(exportDefaultResult.code).toBe(0);
let exportClassResult = shell.grep("-l", 'export class "', JSFiles);
expect(exportClassResult.stdout.trim()).toBe("");
expect(exportClassResult.stderr).toBeNull();
expect(exportClassResult.code).toBe(0);
let exportConstResult = shell.grep("-l", 'export const "', JSFiles);
expect(exportConstResult.stdout.trim()).toBe("");
expect(exportConstResult.stderr).toBeNull();
expect(exportConstResult.code).toBe(0);
let exportFunctionResult = shell.grep("-l", 'export function "', JSFiles);
expect(exportFunctionResult.stdout.trim()).toBe("");
expect(exportFunctionResult.stderr).toBeNull();
expect(exportFunctionResult.code).toBe(0);
};

const makeApp = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import type { ExportDefaultDeclaration, JSCodeshift } from "jscodeshift";

/**
* export default foo
* =>
* module.exports = foo
*/
export const createExportExpressionStatementFromExportDefaultDeclaration = (
j: JSCodeshift,
exportDefaultDeclaration: ExportDefaultDeclaration
) => {
/**
* HACK: Can't use casts nor type guards in a `jscodeshift` transform
* https://github.com/facebook/jscodeshift/issues/467
*
* So to narrow declaration type, we check it against all possible
* `DeclarationKind` values instead.
*/
if (
exportDefaultDeclaration.declaration.type === "ClassBody" ||
exportDefaultDeclaration.declaration.type === "ClassMethod" ||
exportDefaultDeclaration.declaration.type === "ClassPrivateMethod" ||
exportDefaultDeclaration.declaration.type === "ClassPrivateProperty" ||
exportDefaultDeclaration.declaration.type === "ClassProperty" ||
exportDefaultDeclaration.declaration.type === "ClassPropertyDefinition" ||
exportDefaultDeclaration.declaration.type === "DeclareClass" ||
exportDefaultDeclaration.declaration.type ===
"DeclareExportAllDeclaration" ||
exportDefaultDeclaration.declaration.type === "DeclareExportDeclaration" ||
exportDefaultDeclaration.declaration.type === "DeclareInterface" ||
exportDefaultDeclaration.declaration.type === "DeclareOpaqueType" ||
exportDefaultDeclaration.declaration.type === "DeclareTypeAlias" ||
exportDefaultDeclaration.declaration.type === "EnumDeclaration" ||
exportDefaultDeclaration.declaration.type === "ExportAllDeclaration" ||
exportDefaultDeclaration.declaration.type === "ExportDeclaration" ||
exportDefaultDeclaration.declaration.type === "ExportDefaultDeclaration" ||
exportDefaultDeclaration.declaration.type === "ExportNamedDeclaration" ||
exportDefaultDeclaration.declaration.type === "ImportDeclaration" ||
exportDefaultDeclaration.declaration.type === "InterfaceDeclaration" ||
exportDefaultDeclaration.declaration.type === "MethodDefinition" ||
exportDefaultDeclaration.declaration.type === "OpaqueType" ||
exportDefaultDeclaration.declaration.type ===
"TSCallSignatureDeclaration" ||
exportDefaultDeclaration.declaration.type ===
"TSConstructSignatureDeclaration" ||
exportDefaultDeclaration.declaration.type === "TSDeclareFunction" ||
exportDefaultDeclaration.declaration.type === "TSDeclareMethod" ||
exportDefaultDeclaration.declaration.type === "TSEnumDeclaration" ||
exportDefaultDeclaration.declaration.type === "TSExternalModuleReference" ||
exportDefaultDeclaration.declaration.type === "TSImportEqualsDeclaration" ||
exportDefaultDeclaration.declaration.type === "TSIndexSignature" ||
exportDefaultDeclaration.declaration.type === "TSInterfaceDeclaration" ||
exportDefaultDeclaration.declaration.type === "TSMethodSignature" ||
exportDefaultDeclaration.declaration.type === "TSModuleDeclaration" ||
exportDefaultDeclaration.declaration.type ===
"TSNamespaceExportDeclaration" ||
exportDefaultDeclaration.declaration.type === "TSPropertySignature" ||
exportDefaultDeclaration.declaration.type === "TSTypeAliasDeclaration" ||
exportDefaultDeclaration.declaration.type ===
"TSTypeParameterDeclaration" ||
exportDefaultDeclaration.declaration.type === "TypeAlias" ||
exportDefaultDeclaration.declaration.type === "VariableDeclaration"
) {
return exportDefaultDeclaration;
}

let expressionKind =
exportDefaultDeclaration.declaration.type === "ClassDeclaration"
? j.classExpression.from(exportDefaultDeclaration.declaration)
: exportDefaultDeclaration.declaration.type === "FunctionDeclaration"
? j.functionExpression.from(exportDefaultDeclaration.declaration)
: exportDefaultDeclaration.declaration;
return j.expressionStatement(
j.assignmentExpression(
"=",
j.memberExpression(j.identifier("module"), j.identifier("exports")),
expressionKind
)
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import type {
ClassDeclaration,
ExportNamedDeclaration,
FunctionDeclaration,
JSCodeshift,
VariableDeclaration,
} from "jscodeshift";

/**
* export class Foo {}
* export const foo = bar
* export function foo() {}
* =>
* module.Foo = class Foo {}
* module.foo = bar
* module.foo = function foo() {}
*/
export const createExportExpressionStatementFromExportNamedDeclaration = (
j: JSCodeshift,
exportNamedDeclaration: ExportNamedDeclaration
) => {
/**
* HACK: Can't use casts nor type guards in a `jscodeshift` transform
* https://github.com/facebook/jscodeshift/issues/467
*
* So to narrow declaration type, we check it against convertable values
* instead.
*/
if (
!(
exportNamedDeclaration.declaration?.type === "ClassDeclaration" ||
exportNamedDeclaration.declaration?.type === "FunctionDeclaration" ||
exportNamedDeclaration.declaration?.type === "VariableDeclaration"
)
) {
return exportNamedDeclaration;
}

// export class Foo {}
if (exportNamedDeclaration.declaration.type === "ClassDeclaration") {
return createExportExpressionStatementFromExportNamedClassDeclaration(
j,
exportNamedDeclaration.declaration
);
}

// export function foo() {}
if (exportNamedDeclaration.declaration.type === "FunctionDeclaration") {
return createExportExpressionStatementFromExportNamedFunctionDeclaration(
j,
exportNamedDeclaration.declaration
);
}

// export const foo = bar
if (exportNamedDeclaration.declaration.type === "VariableDeclaration") {
return createExportExpressionStatementFromExportNamedVariableDeclaration(
j,
exportNamedDeclaration.declaration
);
}
};

/**
* export class Foo {}
* =>
* module.Foo = class Foo {}
*/
const createExportExpressionStatementFromExportNamedClassDeclaration = (
j: JSCodeshift,
classDeclaration: ClassDeclaration
) =>
j.expressionStatement(
j.assignmentExpression(
"=",
j.memberExpression(
j.identifier("module"),
classDeclaration.id || j.identifier("")
),
j.classExpression.from(classDeclaration)
)
);

/**
* export function foo() {}
* =>
* module.foo = function foo() {}
*/
const createExportExpressionStatementFromExportNamedFunctionDeclaration = (
j: JSCodeshift,
functionDeclaration: FunctionDeclaration
) =>
j.expressionStatement(
j.assignmentExpression(
"=",
j.memberExpression(
j.identifier("module"),
functionDeclaration.id || j.identifier("")
),
j.functionExpression.from(functionDeclaration)
)
);

/**
* export const foo = bar
* export const foo = 5
* export const foo = []
* export const foo = function foo(){}
* =>
* module.foo = bar
* module.foo = 5
* module.foo = []
* module.foo = function foo(){}
*/
const createExportExpressionStatementFromExportNamedVariableDeclaration = (
j: JSCodeshift,
variableDeclaration: VariableDeclaration
) =>
variableDeclaration.declarations.flatMap((declaration) => {
/**
* HACK: Can't use casts nor type guards in a `jscodeshift` transform
* https://github.com/facebook/jscodeshift/issues/467
*
* So to narrow declaration id type, we check it against convertable values
* instead.
*/
if (
declaration.type !== "VariableDeclarator" ||
declaration.id.type === "ArrayPattern" ||
declaration.id.type === "AssignmentPattern" ||
declaration.id.type === "ObjectPattern" ||
declaration.id.type === "PropertyPattern" ||
declaration.id.type === "RestElement" ||
declaration.id.type === "SpreadElementPattern" ||
declaration.id.type === "SpreadPropertyPattern" ||
declaration.id.type === "TSParameterProperty" ||
!declaration.init
) {
return [];
}

return j.expressionStatement(
j.assignmentExpression(
"=",
j.memberExpression(j.identifier("module"), declaration.id),
declaration.init
)
);
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import type { ImportDeclaration, JSCodeshift } from "jscodeshift";

export const createExpressionStatement = (
/**
* import "foo"
* =>
* require("foo")
*/
export const createImportExpressionStatement = (
j: JSCodeshift,
{ source }: ImportDeclaration
) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import type { ImportDeclaration, JSCodeshift } from "jscodeshift";

/**
* import foo from "foo"
* import * as foo from "foo"
* =>
* const foo = require("foo").default
* const foo = require("foo")
*/
export const createVariableDeclarationIdentifier = (
j: JSCodeshift,
{ source, specifiers }: ImportDeclaration
) => {
let callExpression = j.callExpression(j.identifier("require"), [source]);
let isDefaultImport = (specifiers || []).some(
({ type }) => type === "ImportDefaultSpecifier"
);

return j.variableDeclaration("const", [
j.variableDeclarator(
Expand All @@ -24,7 +34,9 @@ export const createVariableDeclarationIdentifier = (
: []
)[0].local?.name || ""
),
callExpression
isDefaultImport
? j.memberExpression(callExpression, j.identifier("default"))
: callExpression
),
]);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import type { ImportDeclaration, JSCodeshift } from "jscodeshift";

/**
* import { foo } from "foo"
* import { foo as bar } from "foo"
* =>
* const { foo } = require("foo")
* const { foo: bar } = require("foo")
*/
export const createVariableDeclarationObjectPattern = (
j: JSCodeshift,
{ source, specifiers }: ImportDeclaration
Expand Down
Loading

0 comments on commit 81bec18

Please sign in to comment.