Skip to content

Commit 5c52e51

Browse files
Merge pull request michalkvasnicak#9 from jvivs/add-extension-support
add support for file extensions beyond .css
2 parents ddb71bc + 9e370c2 commit 5c52e51

File tree

6 files changed

+80
-8
lines changed

6 files changed

+80
-8
lines changed

README.md

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ console.log(styles.someClass); // prints Test__someClass___2Frqu
4242
npm install --save-dev babel-plugin-css-modules-transform
4343
```
4444

45-
**Include plugin to `.babelrc`**
45+
**Include plugin in `.babelrc`**
4646

4747
```json
4848
{
@@ -57,14 +57,15 @@ npm install --save-dev babel-plugin-css-modules-transform
5757
{
5858
"plugins": [
5959
[
60-
"css-modules-transform", {
60+
"css-modules-transform", {
6161
"generateScopedName": "[name]__[local]___[hash:base64:5]", // in case you don't want to use a function
6262
"generateScopedName": "./path/to/module-exporting-a-function.js", // in case you want to use a function
6363
"generateScopedName": "npm-module-name",
6464
"preprocessCss": "./path/to/module-exporting-a-function.js",
6565
"preprocessCss": "npm-module-name",
6666
"processCss": "./path/to/module-exporting-a-function.js",
6767
"processCss": "npm-module-name",
68+
"extensions": [".css", ".scss", ".less"], // list extensions to process; defaults to .css
6869
"append": [
6970
"npm-module-name",
7071
"./path/to/module-exporting-a-function.js"
@@ -79,6 +80,42 @@ npm install --save-dev babel-plugin-css-modules-transform
7980
}
8081
```
8182

83+
## Using a preprocessor
84+
85+
When using this plugin with a preprocessor, you'll need to configure it as such:
86+
87+
88+
```
89+
// ./path/to/module-exporting-a-function.js
90+
var sass = require('node-sass');
91+
var path = require('path');
92+
93+
module.exports = function processSass(data, filename) {
94+
var result;
95+
result = sass.renderSync({
96+
data: data,
97+
file: filename
98+
}).css;
99+
return result.toString('utf8');
100+
};
101+
```
102+
103+
and then add any relevant extensions to your plugin config:
104+
105+
```
106+
{
107+
"plugins": [
108+
[
109+
"css-modules-transform", {
110+
"preprocessCss": "./path/to/module-exporting-a-function.js",
111+
"extensions": [".css", ".scss"]
112+
}
113+
]
114+
]
115+
}
116+
117+
```
118+
82119
## License
83120

84121
MIT

src/index.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,25 @@ export default function transformCssModules({ types: t }) {
3131
* @returns {Array} array of class names
3232
*/
3333
function requireCssFile(filepath, cssFile) {
34-
const from = resolveModulePath(filepath);
35-
return require(resolve(from, cssFile));
34+
let filePathOrModuleName = cssFile;
35+
36+
// only resolve path to file when we have a file path
37+
if (!/^\w/i.test(filePathOrModuleName)) {
38+
const from = resolveModulePath(filepath);
39+
filePathOrModuleName = resolve(from, filePathOrModuleName);
40+
}
41+
return require(filePathOrModuleName);
3642
}
3743

3844
// is css modules require hook initialized?
3945
let initialized = false;
4046

47+
let matchExtensions = /\.css/i;
48+
function matcher(extensions = ['.css']) {
49+
const extensionsPatern = extensions.join('|').replace('.', '\.');
50+
return new RegExp(`(${extensionsPatern})`, 'i');
51+
}
52+
4153
return {
4254
visitor: {
4355
Program(path, { opts }) {
@@ -47,6 +59,10 @@ export default function transformCssModules({ types: t }) {
4759

4860
const currentConfig = { ...defaultOptions, ...opts };
4961

62+
// match file extensions, speeds up transform by creating one
63+
// RegExp ahead of execution time
64+
matchExtensions = matcher(currentConfig.extensions);
65+
5066
// check if there are simple requires and if they are functions
5167
simpleRequires.forEach(key => {
5268
if (typeof currentConfig[key] !== 'string') {
@@ -133,17 +149,18 @@ export default function transformCssModules({ types: t }) {
133149
return;
134150
}
135151

136-
if (/\.css/i.test(args[0].value)) {
137-
const [ { value: cssPath }] = args;
152+
const [{ value: stylesheetPath }] = args;
138153

154+
if (matchExtensions.test(stylesheetPath)) {
139155
// if parent expression is variable declarator, replace right side with tokens
140156
if (!t.isVariableDeclarator(path.parent)) {
141157
throw new Error(
142-
`You can't import css file ${cssPath} to a module scope.`
158+
`You can't import css file ${stylesheetPath} to a module scope.`
143159
);
144160
}
145161

146-
const tokens = requireCssFile(file.opts.filename, args[0].value);
162+
const requiringFile = file.opts.filename;
163+
const tokens = requireCssFile(requiringFile, stylesheetPath);
147164

148165
/* eslint-disable new-cap */
149166
path.replaceWith(t.ObjectExpression(

test/extensions.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.sassy {
2+
display: block;
3+
color: pink;
4+
}

test/fixtures/extensions.expected.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
3+
var css = {
4+
'className': 'styles__className___385m0 parent__block___33Sxl'
5+
};
6+
var scss = {
7+
'sassy': 'extensions__sassy___12Yag'
8+
};

test/fixtures/extensions.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
var css = require('../styles.css');
2+
var scss = require('../extensions.scss');

test/index.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,8 @@ describe('babel-plugin-css-modules-transform', () => {
136136

137137
stream.end();
138138
});
139+
140+
it('should accept file extensions as an array', () => {
141+
expect(transform('fixtures/extensions.js', {extensions: ['.scss', '.css']}).code).to.be.equal(readExpected('fixtures/extensions.expected.js'));
142+
});
139143
});

0 commit comments

Comments
 (0)