https://github.com/budarin/ts-css-loader
Webpack loader to generate typescript definitions for css-modules for isomorphic apps
https://github.com/budarin/ts-css-loader
css-modules isomorphic-applications style-loader typescript webpack-loader
Last synced: 10 days ago
JSON representation
Webpack loader to generate typescript definitions for css-modules for isomorphic apps
- Host: GitHub
- URL: https://github.com/budarin/ts-css-loader
- Owner: budarin
- License: mit
- Created: 2018-09-14T19:37:36.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2020-05-26T16:23:41.000Z (almost 5 years ago)
- Last Synced: 2025-05-09T10:01:52.550Z (15 days ago)
- Topics: css-modules, isomorphic-applications, style-loader, typescript, webpack-loader
- Language: JavaScript
- Homepage:
- Size: 483 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# @budarin/ts-css-loader
This loader is a fork of the well-known loader [typings-for-css-modules-loader](https://github.com/Jimdo/typings-for-css-modules-loader)
The purpose of creating yet another typescript generation loader for css-modules is the ability to use it in an isomorphic application in conjunction with [style-loader/usable](https://github.com/webpack-contrib/style-loader)(is used in browser to use or unse component's stylesheets) and [fake-style-loader](https://github.com/dferber90/fake-style-loader)(is used on server side to get source css from component's stylesheet).
`style-loader/usable` adds 2 methods to the css-modules interface:
- `use: Function`
- `unuse: Function``fake-style-loader` adds properties to the css-modules interface:
- `source: String`
- all classnames into default exported object## `Installation`
Install via npm `npm install --save-dev @budarin/ts-css-loader`
## `Options`
All options are available only when the parameter `modules` set to `true`(see options for [css-loader](https://github.com/webpack-contrib/css-loader#options))
| Name | Type | Default | Description |
| :---------------------------------------: | :---------: | :-----: | :------------------------------------------------------------------------- |
| **[`EOL`](#EOL)** | `{String}` | `CRLF` | {'CRLF', 'LF'} |
| **[`onlyNamedExport`](#onlyNamedExport)** | `{Boolean}` | `false` | Export only named items of interface |
| **[`browser`](#browser)** | `{Boolean}` | `false` | Add `use` and `unuse` methods to interface and all classnames in flat view |
| **[`server`](#server)** | `{Boolean}` | `false` | Add `source` property to interface |
| **[`tabWidth`](#tabWidth)** | `{Number}` | 4 | Set tabWidth for indentation |
| **[`silent`](#silent)** | `{Boolean}` | `false` | To silence the loader |
| **[`banner`](#banner)** | `{Boolean}` | `false` | Adds a "banner" prefix to each generated \*.d.ts |the other parameters are the same as the `css-loader`:
This loader should be used instead of` css-loader ' because inside it uses it.
An example of using webpack.config:
```js
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: '@budarin/ts-css-loader',
options: {
modules: true,
},
}
]
```for style file `app.css`:
```css
.foo {
color: red;
}
```the loader will generate a type definition:
```ts
declare interface IAppCss {
readonly foo: string;
}
declare const styles: IAppCss;export default styles;
```### `EOL`
Default: `'CRLF'`.
Defines a line separator in type definition file and must be equal to the parameter set in `git` to prevent constant overwriting of type definition file.
This parameter can take one of these acronims `{'CRLF','LF`}'```js
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: '@budarin/ts-css-loader',
options: {
modules: true,
EOL: 'LF'
}
}
]
```### `onlyNamedExport`
Default: `false`.
This parameter determines whether only named exports are present in the module interface
```js
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: '@budarin/ts-css-loader',
options: {
modules: true,
onlyNamedExport: true
}
}
]
```output:
```ts
export const foo: string;
```### `browser`
Default: `false`.
The parameter determines the presence of `style-loader/disable` methods in the interface: `use` and `unuse`.
```js
test: /\.css$/,
use: [
{
loader: 'style-loader/usable',
},
{
loader: '@budarin/ts-css-loader',
options: {
modules: true,
browser: true
}
}
]
```output:
```ts
declare interface IAppCss {
readonly locals: {
readonly foo: string;
};
readonly use: Function;
readonly unuse: Function;
}
declare const styles: IAppCss;export default styles;
```### `server`
Default: `false`.
Determines the presence of the interface property `source: string` for `fake-style-loader` and presene all css classes in default export
```js
test: /\.css$/,
use: [
{
loader: 'fake-style-loader',
},
{
loader: '@budarin/ts-css-loader',
options: {
modules: true,
server: true
}
}
]
```output:
```ts
declare interface IAppCss {
readonly foo: string;
readonly source: string;
}
declare const styles: IAppCss;export default styles;
```### `tabWidth`
Default: 4.
Number of spaces it should use per tab
### `silent`
Default: `false`.
To silence the loader because you get annoyed by its warnings or for other reasons, you can simply pass the "silent" query to the loader and it will shut up.
e.g.:```js
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: '@budarin/ts-css-loader',
options: {
modules: false,
}
}
]
```### `banner`
Default: `false`..
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
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: '@budarin/ts-css-loader',
options: {
modules: true,
banner: "// This file is automatically generated file.\n// Please do not change this file!"
}
}
]
```output:
```ts
// This file is automatically generated file
// Please do not change this file!"
declare interface IAppCss {
readonly locals: {
readonly foo: string;
};
}
declare const styles: IAppCss;export default styles;
```For isomorphic applications, you can use the following configuration:
```js
test: /\.css$/,
use: [
{
loader: ...
},
{
loader: '@budarin/ts-css-loader',
options: {
modules: true,
browser: true,
server: true
}
}
]
```output:
```ts
declare interface IAppCss {
readonly locals: {
readonly foo: string;
};
readonly use: Function;
readonly unuse: Function;
readonly source: string;
}
declare const styles: IAppCss;export default styles;
```### using `onlyNamedExport` with the `camelCase`
Using the `onlyNamedExport` as well as the `camelCase` options the generated file will look as follow:
```ts
export const someClass: string;
export const someOtherClass: string;
export const someClassSayWhat: string;
```### Example in Visual Studio Code

If you encounter the following errors:
```
error TS1192: Module '"xxxxx/xxxx/src/style.sass"' has no default export.
```maybe you should export the styles as following:
```
import * as styles from './style.sass';
```## 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 uses `css-loader`(https://github.com/webpack/css-loader) under the hood. 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 doesnt 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.
Any hints on how this could be fixed deterministically are welcome!