terriajs-typings-for-css-modules-loader
Version:
Webpack loader that generates TypeScript typings for CSS modules from css-loader on the fly
354 lines (295 loc) • 9.95 kB
Markdown
[![npm][npm]][npm-url]
[![build][build]][build-url]
[![deps][deps]][deps-url]
Note: This repo is a fork of [jdelStrother/typings-for-css-modules-loader#css-loader-7](https://github.com/jdelStrother/typings-for-css-modules-loader/tree/css-loader-7) that makes `fixes typings-for-css-modules-loader` work with css-loader version > 7.
# typings-for-css-modules-loader
Webpack loader that generates TypeScript typings for CSS modules from css-loader on the fly
## Disclaimer
This repository is a fork of the unmaintained https://github.com/Jimdo/typings-for-css-modules-loader repository.
## Installation
Install via npm `npm install --save-dev @teamsupercell/typings-for-css-modules-loader`
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
"@teamsupercell/typings-for-css-modules-loader",
{
loader: "css-loader",
options: { modules: true }
}
]
}
]
}
};
```
## Options
| Name | Type | Description |
| :-----------------------------------------------: | :---------: | :----------------------------------------------------------: |
| **[`banner`](#banner)** | `{String}` | To add a 'banner' prefix to each generated `*.d.ts` file |
| **[`formatter`](#formatter)** | `{String}` | Formats the generated `*.d.ts` file with specified formatter, eg. `prettier` |
| **[`eol`](#eol)** | `{String}` | Newline character to be used in generated `*.d.ts` files |
| **[`verifyOnly`](#verifyOnly)** | `{Boolean}` | Validate generated `*.d.ts` files and fail if an update is needed (useful in CI) |
| **[`disableLocalsExport`](#disableLocalsExport)** | `{Boolean}` | Disable the use of locals export. |
| **[`prettierConfigFile`](#prettierConfigFile)** | `{String}` | Path to prettier config file |
### `banner`
To add a "banner" prefix to each generated `*.d.ts` file, you can pass a string to this option as shown below. The prefix is quite literally prefixed into the generated file, so please ensure it conforms to the type definition syntax.
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: "@teamsupercell/typings-for-css-modules-loader",
options: {
banner:
"// autogenerated by typings-for-css-modules-loader. \n// Please do not change this file!"
}
},
{
loader: "css-loader",
options: { modules: true }
}
]
}
]
}
};
```
### `formatter`
Possible options: `none` and `prettier` (requires `prettier` package to be installed). Defaults to prettier if `prettier` module can be resolved.
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: "@teamsupercell/typings-for-css-modules-loader",
options: {
formatter: "prettier"
}
},
{
loader: "css-loader",
options: { modules: true }
}
]
}
]
}
};
```
### `eol`
Newline character to be used in generated `*.d.ts` files. By default a value from `require('os').eol` is used.
This option is ignored when [`formatter`](#formatter) `prettier` is used.
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: "@teamsupercell/typings-for-css-modules-loader",
options: {
eol: "\r\n"
}
},
{
loader: "css-loader",
options: { modules: true }
}
]
}
]
}
};
```
### `verifyOnly`
Validate generated `*.d.ts` files and fail if an update is needed (useful in CI).
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: "@teamsupercell/typings-for-css-modules-loader",
options: {
verifyOnly: process.env.NODE_ENV === 'production'
}
},
{
loader: "css-loader",
options: { modules: true }
}
]
}
]
}
};
```
### `disableLocalsExport`
Disable the use of locals export. Defaults to `false`.
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: "@teamsupercell/typings-for-css-modules-loader",
options: {
disableLocalsExport: true
}
},
{
loader: "css-loader",
options: { modules: true }
}
]
}
]
}
};
```
### `prettierConfigFile`
Path to the prettier config file
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
{
loader: "@teamsupercell/typings-for-css-modules-loader",
options: {
prettierConfigFile: resolve(__dirname, '../.prettierrc'),
}
},
{
loader: "css-loader",
options: { modules: true }
}
]
}
]
}
};
```
## Example
Imagine you have a file `~/my-project/src/component/MyComponent/myComponent.scss` in your project with the following content:
```scss
.some-class {
// some styles
&.someOtherClass {
// some other styles
}
&-sayWhat {
// more styles
}
}
```
Adding the `typings-for-css-modules-loader` will generate a file `~/my-project/src/component/MyComponent/myComponent.scss.d.ts` that has the following content:
```ts
declare namespace MyComponentScssModule {
export interface IMyComponentScss {
"some-class": string;
someOtherClass: string;
"some-class-sayWhat": string;
}
}
declare const MyComponentScssModule: MyComponentScssModule.IMyComponentScss & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: MyComponentScssModule.IMyComponentScss;
};
export = MyComponentScssModule;
```
```ts
// using wildcard export when used with style-loader or mini-css-extract-plugin
// or default export only when typescript `esModuleInterop` enabled
import * as styles from "./myComponent.scss";
console.log(styles["some-class"]);
console.log(styles.someOtherClass);
```
```ts
// using locals export when used without style-loader or mini-css-extract-plugin
import { locals } from "./myComponent.scss";
console.log(locals["some-class"]);
console.log(locals.someOtherClass);
```
### Example in Visual Studio Code

## Upgrade from v1:
- Update webpack config
- This package no longer replaces `css-loader`, but it has to be added alongside `css-loader`:
- `css-loader` is no longer a peer dependency due to the change above
- `css-loader` will need to be configured to output CSS Modules (e.g. `options: { modules: true; }`)
```diff
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: [
"style-loader",
{
loader: "@teamsupercell/typings-for-css-modules-loader",
options: {
// pass all the options for `css-loader` to `css-loader`, eg.
- namedExport: true,
- modules: true
}
},
+ {
+ loader: "css-loader",
+ options: {
+ modules: true
+ }
+ },
]
}
]
}
};
```
## Support
As the loader just acts as an intermediary it can handle all kind of css preprocessors (`sass`, `scss`, `stylus`, `less`, ...).
The only requirement is that those preprocessors have proper webpack loaders defined - meaning they can already be loaded by webpack anyways.
## Requirements
The loader is supposed to be used with `css-loader`(https://github.com/webpack/css-loader). Thus it is a peer-dependency and the expected loader to create CSS Modules.
## Known issues
### Webpack rebuilds / builds slow
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:
```
plugins: [
new webpack.WatchIgnorePlugin([
/css\.d\.ts$/
]),
...
]
```
where `css` is the file extension of your style files. If you use `sass` you need to put `sass` here instead. If you use `less`, `stylus` or any other style language use their file ending.
### Typescript does not find the typings
As the webpack process is independent from your typescript "runtime" it may take a while for typescript to pick up the typings.
It is possible to write a custom webpack plugin using the `fork-ts-checker-service-before-start` hook from https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#plugin-hooks to delay the start of type checking until all the `*.d.ts` files are generated. Potentially, this plugin can be included in this repository.
[npm]: https://img.shields.io/npm/v/@teamsupercell/typings-for-css-modules-loader.svg
[npm-url]: https://npmjs.com/package/@teamsupercell/typings-for-css-modules-loader
[build]: https://travis-ci.com/TeamSupercell/typings-for-css-modules-loader.svg?branch=master
[build-url]: https://travis-ci.com/TeamSupercell/typings-for-css-modules-loader
[deps]: https://david-dm.org/@teamsupercell/typings-for-css-modules-loader.svg
[deps-url]: https://david-dm.org/@teamsupercell/typings-for-css-modules-loader