Skip to content

Commit

Permalink
Add include and exclude globs for CSS modules (#9301)
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett committed Oct 11, 2023
1 parent 1a3a254 commit 8e05ef2
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 9 deletions.
43 changes: 43 additions & 0 deletions packages/core/integration-tests/test/css-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
assertBundles,
distDir,
outputFS,
overlayFS,
fsFixture,
} from '@parcel/test-utils';
import postcss from 'postcss';

Expand Down Expand Up @@ -776,4 +778,45 @@ describe('css modules', () => {
},
]);
});

it('should support the "include" and "exclude" options', async function () {
await fsFixture(overlayFS, __dirname)`
css-module-include
a.css:
.foo { color: red }
modules/b.css:
.bar { color: yellow }
modules/_c.css:
.baz { color: pink }
index.js:
import './a.css';
import {bar} from './modules/b.css';
import './modules/_c.css';
export default bar;
package.json:
{
"@parcel/transformer-css": {
"cssModules": {
"include": "modules/*.css",
"exclude": "modules/_*.css"
}
}
}
yarn.lock:`;

let b = await bundle(path.join(__dirname, 'css-module-include/index.js'), {
mode: 'production',
inputFS: overlayFS,
});

let contents = await outputFS.readFile(
b.getBundles().find(b => b.type === 'css').filePath,
'utf8',
);
assert(contents.includes('.foo'));
assert(contents.includes('.rp85ja_bar'));
assert(contents.includes('.baz'));
});
});
60 changes: 51 additions & 9 deletions packages/transformers/css/src/CSSTransformer.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import {
browserslistToTargets,
type SourceLocation as LightningSourceLocation,
} from 'lightningcss';
import {remapSourceLocation, relativePath} from '@parcel/utils';
import {
remapSourceLocation,
relativePath,
globToRegex,
normalizeSeparators,
} from '@parcel/utils';
import browserslist from 'browserslist';
import nullthrows from 'nullthrows';
import ThrowableDiagnostic, {errorToDiagnostic} from '@parcel/diagnostic';
Expand All @@ -21,7 +26,22 @@ export default (new Transformer({
let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
packageKey: '@parcel/transformer-css',
});
return conf?.contents;
let contents = conf?.contents;
if (typeof contents?.cssModules?.include === 'string') {
contents.cssModules.include = [globToRegex(contents.cssModules.include)];
} else if (Array.isArray(contents?.cssModules?.include)) {
contents.cssModules.include = contents.cssModules.include.map(include =>
typeof include === 'string' ? globToRegex(include) : include,
);
}
if (typeof contents?.cssModules?.exclude === 'string') {
contents.cssModules.exclude = [globToRegex(contents.cssModules.exclude)];
} else if (Array.isArray(contents?.cssModules?.exclude)) {
contents.cssModules.exclude = contents.cssModules.exclude.map(exclude =>
typeof exclude === 'string' ? globToRegex(exclude) : exclude,
);
}
return contents;
},
async transform({asset, config, options, logger}) {
// Normalize the asset's environment so that properties that only affect JS don't cause CSS to be duplicated.
Expand Down Expand Up @@ -59,12 +79,32 @@ export default (new Transformer({
asset.meta.cssModulesCompiled == null
) {
let cssModulesConfig = config?.cssModules;
if (
(asset.isSource &&
(typeof cssModulesConfig === 'boolean' ||
cssModulesConfig?.global)) ||
/\.module\./.test(asset.filePath)
) {
let isCSSModule = /\.module\./.test(asset.filePath);
if (asset.isSource) {
let projectRootPath = path.relative(
options.projectRoot,
asset.filePath,
);
if (typeof cssModulesConfig === 'boolean') {
isCSSModule = true;
} else if (cssModulesConfig?.include) {
isCSSModule = cssModulesConfig.include.some(include =>
include.test(projectRootPath),
);
} else if (cssModulesConfig?.global) {
isCSSModule = true;
}

if (
cssModulesConfig?.exclude?.some(exclude =>
exclude.test(projectRootPath),
)
) {
isCSSModule = false;
}
}

if (isCSSModule) {
if (cssModulesConfig?.dashedIdents && !asset.isSource) {
cssModulesConfig.dashedIdents = false;
}
Expand All @@ -74,7 +114,9 @@ export default (new Transformer({
}

res = transform({
filename: path.relative(options.projectRoot, asset.filePath),
filename: normalizeSeparators(
path.relative(options.projectRoot, asset.filePath),
),
code,
cssModules,
analyzeDependencies: asset.meta.hasDependencies !== false,
Expand Down

0 comments on commit 8e05ef2

Please sign in to comment.