Skip to content

v3.1.5: Fix #75 #76

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
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
5 changes: 4 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
## V3.1.2
## V3.1.5
- fix [issue#75](https://github.com/indooorsman/esbuild-css-modules-plugin/issues/75)

- ## V3.1.2
- fix [issue#74](https://github.com/indooorsman/esbuild-css-modules-plugin/issues/74)

## V3.1.1
Expand Down
31 changes: 30 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Plugin, PluginBuild } from 'esbuild';
import type {
BundleOptions,
CustomAtRules,
TransformOptions,
} from 'lightningcss';

declare type EmitDtsConfig = Partial<
Expand Down Expand Up @@ -138,6 +137,36 @@ declare interface BuildOptions
module?: string;
version: string;
};
/**
* Enforces usage of one or more id or class selectors for each rule.
*
* If you enable this option, Lightning CSS will throw an error for CSS rules
* that don't have at least one id or class selector, like div. This is useful
* because selectors like div are not scoped and affects all elements on the
* page.
*
* https://lightningcss.dev/css-modules.html#pure-mode
*/
pure?: boolean;
/**
* Turn off feature scoping for animations;
*
* https://lightningcss.dev/css-modules.html#turning-off-feature-scoping
*/
animation?: boolean;
/**
* Turn off feature scoping for custom idents:
* https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident;
*
* https://lightningcss.dev/css-modules.html#turning-off-feature-scoping
*/
customIdents?: boolean;
/**
* Turn off feature scoping for grid areas;
*
* https://lightningcss.dev/css-modules.html#turning-off-feature-scoping
*/
grid?: boolean;
}

declare function CssModulesPlugin(options?: BuildOptions): Plugin;
Expand Down
6 changes: 4 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const setup = (build, _options) => {
const rpath = relative(buildRoot, path);
const prefix = basename(rpath, extname(path))
.replace(/[^a-zA-Z0-9]/g, '-')
.replace(/^\-*/, '');
.replace(/^-*/, '');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just removing an extraneous escape character

const suffix = patchedBuild.context.packageVersion?.replace(/[^a-zA-Z0-9]/g, '') ?? '';

const buildResult = CSSTransformer.getInstance(patchedBuild).bundle(path, {
Expand Down Expand Up @@ -320,7 +320,9 @@ export const setup = (build, _options) => {
/** @type {[string, string][]} */
const filesToBuild = [];
warnMetafile();
const cssOutputsMap = Object.entries(r.metafile?.outputs ?? {}).reduce((m, [o, { inputs }]) => {

const cssOutputsMap = Object.entries(r.metafile?.outputs ?? {})
.reduce(/** @type {(m: Record<string, string>, o: any) => Record<string, string>} */(m, [o, {inputs}]) => {
Comment on lines +324 to +325
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing a typescript failure due to it not understanding the type of the accumulator. There could be a better solution to be quite honest.

const keys = Object.keys(inputs);
if (keys.length === 1 && new RegExp(`^${pluginCssNamespace}:.+\.css$`).test(keys[0])) {
m[keys[0].replace(`${pluginCssNamespace}:`, '')] = o;
Expand Down
6 changes: 5 additions & 1 deletion lib/css.helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ ${uniqNames.map(([o, l]) => ` "${o}": ${l}`).join(',\n')}
filename: fullpath,
cssModules: {
dashedIdents: options?.dashedIndents,
pattern: options?.pattern ?? `${opt?.prefix ?? ''}__[local]_[hash]__${opt?.suffix ?? ''}`
pattern: options?.pattern ?? `${opt?.prefix ?? ''}__[local]_[hash]__${opt?.suffix ?? ''}`,
pure: options?.pure ?? false,
animation: options?.animation ?? true,
customIdents: options?.customIdents ?? true,
grid: options?.grid ?? true,
},
drafts: {
customMedia: true,
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": "esbuild-css-modules-plugin",
"version": "3.1.4",
"version": "3.1.5",
"description": "A esbuild plugin to bundle css modules into js(x)/ts(x), based on extremely fast [Lightning CSS](https://lightningcss.dev/)",
"main": "./index.cjs",
"module": "./index.js",
Expand Down
19 changes: 19 additions & 0 deletions test/styles/app.modules.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
.hello_world {
color: red;
background: url("../components/world.jpg");

animation: 3s linear slide-in;
display: grid;
grid-template: "image text";
Comment on lines +7 to +9
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To test the hashing/not-hashing of the feature scoping controls.

}

.hello-world img {
display: inline-block;
grid-area: image;
}

.hello-world:hover {
Expand All @@ -16,3 +21,17 @@
.some-other-selector {
background-image: url('../components/world.jpg');
}

/* Should throw an error when `pure: true` */
div {
border-radius: 20px;
}

@keyframes slide-in {
from {
margin-left: -20%;
}
to {
margin-left: 100%;
}
}
1 change: 1 addition & 0 deletions test/styles/deep/styles/hello.modules.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.hello-text {
composes: bg-red from "../../base.modules.css";
color: grey;
grid-area: text;
}
76 changes: 70 additions & 6 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import cssModulesPlugin from '../index.js';
plugins: [
cssModulesPlugin({
inject: '#my-custom-element-with-shadow-dom',
emitDeclarationFile: true
emitDeclarationFile: true,
pattern: "__[hash]_[local]"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LightningCSS complains if the pattern doesn't end with [local] when grid areas are being used. See: https://lightningcss.dev/css-modules.html#css-grid

})
],
metafile: true,
Expand Down Expand Up @@ -56,7 +57,8 @@ import cssModulesPlugin from '../index.js';
document.head.appendChild(styleEle);
}
`;
}
},
pattern: "__[hash]_[local]"
})
],
logLevel: 'debug'
Expand Down Expand Up @@ -85,7 +87,9 @@ import cssModulesPlugin from '../index.js';
cssModulesPlugin({
inject: false,
namedExports: true,
filter: /\.css$/i
filter: /\.css$/i,
pattern: "__[hash]_[local]"

})
],
logLevel: 'debug',
Expand All @@ -112,7 +116,8 @@ import cssModulesPlugin from '../index.js';
cssModulesPlugin({
inject: false,
namedExports: true,
emitDeclarationFile: true
emitDeclarationFile: true,
pattern: "__[hash]_[local]"
})
],
logLevel: 'debug',
Expand Down Expand Up @@ -144,7 +149,8 @@ import cssModulesPlugin from '../index.js';
},
force: true,
forceInlineImages: true,
inject: '#my-styles-container'
inject: '#my-styles-container',
pattern: "__[hash]_[local]"
})
],
logLevel: 'debug',
Expand All @@ -169,14 +175,72 @@ import cssModulesPlugin from '../index.js';
},
plugins: [
cssModulesPlugin({
inject: true
inject: true,
pattern: "__[hash]_[local]"
})
],
logLevel: 'debug',
metafile: true
});
console.log('[test][esbuild:bundle:splitting] done, please check `test/dist/bundle-splitting`', '\n');

try {
// testing pure: true
await esbuild.build({
entryPoints: ['app.jsx'],
entryNames: '[name]-[hash]',
format: 'esm',
target: ['esnext'],
bundle: true,
minify: false,
publicPath: 'https://my.domain/static/',
external: ['react', 'react-dom'],
outdir: './dist/pure',
write: true,
loader: {
'.jpg': 'file'
},
plugins: [
cssModulesPlugin({
pure: true,
pattern: "__[hash]_[local]"
})
],
metafile: true,
logLevel: 'debug'
});
} catch (error) {
console.log('Should result in " [ERROR] A selector in CSS modules should contain at least one class or ID selector [plugin esbuild-css-modules-plugin]"`', '\n');
}

// testing feature scoping
await esbuild.build({
entryPoints: ['app.jsx'],
entryNames: '[name]-[hash]',
format: 'esm',
target: ['esnext'],
bundle: true,
minify: false,
publicPath: 'https://my.domain/static/',
external: ['react', 'react-dom'],
outdir: './dist/feature-scoping',
write: true,
loader: {
'.jpg': 'file'
},
plugins: [
cssModulesPlugin({
animation: false,
customIdents: false,
grid: false,
pattern: "__[hash]_[local]"
})
],
metafile: true,
logLevel: 'debug'
});
console.log('Should result in " [ERROR] A selector in CSS modules should contain at least one class or ID selector [plugin esbuild-css-modules-plugin]"`', '\n');

// testing no metafile & write false
const r = await esbuild.build({
...buildOptions,
Expand Down