ember-codemod-remove-ember-css-modules

1.1.1 • Public • Published

This project uses GitHub Actions for continuous integration.

ember-codemod-remove-ember-css-modules

Codemod to replace ember-css-modules with embroider-css-modules

  1. Features
  2. Usage
  3. How to refactor code
  4. Compatibility
  5. Contributing
  6. License

Features

  • Preserves your code whenever possible
  • Supports glint
  • Focuses on maintainability and extensibility

Usage

You can check ember-container-query as a reference.

Step 1. Quickly migrate to embroider-css-modules.1

cd <path/to/your/project>
npx ember-codemod-remove-ember-css-modules <arguments>

Step 2. Review the project.

  • [x] Update the configuration files.2
  • [x] Remove the remaining instances of local-class attributes and {{local-class}} helpers from ember-css-modules.
  • [x] Confirm that you can run all scripts in package.json.

1. Some prerequisites for running the codemod: First, migrate to the Octane layout (flat or nested). You can leverage codemods for classic and pod layouts. Second, refactor code to help the codemod update templates correctly.

2. Files such as .eslintrc.js, .prettierrc.js, .stylelintrc.js, .template-lintrc.js, ember-cli-build.js, package.json, postcss.config.js, tsconfig.json, etc.

Arguments

Optional: Specify the component structure

By default, an Octane project has the flat component structure. Pass --component-structure to indicate otherwise.

npx ember-codemod-remove-ember-css-modules --component-structure="nested"
Optional: Specify the project root

Pass --root to run the codemod on a project somewhere else (i.e. not in the current directory).

npx ember-codemod-remove-ember-css-modules --root=<path/to/your/project>

Limitations

The codemod is designed to cover typical uses of ember-css-modules. It is not designed to cover one-off cases.

To better meet your needs, consider cloning the repo and running the codemod locally.

cd <path/to/cloned/repo>

# Compile TypeScript
pnpm build

# Run codemod
./dist/bin/ember-codemod-remove-ember-css-modules.js --root=<path/to/your/project>

How to refactor code

Remove code inheritance

ember-css-modules allows composing (really, inheriting) CSS code in two ways:

  • composes: ... from '...'; in *.css
  • {{local-class ... from="..."}} in *.hbs

The first syntax will continue to work in an Embroider app, provided that the import path is either global or a relative path.

/* app/components/ui/form/textarea.css */
.textarea {
  composes: input from "./input.css";
}

.is-disabled {
  composes: input-disabled from global;
}

/* These do not work */
.textarea {
  composes: input from "my-app/components/ui/form/input.css";
}

.textarea {
  composes: input from "my-v2-addon/components/ui/form/input.css";
}

The second syntax isn't supported by the {{local}} helper from embroider-css-modules, so you will need to update the template and stylesheet accordingly.

However, note that the presence of composes (in a set of related components) may indicate a premature abstraction and an incorrect component design. Ideally, you might duplicate the CSS, then refactor the components. If short on time, you can import the relevant styles object in the backing class.

Before, with ember-css-modules

Case 1:

{{! app/components/ui/form/textarea.hbs }}
<textarea
  class={{local-class "input" from="my-app/components/ui/form/input.css"}}
/>

Case 2:

/* app/components/ui/form/textarea.css */
.textarea {
  composes: input from "my-app/components/ui/form/input.css";
}
{{! app/components/ui/form/textarea.hbs }}
<textarea
  local-class="textarea"
/>
After, with embroider-css-modules
/* app/components/ui/form/textarea.ts */
import Component from '@glimmer/component';

import inputStyles from './input.css';
import styles from './textarea.css';

export default class UiFormTextareaComponent extends Component {
  inputStyles = inputStyles;
  styles = styles;
}
{{! app/components/ui/form/textarea.hbs }}
<textarea
  class={{this.inputStyles.input}}
/>

Remove complex string concatenations

In ember-css-modules, a string can represent multiple local class names via concatenation. In embroider-css-modules, each string represents exactly one.

Before, with ember-css-modules
{{! app/components/ui/form/textarea.hbs }}
<textarea
  local-class="
    textarea
    {{if (or @isDisabled @isReadOnly) 'is-disabled'}}
  "
/>
After, with embroider-css-modules
{{! app/components/ui/form/textarea.hbs }}
<textarea
  class={{local-class
    this.styles
    "textarea"
    (if (or @isDisabled @isReadOnly) "is-disabled")
  }}
/>

The codemod may fail to update complex expressions. Refactor templates to provide hints. For example, remove nested conditionals (apply them outside the HTML element) and use the {{concat}} helper to group substrings.

Before refactor, with ember-css-modules
{{! app/components/ui/form/phone.hbs }}
<input
  local-class="input flag-{{@country}}"
  type="tel"
/>
After refactor, with ember-css-modules
{{! app/components/ui/form/phone.hbs }}
<input
  local-class="input {{concat 'flag-' @country}}"
  type="tel"
/>

Compatibility

  • Node.js v18 or above

Contributing

See the Contributing guide for details.

License

This project is licensed under the MIT License.

Package Sidebar

Install

npm i ember-codemod-remove-ember-css-modules

Weekly Downloads

6

Version

1.1.1

License

MIT

Unpacked Size

49.4 kB

Total Files

34

Last publish

Collaborators

  • ijlee2