Skip to content

Commit e85242b

Browse files
add keepImport option, closes #65
1 parent 383c773 commit e85242b

File tree

5 files changed

+95
-4
lines changed

5 files changed

+95
-4
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,24 @@ To extract all files in a single directory, give an object:
175175
Note that `relativeRoot` is used to resolve relative directory names, available
176176
as `[path]` in `filename` pattern.
177177

178+
## Keeping import
179+
180+
To keep import statements you should set option `keepImport` to *true*. In this way, simultaneously with the converted values, the import will be described as unassigned call expression.
181+
182+
```js
183+
// before
184+
const styles = require('./test.css');
185+
```
186+
187+
```js
188+
// after
189+
require('./test.css');
190+
191+
const styles = {
192+
'someClass': 'Test__someClass___2Frqu'
193+
}
194+
```
195+
178196
## Alternatives
179197

180198
- [babel-plugin-transform-postcss](https://github.com/wbyoung/babel-plugin-transform-postcss) - which supports async plugins and does not depend on `css-modules-require-hook`.

src/index.js

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ const defaultOptions = {
1010
generateScopedName: '[name]__[local]___[hash:base64:5]'
1111
};
1212

13+
function findExpressionStatementChild(path, t) {
14+
const parent = path.parentPath;
15+
if (!parent) {
16+
throw new Error('Invalid expression structure');
17+
}
18+
if (
19+
t.isExpressionStatement(parent)
20+
|| t.isProgram(parent)
21+
|| t.isBlockStatement(parent)
22+
) {
23+
return path;
24+
}
25+
return findExpressionStatementChild(parent, t);
26+
}
27+
1328
export default function transformCssModules({ types: t }) {
1429
function resolveModulePath(filename) {
1530
const dir = dirname(filename);
@@ -91,6 +106,7 @@ export default function transformCssModules({ types: t }) {
91106
const currentConfig = { ...defaultOptions, ...thisPluginOptions };
92107
// this is not a css-require-ook config
93108
delete currentConfig.extractCss;
109+
delete currentConfig.keepImport;
94110

95111
// match file extensions, speeds up transform by creating one
96112
// RegExp ahead of execution time
@@ -154,14 +170,29 @@ export default function transformCssModules({ types: t }) {
154170
const requiringFile = file.opts.filename;
155171
const tokens = requireCssFile(requiringFile, value);
156172

157-
path.parentPath.replaceWith(
158-
t.variableDeclaration('var', [
173+
const varDeclaration = t.variableDeclaration(
174+
'var',
175+
[
159176
t.variableDeclarator(
160177
t.identifier(path.node.local.name),
161178
buildClassNameToScopeNameMap(tokens)
162179
)
163-
]),
180+
]
164181
);
182+
183+
if (thisPluginOptions.keepImport === true) {
184+
path.parentPath.replaceWithMultiple([
185+
t.expressionStatement(
186+
t.callExpression(
187+
t.identifier('require'),
188+
[t.stringLiteral(value)]
189+
)
190+
),
191+
varDeclaration
192+
]);
193+
} else {
194+
path.parentPath.replaceWith(varDeclaration);
195+
}
165196
}
166197
},
167198

@@ -183,7 +214,19 @@ export default function transformCssModules({ types: t }) {
183214
// Otherwise remove require from file, we just want to get generated css for our output
184215
if (!t.isExpressionStatement(path.parent)) {
185216
path.replaceWith(buildClassNameToScopeNameMap(tokens));
186-
} else {
217+
218+
// Keeped import will places before closest expression statement child
219+
if (thisPluginOptions.keepImport === true) {
220+
findExpressionStatementChild(path, t).insertBefore(
221+
t.expressionStatement(
222+
t.callExpression(
223+
t.identifier('require'),
224+
[t.stringLiteral(stylesheetPath)]
225+
)
226+
)
227+
);
228+
}
229+
} else if (thisPluginOptions.keepImport !== true) {
187230
path.remove();
188231
}
189232
}

test/fixtures/keepImport.expected.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use strict';
2+
3+
require('../styles.css');
4+
5+
var css = {
6+
'className': 'styles__className___385m0 parent__block___33Sxl child__line___3fweh'
7+
};
8+
9+
require('../extensions.scss');
10+
11+
var scss = {
12+
'sassy': 'extensions__sassy___12Yag'
13+
};
14+
require('../extensions.scss');
15+
var foo = require('something-that-has-css-somewhere-in-the-name');
16+
var bar = require('something-that-has-scss-somewhere-in-the-name');

test/fixtures/keepImport.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import css from '../styles.css';
2+
var scss = require('../extensions.scss');
3+
require('../extensions.scss');
4+
var foo = require('something-that-has-css-somewhere-in-the-name');
5+
var bar = require('something-that-has-scss-somewhere-in-the-name');

test/index.spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,13 @@ describe('babel-plugin-css-modules-transform', () => {
292292
'styles.css'
293293
]);
294294
});
295+
296+
describe('keepImport option', () => {
297+
it('keeps requires/imports', () => {
298+
expect(transform('fixtures/keepImport.js', {
299+
keepImport: true,
300+
extensions: ['.scss', '.css']
301+
}).code).to.be.equal(readExpected('fixtures/keepImport.expected.js'));
302+
});
303+
});
295304
});

0 commit comments

Comments
 (0)