Skip to content

Commit

Permalink
feat: inject compilerOptions into customRenderer (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
dancon committed Apr 27, 2020
1 parent 409e8e6 commit 76d75d6
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 11 deletions.
27 changes: 19 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,22 @@ for [CSS Modules](https://github.com/css-modules/css-modules).

## Table of contents

- [Installation](#installation)
- [Importing CSS](#importing-css)
- [Options](#options)
- [Visual Studio Code](#visual-studio-code)
- [Custom definitions](#custom-definitions)
- [Troubleshooting](#troubleshooting)
- [About this project](#about-this-project)
- [typescript-plugin-css-modules](#typescript-plugin-css-modules)
- [Table of contents](#table-of-contents)
- [Installation](#installation)
- [Importing CSS](#importing-css)
- [Options](#options)
- [`classnameTransform`](#classnametransform)
- [`customRenderer`](#customrenderer)
- [`customTemplate`](#customtemplate)
- [`postCssOptions`](#postcssoptions)
- [`rendererOptions`](#rendereroptions)
- [Visual Studio Code](#visual-studio-code)
- [Recommended usage](#recommended-usage)
- [Alternative usage](#alternative-usage)
- [Custom definitions](#custom-definitions)
- [Troubleshooting](#troubleshooting)
- [About this project](#about-this-project)

## Installation

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

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

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.
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.

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

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

> 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)
#### `customTemplate`

The `customTemplate` is an advanced option, letting you provide a template for the generated TypeScript declarations.
Expand Down
7 changes: 7 additions & 0 deletions src/helpers/__tests__/getDtsSnapshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { join } from 'path';
import postcss from 'postcss';
import postcssIcssSelectors from 'postcss-icss-selectors';
import postcssImportSync from 'postcss-import-sync2';
import tsModule from 'typescript/lib/tsserverlibrary';
import { getClasses } from '../getClasses';
import { createExports } from '../createExports';
import { Logger } from '../logger';
Expand All @@ -28,6 +29,8 @@ const logger: Logger = {

const options: Options = {};

const compilerOptions: tsModule.CompilerOptions = {};

const processor = postcss([
postcssImportSync(),
postcssIcssSelectors({ mode: 'local' }),
Expand All @@ -46,6 +49,7 @@ describe('utils / cssSnapshots', () => {
logger,
options,
processor,
compilerOptions,
});
});

Expand Down Expand Up @@ -101,6 +105,7 @@ describe('utils / cssSnapshots', () => {
logger,
options,
processor,
compilerOptions,
});

expect(classes.test).toMatchSnapshot();
Expand All @@ -121,6 +126,7 @@ describe('utils / cssSnapshots', () => {
logger,
options,
processor,
compilerOptions,
});

expect(classes).toMatchSnapshot();
Expand All @@ -145,6 +151,7 @@ describe('utils / cssSnapshots', () => {
logger,
options,
processor,
compilerOptions,
});

expect(classes).toMatchSnapshot();
Expand Down
9 changes: 8 additions & 1 deletion src/helpers/getClasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import postcss from 'postcss';
import less from 'less';
import sass from 'sass';
import { extractICSS } from 'icss-utils';
import tsModule from 'typescript/lib/tsserverlibrary';
import { Logger } from './logger';
import { Options, CustomRenderer } from '../options';

Expand All @@ -28,12 +29,14 @@ export const getClasses = ({
logger,
options,
processor,
compilerOptions,
}: {
css: string;
fileName: string;
logger: Logger;
options: Options;
processor: postcss.Processor;
compilerOptions: tsModule.CompilerOptions;
}) => {
try {
const fileType = getFileType(fileName);
Expand All @@ -44,7 +47,11 @@ export const getClasses = ({
if (options.customRenderer) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const customRenderer = require(options.customRenderer) as CustomRenderer;
transformedCss = customRenderer(css, { fileName, logger });
transformedCss = customRenderer(css, {
fileName,
logger,
compilerOptions,
});
} else if (fileType === FileTypes.less) {
less.render(
css,
Expand Down
10 changes: 9 additions & 1 deletion src/helpers/getDtsSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const getDtsSnapshot = (
scriptSnapshot: ts.IScriptSnapshot,
options: Options,
logger: Logger,
compilerOptions: tsModule.CompilerOptions,
) => {
const css = scriptSnapshot.getText(0, scriptSnapshot.getLength());

Expand All @@ -24,7 +25,14 @@ export const getDtsSnapshot = (
return scriptSnapshot;
}

const classes = getClasses({ css, fileName, logger, options, processor });
const classes = getClasses({
css,
fileName,
logger,
options,
processor,
compilerOptions,
});
const dts = createExports({ classes, fileName, logger, options });
return ts.ScriptSnapshot.fromString(dts);
};
18 changes: 17 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) {
function create(info: ts.server.PluginCreateInfo) {
const logger = createLogger(info);
const directory = info.project.getCurrentDirectory();
const compilerOptions = info.project.getCompilerOptions();

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

// If a custom renderer is provided, resolve the path.
if (options.customRenderer) {
options.customRenderer = path.resolve(directory, options.customRenderer);
if (fs.existsSync(path.resolve(directory, options.customRenderer))) {
options.customRenderer = path.resolve(
directory,
options.customRenderer,
);
} else if (fs.existsSync(require.resolve(options.customRenderer))) {
options.customRenderer = require.resolve(options.customRenderer);
} else {
logger.error(
new Error(
`Invalid 'customRenderer', '${options.customRenderer}' does not exist.`,
),
);
}
}

// If a custom template is provided, resolve the path.
Expand Down Expand Up @@ -106,6 +120,7 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) {
scriptSnapshot,
options,
logger,
compilerOptions,
);
}
const sourceFile = _createLanguageServiceSourceFile(
Expand Down Expand Up @@ -134,6 +149,7 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) {
scriptSnapshot,
options,
logger,
compilerOptions,
);
}
sourceFile = _updateLanguageServiceSourceFile(
Expand Down
2 changes: 2 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Options as SassOptions } from 'sass';
import tsModule from 'typescript/lib/tsserverlibrary';
import { DotenvConfigOptions } from 'dotenv/types';
import { CSSExports } from 'icss-utils';
import { Logger } from './helpers/logger';
Expand Down Expand Up @@ -33,6 +34,7 @@ export type ClassnameTransformOptions =
export interface CustomRendererOptions {
fileName: string;
logger: Logger;
compilerOptions: tsModule.CompilerOptions;
}

export type CustomRenderer = (
Expand Down

0 comments on commit 76d75d6

Please sign in to comment.