Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
32 changes: 29 additions & 3 deletions docs/MigrationGuide.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import './MigrationGuide.css';
import { Footer, TableOfContent } from '@sb/components';
import { Meta } from '@storybook/blocks';
import './MigrationGuide.css';
import { MessageStrip } from '@ui5/webcomponents-react';

<Meta title="Migration Guide" />

Expand All @@ -14,10 +15,35 @@ or the [changelog](?path=/docs/change-log--page)._
> This migration guide only covers breaking changes when updating from v1 to v2.
> For migration guides for older releases, please refer to our [Migration Guide Archive](https://github.com/SAP/ui5-webcomponents-react/blob/main/docs/MigrationGuide.archive.md).

<br />

<TableOfContent headingSelector="h2, h3" />

## Codemod

To make the migration to UI5 Web Components (for React) v2 easier,
we provide a codemod which tries to transform most of the breaking changes.

<MessageStrip
hideCloseButton
design="Critical"
children={
<>
The codemod is a best efforts attempt to help you migrate the breaking change. Please review the generated code
thoroughly!
<br />
<strong>
Applying the codemod might break your code formatting, so please don't forget to run prettier and/or eslint
after you've applied the codemod!
</strong>
</>
}
/>

```shell
npx @ui5/webcomponents-react-cli codemod --transform v2 \
--src ./path/to/src \
--typescript # only if you use TypeScript in your project, omit if you use JavaScript
```

## General changes

### Removed `react-jss`
Expand Down
98 changes: 81 additions & 17 deletions packages/cli/src/bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,25 @@ import { resolve } from 'node:path';
import { parseArgs } from 'node:util';
import * as process from 'process';

const options = {
packageName: {
type: 'string' as const
},
out: {
type: 'string' as const,
short: 'o'
},
additionalComponentNote: {
type: 'string' as const
}
};
const { values, positionals } = parseArgs({ options, allowPositionals: true });
const { positionals } = parseArgs({ allowPositionals: true, strict: false });

const [command] = positionals;

console.log(command);

switch (command) {
case 'create-wrappers': {
const wrapperOptions = {
packageName: {
type: 'string' as const
},
out: {
type: 'string' as const,
short: 'o'
},
additionalComponentNote: {
type: 'string' as const
}
};
const { values } = parseArgs({ options: wrapperOptions, allowPositionals: true });
const { packageName, out, additionalComponentNote } = values;
const missingParameters = [];
if (!packageName) {
Expand Down Expand Up @@ -51,9 +50,74 @@ switch (command) {
}

case 'resolve-cem': {
const cemOptions = {
packageName: {
type: 'string' as const
},
out: {
type: 'string' as const,
short: 'o'
}
};
const { values } = parseArgs({ options: cemOptions, allowPositionals: true });
const { packageName, out } = values;
const missingParameters = [];
if (!packageName) {
missingParameters.push('--packageName');
}
if (!out) {
missingParameters.push('--out');
}

if (missingParameters.length > 0) {
console.error(`
Missing parameters: ${missingParameters.join(', ')}
Example: ui5-wcr resolve-cem --packageName @ui5/webcomponents --out ./src/components

Please add the missing parameters and try again.
`);
process.exit(1);
}

const resolveCEM = await import('../scripts/resolve-cem/main.js');
const outPath = resolve(process.cwd(), values.out!);
await resolveCEM.default(values.packageName!, outPath);
const outPath = resolve(process.cwd(), out!);
await resolveCEM.default(packageName!, outPath);
break;
}

case 'codemod': {
const codemodOptions = {
transform: {
type: 'string' as const
},
src: {
type: 'string' as const
},
typescript: {
type: 'boolean' as const,
default: false
}
};
const { values } = parseArgs({ options: codemodOptions, allowPositionals: true });
const missingParameters = [];
if (!values.src) {
missingParameters.push('--src');
}
if (!values.transform) {
missingParameters.push('--transform');
}

if (missingParameters.length > 0) {
console.error(`
Missing parameters: ${missingParameters.join(', ')}
Example: ui5-wcr codemod --src ./src --transform v2 (--typescript)

Please add the missing parameters and try again.
`);
process.exit(1);
}
const codemod = await import('../scripts/codemod/main.js');
await codemod.default(values.transform!, values.src!, values.typescript!);
break;
}
default:
Expand Down
40 changes: 40 additions & 0 deletions packages/cli/src/scripts/codemod/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import childProcess from 'node:child_process';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const SUPPORTED_TRANSFORMERS = ['v2'];

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const transformerDir = path.resolve(__dirname, 'transforms');

export default async function runCodemod(transform: string, inputDir: string, useTypeScript: boolean) {
if (!SUPPORTED_TRANSFORMERS.includes(transform)) {
// eslint-disable-next-line no-console
console.error('Invalid transform choice, pick one of:');
// eslint-disable-next-line no-console
console.error(SUPPORTED_TRANSFORMERS.map((x) => '- ' + x).join('\n'));
process.exit(1);
}

const jscodeshiftOptions = [];

const transformerPath = path.join(transformerDir, transform, `main.cjs`);
jscodeshiftOptions.push(`--transform`, transformerPath);

if (useTypeScript) {
jscodeshiftOptions.push('--extensions=tsx,ts,jsx,js');
jscodeshiftOptions.push('--parser', 'tsx');
} else {
jscodeshiftOptions.push('--extensions=jsx,js');
}

jscodeshiftOptions.push('--ignore-pattern=**/node_modules/**');

// eslint-disable-next-line no-console
console.log(`Executing 'npx jscodeshift ${jscodeshiftOptions.join(' ')} ${inputDir}'`);
childProcess.spawnSync('npx', ['jscodeshift', ...jscodeshiftOptions, inputDir], {
stdio: 'inherit'
});
}