Skip to content

keepImport #65

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

Closed
wants to merge 13 commits into from
Closed
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
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,24 @@ To extract all files in a single directory, give an object:
Note that `relativeRoot` is used to resolve relative directory names, available
as `[path]` in `filename` pattern.

## Keeping import

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.

```js
// before
const styles = require('./test.css');
```

```js
// after
require('./test.css');

const styles = {
'someClass': 'Test__someClass___2Frqu'
}
```

## Alternatives

- [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`.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "babel-plugin-css-modules-transform",
"version": "1.2.7",
"version": "1.2.8",
"description": "Transform required css modules so one can use generated class names.",
"main": "build/index.js",
"scripts": {
Expand Down
70 changes: 56 additions & 14 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ const defaultOptions = {
generateScopedName: '[name]__[local]___[hash:base64:5]'
};

function findExpressionStatementChild(path, t) {
const parent = path.parentPath;
if (!parent) {
throw new Error('Invalid expression structure');
}
if (
t.isExpressionStatement(parent)
|| t.isProgram(parent)
|| t.isBlockStatement(parent)
) {
return path;
}
return findExpressionStatementChild(parent, t);
}

export default function transformCssModules({ types: t }) {
function resolveModulePath(filename) {
const dir = dirname(filename);
Expand Down Expand Up @@ -37,7 +52,12 @@ export default function transformCssModules({ types: t }) {
try {
return require(filePathOrModuleName);
} catch (e) {
return {}; // return empty object, this simulates result of ignored stylesheet file
// As a last resort, require the cssFile itself. This enables loading of CSS files from external deps
try {
return require(cssFile);
} catch (f) {
return {}; // return empty object, this simulates result of ignored stylesheet file
}
}
}

Expand Down Expand Up @@ -108,6 +128,10 @@ export default function transformCssModules({ types: t }) {
return processed;
};

// Build arguments especially for css-modules-require-hook
// because it has arguments validator and any external
// option will result in a error
const requireHooksArguments = {};
// resolve options
Object.keys(requireHooksOptions).forEach(key => {
// skip undefined options
Expand All @@ -116,14 +140,14 @@ export default function transformCssModules({ types: t }) {
}

inProcessingFunction = true;
currentConfig[key] = requireHooksOptions[key](currentConfig[key], currentConfig);
requireHooksArguments[key] = requireHooksOptions[key](currentConfig[key], currentConfig);
inProcessingFunction = false;
});

// wrap or define processCss function that collect generated css
currentConfig.processCss = pushStylesCreator(currentConfig.processCss);
requireHooksArguments.processCss = pushStylesCreator(currentConfig.processCss);

require('css-modules-require-hook')(currentConfig);
require('css-modules-require-hook')(requireHooksArguments);

initialized = true;

Expand All @@ -149,22 +173,28 @@ export default function transformCssModules({ types: t }) {
const requiringFile = file.opts.filename;
const tokens = requireCssFile(requiringFile, value);

path.parentPath.replaceWith(
t.variableDeclaration('var', [
t.variableDeclarator(
t.identifier(path.node.local.name),
buildClassNameToScopeNameMap(tokens)
)
]),
);
const varDeclaration = t.variableDeclaration('var', [t.variableDeclarator(t.identifier(path.node.local.name), buildClassNameToScopeNameMap(tokens))]);

if (thisPluginOptions.keepImport) {
path.parentPath.replaceWithMultiple([
t.importDeclaration([], t.stringLiteral(value)),
varDeclaration
]);
} else {
path.parentPath.replaceWith(varDeclaration);
}
}
},

// const styles = require('./styles.css');
CallExpression(path, { file }) {
const { callee: { name: calleeName }, arguments: args } = path.node;

if (calleeName !== 'require' || !args.length || !t.isStringLiteral(args[0])) {
if (
calleeName !== 'require'
|| !args.length
|| !t.isStringLiteral(args[0])
) {
return;
}

Expand All @@ -176,10 +206,22 @@ export default function transformCssModules({ types: t }) {

// if parent expression is not a Program, replace expression with tokens
// Otherwise remove require from file, we just want to get generated css for our output
// or keep if `keepImport` option enabled
if (!t.isExpressionStatement(path.parent)) {
path.replaceWith(buildClassNameToScopeNameMap(tokens));
// Keeped import will places before closest expression statement child
if (thisPluginOptions.keepImport) {
findExpressionStatementChild(path, t).insertBefore(t.expressionStatement(
t.callExpression(
t.identifier('require'),
[t.stringLiteral(stylesheetPath)]
)
));
}
} else {
path.remove();
if (!thisPluginOptions.keepImport) {
path.remove();
}
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions test/fixtures/require.keep.expected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

require('../styles.css');

var styles = {
'className': 'styles__className___385m0 parent__block___33Sxl child__line___3fweh'
};
6 changes: 6 additions & 0 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,4 +292,10 @@ describe('babel-plugin-css-modules-transform', () => {
'styles.css'
]);
});

it('should keep require', () => {
expect(transform('fixtures/require.js', {
keepImport: true
}).code).to.be.equal(readExpected('fixtures/require.keep.expected.js'));
});
});