Awesome
typed-css-modules
Creates TypeScript definition files from CSS Modules .css files.
If you have the following css,
/* styles.css */
@value primary: red;
.myClass {
color: primary;
}
typed-css-modules creates the following .d.ts files from the above css:
/* styles.css.d.ts */
declare const styles: {
readonly primary: string;
readonly myClass: string;
};
export = styles;
So, you can import CSS modules' class or variable into your TypeScript sources:
/* app.ts */
import styles from './styles.css';
console.log(`<div class="${styles.myClass}"></div>`);
console.log(`<div style="color: ${styles.primary}"></div>`);
CLI
npm install -g typed-css-modules
And exec tcm <input directory>
command.
For example, if you have .css files under src
directory, exec the following:
tcm src
Then, this creates *.css.d.ts
files under the directory which has the original .css file.
(your project root)
- src/
| myStyle.css
| myStyle.css.d.ts [created]
output directory
Use -o
or --outDir
option.
For example:
tcm -o dist src
(your project root)
- src/
| myStyle.css
- dist/
| myStyle.css.d.ts [created]
file name pattern
By default, this tool searches **/*.css
files under <input directory>
.
If you can customize the glob pattern, you can use --pattern
or -p
option.
Note the quotes around the glob to -p
(they are required, so that your shell does not perform the expansion).
tcm -p 'src/**/*.css' .
watch
With -w
or --watch
, this CLI watches files in the input directory.
validating type files
With -l
or --listDifferent
, list any files that are different than those that would be generated.
If any are different, exit with a status code 1.
camelize CSS token
With -c
or --camelCase
, kebab-cased CSS classes(such as .my-class {...}
) are exported as camelized TypeScript variable name(export const myClass: string
).
You can pass --camelCase dashes
to only camelize dashes in the class name. Since version 0.27.1
in the
webpack css-loader
. This will keep upperCase class names intact, e.g.:
.SomeComponent {
height: 10px;
}
becomes
declare const styles: {
readonly SomeComponent: string;
};
export = styles;
See also webpack css-loader's camelCase option.
named exports (enable tree shaking)
With -e
or --namedExports
, types are exported as named exports as opposed to default exports.
This enables support for the namedExports
css-loader feature, required for webpack to tree shake the final CSS (learn more here).
Use this option in combination with https://webpack.js.org/loaders/css-loader/#namedexport and https://webpack.js.org/loaders/style-loader/#namedexport (if you use style-loader
).
When this option is enabled, the type definition changes to support named exports.
NOTE: this option enables camelcase by default.
.SomeComponent {
height: 10px;
}
Standard output:
declare const styles: {
readonly SomeComponent: string;
};
export = styles;
Named exports output:
export const someComponent: string;
arbitrary file extensions
With -a
or --allowArbitraryExtensions
, output filenames will be compatible with the "arbitrary file extensions" feature that was introduce in TypeScript 5.0. See the docs for more info.
In essence, the *.css.d.ts
extension now becomes *.d.css.ts
so that you can import CSS modules in projects using ESM module resolution.
API
npm install typed-css-modules
import DtsCreator from 'typed-css-modules';
let creator = new DtsCreator();
creator.create('src/style.css').then(content => {
console.log(content.tokens); // ['myClass']
console.log(content.formatted); // 'export const myClass: string;'
content.writeFile(); // writes this content to "src/style.css.d.ts"
});
class DtsCreator
DtsCreator instance processes the input CSS and creates TypeScript definition contents.
new DtsCreator(option)
You can set the following options:
option.rootDir
: Project root directory(default:process.cwd()
).option.searchDir
: Directory which includes target*.css
files(default:'./'
).option.outDir
: Output directory(default:option.searchDir
).option.camelCase
: Camelize CSS class tokens.option.namedExports
: Use named exports as opposed to default exports to enable tree shaking. Requiresimport * as style from './file.module.css';
(default:false
)option.allowArbitraryExtensions
: Output filenames that will be compatible with the "arbitrary file extensions" TypeScript featureoption.EOL
: EOL (end of line) for the generatedd.ts
files. Possible values'\n'
or'\r\n'
(default:os.EOL
).
create(filepath, contents) => Promise(dtsContent)
Returns DtsContent
instance.
filepath
: path of target .css file.contents
(optional): the CSS content of thefilepath
. If set, DtsCreator uses the contents instead of the original contents of thefilepath
.
class DtsContent
DtsContent instance has *.d.ts
content, final output path, and function to write the file.
writeFile(postprocessor) => Promise(dtsContent)
Writes the DtsContent instance's content to a file. Returns the DtsContent instance.
-
postprocessor
(optional): a function that takes the formatted definition string and returns a modified string that will be the final content written to the file.You could use this, for example, to pass generated definitions through a formatter like Prettier, or to add a comment to the top of generated files:
dtsContent.writeFile(definition => `// Generated automatically, do not edit\n${definition}`);
tokens
An array of tokens is retrieved from the input CSS file.
e.g. ['myClass']
contents
An array of TypeScript definition expressions.
e.g. ['export const myClass: string;']
.
formatted
A string of TypeScript definition expressions.
e.g.
export const myClass: string;
messageList
An array of messages. The messages contain invalid token information.
e.g. ['my-class is not valid TypeScript variable name.']
.
outputFilePath
Final output file path.
Remarks
If your input CSS file has the following class names, these invalid tokens are not written to output .d.ts
file.
/* TypeScript reserved word */
.while {
color: red;
}
/* invalid TypeScript variable */
/* If camelCase option is set, this token will be converted to 'myClass' */
.my-class {
color: red;
}
/* it's ok */
.myClass {
color: red;
}
Example
There is a minimum example in this repository example
folder. Clone this repository and run cd example; npm i; npm start
.
Or please see https://github.com/Quramy/typescript-css-modules-demo. It's a working demonstration of CSS Modules with React and TypeScript.
License
This software is released under the MIT License, see LICENSE.txt.