Skip to content

Feature: having postcss syntax configurable #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
<PROJECT_ROOT>/node_modules/config-chain/test/broken.json
<PROJECT_ROOT>/node_modules/conventional-changelog-core/test/fixtures/_malformation.json
<PROJECT_ROOT>/node_modules/npmconf/test/fixtures/package.json

[options]
module.ignore_non_literal_requires=true
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ In contrast to [`react-css-modules`](https://github.com/gajus/react-css-modules)
* [Anonymous reference](#anonymous-reference)
* [Named reference](#named-reference)
* [Configuration](#configuration)
* [Configurate syntax loaders](#configurate-syntax-loaders)
* [Installation](#installation)
* [Example transpilations](#example-transpilations)
* [Anonymous `styleName` resolution](#anonymous-stylename-resolution)
Expand Down Expand Up @@ -167,14 +168,33 @@ NODE_ENV=production ./test

|Name|Description|Default|
|---|---|---|
|`generateScopedName`|Refer to [Generating scoped names](https://github.com/css-modules/postcss-modules#generating-scoped-names)|`[path]___[name]__[local]___[hash:base64:5]`|
|`context`|Must match webpack [`context`](https://webpack.github.io/docs/configuration.html#context) configuration. [`css-loader`](https://github.com/webpack/css-loader) inherits `context` values from webpack. Other CSS module implementations might use different context resolution logic.|`process.cwd()`|
|`filetypes`|Configure [postcss syntax loaders](https://github.com/postcss/postcss#syntaxes) like sugerss, LESS and SCSS. ||
|`generateScopedName`|Refer to [Generating scoped names](https://github.com/css-modules/postcss-modules#generating-scoped-names)|`[path]___[name]__[local]___[hash:base64:5]`|

Missing a configuration? [Raise an issue](https://github.com/gajus/babel-plugin-react-css-modules/issues/new?title=New%20configuration:).

> Note:
> The default configuration should work out of the box with the [css-loader](https://github.com/webpack/css-loader).

### Configurate syntax loaders

To add support for different CSS syntaxes (e.g. SCSS), perform the following two steps:

1. Add the [postcss syntax loader](https://github.com/postcss/postcss#syntaxes) as a development dependency:

```bash
npm install postcss-scss --save-dev
```

2. Add a filetype syntax mapping to the Babel plugin configuration

```json
"filetypes": {
".scss": "postcss-scss"
}
```

## Installation

When `babel-plugin-react-css-modules` cannot resolve CSS module at a compile time, it imports a helper function (read [Runtime `styleName` resolution](#runtime-stylename-resolution)). Therefore, you must install `babel-plugin-react-css-modules` as a direct dependency of the project.
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
"postcss-modules-local-by-default": "^1.1.1",
"postcss-modules-parser": "^1.1.0",
"postcss-modules-scope": "^1.0.2",
"postcss-modules-values": "^1.2.2",
"postcss-scss": "^0.4.0"
"postcss-modules-values": "^1.2.2"
},
"description": "Transforms styleName to className using compile time CSS module resolution.",
"devDependencies": {
Expand All @@ -31,7 +30,9 @@
"flow-bin": "^0.37.4",
"husky": "^0.12.0",
"mocha": "^3.2.0",
"semantic-release": "^6.3.5"
"semantic-release": "^6.3.5",
"postcss-less": "^0.15.0",
"postcss-scss": "^0.4.0"
},
"engines": {
"node": ">5.0.0"
Expand Down
7 changes: 6 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ export default ({
inherits: babelPluginJsxSyntax,
visitor: {
ImportDeclaration (path: Object, stats: Object): void {
if (!path.node.source.value.endsWith('.css') && !path.node.source.value.endsWith('.scss')) {
stats.opts.filetypes = stats.opts.filetypes || {};

const extension = path.node.source.value.lastIndexOf('.') > -1 ? path.node.source.value.substr(path.node.source.value.lastIndexOf('.')) : null;

if (extension !== '.css' && Object.keys(stats.opts.filetypes).indexOf(extension) < 0) {
return;
}

Expand All @@ -84,6 +88,7 @@ export default ({
}

filenameMap[filename].styleModuleImportMap[styleImportName] = requireCssModule(targetResourcePath, {
filetypes: stats.opts.filetypes || {},
generateScopedName: stats.opts.generateScopedName
});
},
Expand Down
16 changes: 9 additions & 7 deletions src/requireCssModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,21 @@ import LocalByDefault from 'postcss-modules-local-by-default';
import Parser from 'postcss-modules-parser';
import Scope from 'postcss-modules-scope';
import Values from 'postcss-modules-values';
import ScssSyntax from 'postcss-scss';
import type {
StyleModuleMapType
} from './types';

const getTokens = (runner, cssSourceFilePath: string): StyleModuleMapType => {
const sourceFilePathIsScss = cssSourceFilePath.endsWith('.scss');
const getTokens = (runner, cssSourceFilePath: string, filetypes): StyleModuleMapType => {
const extension = cssSourceFilePath.substr(cssSourceFilePath.lastIndexOf('.'));
const syntax = filetypes[extension];

const options: Object = {
from: cssSourceFilePath
};

if (sourceFilePathIsScss) {
options.syntax = ScssSyntax;
if (syntax) {
// eslint-disable-next-line import/no-dynamic-require, global-require
options.syntax = require(syntax);
}

const lazyResult = runner
Expand All @@ -44,6 +45,7 @@ const getTokens = (runner, cssSourceFilePath: string): StyleModuleMapType => {
};

type OptionsType = {|
filetypes: Object,
generateScopedName?: string,
context?: string
|};
Expand All @@ -60,7 +62,7 @@ export default (cssSourceFilePath: string, options: OptionsType): StyleModuleMap
const fromDirectoryPath = dirname(from);
const toPath = resolve(fromDirectoryPath, to);

return getTokens(runner, toPath);
return getTokens(runner, toPath, options.filetypes);
};

const plugins = [
Expand All @@ -77,5 +79,5 @@ export default (cssSourceFilePath: string, options: OptionsType): StyleModuleMap

runner = postcss(plugins);

return getTokens(runner, cssSourceFilePath);
return getTokens(runner, cssSourceFilePath, options.filetypes);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './bar.less';

<div styleName="a"></div>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@color: #f00;

.a {background-color: @color;}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import './bar.less';

<div className="bar__a"></div>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"plugins": [
[
"../../../../src",
{
"generateScopedName": "[name]__[local]",
"filetypes": {
".less": "postcss-less"
}
}
]
]
}