Skip to content

Commit 76d75d6

Browse files
authored
feat: inject compilerOptions into customRenderer (mrmckeb#80)
1 parent 409e8e6 commit 76d75d6

File tree

6 files changed

+62
-11
lines changed

6 files changed

+62
-11
lines changed

README.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,22 @@ for [CSS Modules](https://github.com/css-modules/css-modules).
1111

1212
## Table of contents
1313

14-
- [Installation](#installation)
15-
- [Importing CSS](#importing-css)
16-
- [Options](#options)
17-
- [Visual Studio Code](#visual-studio-code)
18-
- [Custom definitions](#custom-definitions)
19-
- [Troubleshooting](#troubleshooting)
20-
- [About this project](#about-this-project)
14+
- [typescript-plugin-css-modules](#typescript-plugin-css-modules)
15+
- [Table of contents](#table-of-contents)
16+
- [Installation](#installation)
17+
- [Importing CSS](#importing-css)
18+
- [Options](#options)
19+
- [`classnameTransform`](#classnametransform)
20+
- [`customRenderer`](#customrenderer)
21+
- [`customTemplate`](#customtemplate)
22+
- [`postCssOptions`](#postcssoptions)
23+
- [`rendererOptions`](#rendereroptions)
24+
- [Visual Studio Code](#visual-studio-code)
25+
- [Recommended usage](#recommended-usage)
26+
- [Alternative usage](#alternative-usage)
27+
- [Custom definitions](#custom-definitions)
28+
- [Troubleshooting](#troubleshooting)
29+
- [About this project](#about-this-project)
2130

2231
## Installation
2332

@@ -113,7 +122,7 @@ When a custom renderer is provided, not other renderers will be used.
113122

114123
The path to the `customRenderer` must be relative to the project root (i.e. `./myRenderer.js`).
115124

116-
The custom renderer itself should be a JavaScript file. The function will be called with two arguments: a `css` string, and an `options` object (see [`options.ts`](https://github.com/mrmckeb/typescript-plugin-css-modules/blob/master/src/options.ts#L33-L41)). It must be synchronous, and must return valid CSS.
125+
The custom renderer itself should be a JavaScript file. The function will be called with three arguments: a `css` string, an `options` object and an `compilerOptions` object that is defined in `tsconfig.json` the `tsc` used. (see [`options.ts`](https://github.com/mrmckeb/typescript-plugin-css-modules/blob/master/src/options.ts#L33-L41)). It must be synchronous, and must return valid CSS.
117126

118127
```js
119128
module.exports = (css, { fileName, logger }) => {
@@ -130,6 +139,8 @@ You can find an example custom renderer in our test fixtures ([`customRenderer.j
130139

131140
The [internal `logger`](https://github.com/mrmckeb/typescript-plugin-css-modules/blob/master/src/helpers/logger.ts) is provided for [debugging](#troubleshooting).
132141

142+
> Note: If you are working with webpack and [`less-loader`](https://www.npmjs.com/package/less-loader), you can choose resolver that webpack provided and webpack will resolve the `@import` file path that start with `~`, but `~` is not support by less natively, and the plugin will break down, then we can use `less-plugin-aliases` npm package make it works again, more details can find [here](https://github.com/mrmckeb/typescript-plugin-css-modules/issues/77) and [here](https://github.com/dancon/less-plugin-aliases)
143+
133144
#### `customTemplate`
134145

135146
The `customTemplate` is an advanced option, letting you provide a template for the generated TypeScript declarations.

src/helpers/__tests__/getDtsSnapshot.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { join } from 'path';
44
import postcss from 'postcss';
55
import postcssIcssSelectors from 'postcss-icss-selectors';
66
import postcssImportSync from 'postcss-import-sync2';
7+
import tsModule from 'typescript/lib/tsserverlibrary';
78
import { getClasses } from '../getClasses';
89
import { createExports } from '../createExports';
910
import { Logger } from '../logger';
@@ -28,6 +29,8 @@ const logger: Logger = {
2829

2930
const options: Options = {};
3031

32+
const compilerOptions: tsModule.CompilerOptions = {};
33+
3134
const processor = postcss([
3235
postcssImportSync(),
3336
postcssIcssSelectors({ mode: 'local' }),
@@ -46,6 +49,7 @@ describe('utils / cssSnapshots', () => {
4649
logger,
4750
options,
4851
processor,
52+
compilerOptions,
4953
});
5054
});
5155

@@ -101,6 +105,7 @@ describe('utils / cssSnapshots', () => {
101105
logger,
102106
options,
103107
processor,
108+
compilerOptions,
104109
});
105110

106111
expect(classes.test).toMatchSnapshot();
@@ -121,6 +126,7 @@ describe('utils / cssSnapshots', () => {
121126
logger,
122127
options,
123128
processor,
129+
compilerOptions,
124130
});
125131

126132
expect(classes).toMatchSnapshot();
@@ -145,6 +151,7 @@ describe('utils / cssSnapshots', () => {
145151
logger,
146152
options,
147153
processor,
154+
compilerOptions,
148155
});
149156

150157
expect(classes).toMatchSnapshot();

src/helpers/getClasses.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import postcss from 'postcss';
33
import less from 'less';
44
import sass from 'sass';
55
import { extractICSS } from 'icss-utils';
6+
import tsModule from 'typescript/lib/tsserverlibrary';
67
import { Logger } from './logger';
78
import { Options, CustomRenderer } from '../options';
89

@@ -28,12 +29,14 @@ export const getClasses = ({
2829
logger,
2930
options,
3031
processor,
32+
compilerOptions,
3133
}: {
3234
css: string;
3335
fileName: string;
3436
logger: Logger;
3537
options: Options;
3638
processor: postcss.Processor;
39+
compilerOptions: tsModule.CompilerOptions;
3740
}) => {
3841
try {
3942
const fileType = getFileType(fileName);
@@ -44,7 +47,11 @@ export const getClasses = ({
4447
if (options.customRenderer) {
4548
// eslint-disable-next-line @typescript-eslint/no-var-requires
4649
const customRenderer = require(options.customRenderer) as CustomRenderer;
47-
transformedCss = customRenderer(css, { fileName, logger });
50+
transformedCss = customRenderer(css, {
51+
fileName,
52+
logger,
53+
compilerOptions,
54+
});
4855
} else if (fileType === FileTypes.less) {
4956
less.render(
5057
css,

src/helpers/getDtsSnapshot.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const getDtsSnapshot = (
1212
scriptSnapshot: ts.IScriptSnapshot,
1313
options: Options,
1414
logger: Logger,
15+
compilerOptions: tsModule.CompilerOptions,
1516
) => {
1617
const css = scriptSnapshot.getText(0, scriptSnapshot.getLength());
1718

@@ -24,7 +25,14 @@ export const getDtsSnapshot = (
2425
return scriptSnapshot;
2526
}
2627

27-
const classes = getClasses({ css, fileName, logger, options, processor });
28+
const classes = getClasses({
29+
css,
30+
fileName,
31+
logger,
32+
options,
33+
processor,
34+
compilerOptions,
35+
});
2836
const dts = createExports({ classes, fileName, logger, options });
2937
return ts.ScriptSnapshot.fromString(dts);
3038
};

src/index.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) {
2626
function create(info: ts.server.PluginCreateInfo) {
2727
const logger = createLogger(info);
2828
const directory = info.project.getCurrentDirectory();
29+
const compilerOptions = info.project.getCompilerOptions();
2930

3031
// TypeScript plugins have a `cwd` of `/`, which causes issues with import resolution.
3132
process.chdir(directory);
@@ -73,7 +74,20 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) {
7374

7475
// If a custom renderer is provided, resolve the path.
7576
if (options.customRenderer) {
76-
options.customRenderer = path.resolve(directory, options.customRenderer);
77+
if (fs.existsSync(path.resolve(directory, options.customRenderer))) {
78+
options.customRenderer = path.resolve(
79+
directory,
80+
options.customRenderer,
81+
);
82+
} else if (fs.existsSync(require.resolve(options.customRenderer))) {
83+
options.customRenderer = require.resolve(options.customRenderer);
84+
} else {
85+
logger.error(
86+
new Error(
87+
`Invalid 'customRenderer', '${options.customRenderer}' does not exist.`,
88+
),
89+
);
90+
}
7791
}
7892

7993
// If a custom template is provided, resolve the path.
@@ -106,6 +120,7 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) {
106120
scriptSnapshot,
107121
options,
108122
logger,
123+
compilerOptions,
109124
);
110125
}
111126
const sourceFile = _createLanguageServiceSourceFile(
@@ -134,6 +149,7 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) {
134149
scriptSnapshot,
135150
options,
136151
logger,
152+
compilerOptions,
137153
);
138154
}
139155
sourceFile = _updateLanguageServiceSourceFile(

src/options.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Options as SassOptions } from 'sass';
2+
import tsModule from 'typescript/lib/tsserverlibrary';
23
import { DotenvConfigOptions } from 'dotenv/types';
34
import { CSSExports } from 'icss-utils';
45
import { Logger } from './helpers/logger';
@@ -33,6 +34,7 @@ export type ClassnameTransformOptions =
3334
export interface CustomRendererOptions {
3435
fileName: string;
3536
logger: Logger;
37+
compilerOptions: tsModule.CompilerOptions;
3638
}
3739

3840
export type CustomRenderer = (

0 commit comments

Comments
 (0)