ember-codemod-remove-ember-css-modules
Codemod to replace ember-css-modules
with embroider-css-modules
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 fromember-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:
Case 2:
/* app/components/ui/form/textarea.css */
.textarea {
composes: input from "my-app/components/ui/form/input.css";
}
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;
}
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
After, with embroider-css-modules
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
After refactor, with ember-css-modules
Compatibility
- Node.js v18 or above
Contributing
See the Contributing guide for details.
License
This project is licensed under the MIT License.