You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
docuseal/vendor/bundle/ruby/4.0.0/gems/shakapacker-9.7.0/tools
Wabo d9b86d464c
Restore fork-specific features lost during upstream sync:
3 weeks ago
..
README.md Restore fork-specific features lost during upstream sync: 3 weeks ago
css-modules-v9-codemod.js Restore fork-specific features lost during upstream sync: 3 weeks ago

README.md

Shakapacker v9 Migration Tools

CSS Modules Codemod

A jscodeshift codemod to help migrate CSS module imports from v8 to v9 format.

What it does

For JavaScript files (.js, .jsx):

  • Converts import styles from './styles.module.css' to import { className1, className2 } from './styles.module.css'
  • Automatically detects which CSS classes are used in the file
  • Handles kebab-case to camelCase conversion (e.g., my-buttonmyButton)
  • Updates all class references from styles.className to className

For TypeScript files (.ts, .tsx):

  • Converts import styles from './styles.module.css' to import * as styles from './styles.module.css'
  • Preserves the same usage pattern (styles.className)
  • Works around TypeScript's limitation with dynamic named exports

Installation

npm install -g jscodeshift

Usage

Dry run (see what would change):

npx jscodeshift -t tools/css-modules-v9-codemod.js src/ --dry

Apply to JavaScript files:

npx jscodeshift -t tools/css-modules-v9-codemod.js src/

Apply to TypeScript files:

npx jscodeshift -t tools/css-modules-v9-codemod.js --parser tsx src/

Apply to specific file patterns:

# Only .jsx files
npx jscodeshift -t tools/css-modules-v9-codemod.js src/**/*.jsx

# Only .tsx files
npx jscodeshift -t tools/css-modules-v9-codemod.js --parser tsx src/**/*.tsx

Options

  • --dry - Run without modifying files
  • --print - Print the transformed output
  • --parser tsx - Use TypeScript parser
  • --verbose - Show detailed progress

Examples

Before (JavaScript):

import styles from "./Button.module.css"

function Button() {
  return (
    <button className={styles.button}>
      <span className={styles["button-text"]}>Click me</span>
    </button>
  )
}

After (JavaScript):

import { button, buttonText } from "./Button.module.css"

function Button() {
  return (
    <button className={button}>
      <span className={buttonText}>Click me</span>
    </button>
  )
}

Before (TypeScript):

import styles from './Button.module.css';

const Button: React.FC = () => {
  return <button className={styles.button}>Click</button>;
};

After (TypeScript):

import * as styles from './Button.module.css';

const Button: React.FC = () => {
  return <button className={styles.button}>Click</button>;
};

Notes

  1. Kebab-case conversion: CSS classes with kebab-case (e.g., my-button) are automatically converted to camelCase (myButton) for JavaScript files, matching css-loader's exportLocalsConvention: 'camelCaseOnly' setting.

  2. Unused imports: The codemod only imports CSS classes that are actually used in JavaScript files. If you pass the entire styles object to a component, it will convert to namespace import for safety.

  3. Manual review recommended: Always review the changes, especially for complex usage patterns or dynamic class name construction.

  4. Backup your code: Run the codemod on version-controlled code or create a backup first.

Troubleshooting

Issue: Codemod doesn't detect all CSS class usages Solution: For dynamic class names or complex patterns, manual migration may be needed.

Issue: TypeScript errors after transformation Solution: Ensure your TypeScript definitions are updated as shown in the v9 Upgrade Guide.

Issue: Runtime errors about missing CSS classes Solution: Check if you have kebab-case class names that need camelCase conversion.