webpack-typings-for-css
Version:
Webpack loader that generates TypeScript typings for CSS modules
165 lines (131 loc) • 4.4 kB
Markdown
# Webpack Typings for CSS loader
[![NPM][npm-image]][npm-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![Build][build-image]][build-url]
> Webpack loader that generates TypeScript typings for CSS modules
## Installation
```
npm install webpack-typings-for-css --save-dev
```
**webpack.config.js**
```javascript
module.exports = {
module: {
rules: [{
test: /\.css$/,
use: [{
loader: 'style-loader'
}, {
loader: 'webpack-typings-for-css'
}, {
loader: 'css-loader',
options: {
localsConvention: 'camelCaseOnly',
modules: {
localIdentName: '[name]__[local]__[hash:base64]'
}
}
}]
}]
}
};
```
## Example
Let's say we are building a simple React button component. And we have this file:
`./src/button/style.scss` in our project with the following content:
```scss
.button {
color: black;
background: white;
font-size: 12px;
padding: 10px;
&--small {
padding: 5px;
font-size: 10px;
}
&--large {
padding: 20px;
font-size: 14px;
}
}
```
When we add the `webpack-typings-for-css` loader, this will generate a TypeScript
definition file `./src/button/style.scss.d.ts` with the following content:
```typescript
declare const styles = {
button: 'styles__button__2wmORyJZRJFrl_Mc46Dxnh',
buttonSmall: 'styles__button--small__1dezcn7Xl7U8em93APXPIU',
buttonLarge: 'styles__button--large__2GA-bPwea6oWSnVWqjy_ux',
} as const;
export type ClassName = (
'styles__button__2wmORyJZRJFrl_Mc46Dxnh' |
'styles__button--small__1dezcn7Xl7U8em93APXPIU' |
'styles__button--large__2GA-bPwea6oWSnVWqjy_ux'
);
export default styles;
```
In your Typescript file you will now be able to import this file and get type hints
with the available classNames. The values for these properties are the final classNames
that are generated by the css-loader. In our example they are hashed:
```typescript
import styles from './styles.scss';
console.log(styles.button); // styles__button__wzc-BjG34gg0YTmmp71Mh
console.log(styles.buttonSmall); // styles__button--small__Jl0thjpdKMgQgK4SczMV_
console.log(styles.buttonLarge); // styles__button--large__2vSRkXkjXTxZOTMAbhDH_n
```
In your (React) button component you can now use the same import and use these readable
type checked classNames to style your components!
```typescript jsx
import React from 'react';
import styles from './styles.scss';
export const Button = () => (
<button className={styles.button}>Hello World!</button>
);
```
## Known issues
As the loader generates typing files, it is wise to tell webpack to ignore them.
The fix is luckily very simple. Webpack ships with a "WatchIgnorePlugin" out of the box.
Simply add this to your webpack plugins:
```javascript
plugins: [
new webpack.WatchIgnorePlugin([
/css\.d\.ts$/
]),
...
]
```
You might see project warnings when you have not yet build the project. This happens
because Typescript cannot import SCSS, LESS or CSS files (since they are not official
modules). In order to fix this you can add a type definition to your project. You can
find the common examples in the `typings` folder of this project.
Let's say your project uses SCSS files for styling then add the following file
to your project:
**./typings/scss.d.ts**
```typescript
declare module '*.scss' {
declare const styles: {
readonly [key: string]: string;
};
export type ClassName = string;
export default styles;
}
```
**tsconfig.json**
```json
{
...
"files": [
"./typings/scss.d.ts"
],
...
}
```
[npm-url]: https://npmjs.org/package/webpack-typings-for-css
[npm-image]: https://img.shields.io/npm/v/webpack-typings-for-css.svg
[license-url]: LICENSE
[license-image]: http://img.shields.io/npm/l/webpack-typings-for-css.svg
[downloads-url]: http://npm-stat.com/charts.html?package=webpack-typings-for-css
[downloads-image]: http://img.shields.io/npm/dm/webpack-typings-for-css.svg
[build-url]: https://circleci.com/gh/ferdikoomen/webpack-typings-for-css/tree/master
[build-image]: https://circleci.com/gh/ferdikoomen/webpack-typings-for-css/tree/master.svg?style=svg