rollup-plugin-lib-style 2.3.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.es.js CHANGED
@@ -18,6 +18,20 @@ const replaceFormat = (formatString, fileName, cssContent) => {
18
18
  return formatString.replace("[local]", fileName).replace(/\[hash:(.*?)(:\d+)?\]/, hashToUse)
19
19
  };
20
20
 
21
+ /**
22
+ * Ensures generated class names are valid CSS identifiers.
23
+ * - Replaces invalid characters with `_`
24
+ * - Ensures class names do not start with a number
25
+ * @param {string} name - Original class name
26
+ * @returns {string} - Valid CSS class name
27
+ */
28
+ const normalizeClassName = (hash) => {
29
+ // Replace invalid characters with '_'
30
+ let sanitized = hash.replace(/[^a-zA-Z0-9-_]/g, "_");
31
+ if (/^[0-9]/.test(sanitized)) sanitized = `_${sanitized}`;
32
+ return sanitized
33
+ };
34
+
21
35
  const DEFAULT_SCOPED_NAME = "[local]_[hash:hex:6]";
22
36
 
23
37
  /**
@@ -44,13 +58,18 @@ const postCssLoader = async ({code, fiePath, options}) => {
44
58
 
45
59
  const modulesExported = {};
46
60
 
47
- const isGlobalStyle = /\.global.(css|scss|sass|less|stylus)$/.test(fiePath);
61
+ const isGlobalStyle = /\.global\.(css|scss|sass|less|stylus)$/.test(fiePath);
48
62
  const isInNodeModules = /[\\/]node_modules[\\/]/.test(fiePath);
49
63
 
50
64
  const postCssPluginsWithCssModules = [
51
65
  postcssModules({
52
66
  generateScopedName: (name, filename, css) => {
53
- return isInNodeModules || isGlobalStyle ? name : classNamePrefix + replaceFormat(scopedName, name, css)
67
+ const hashContent = `${filename}:${name}:${css}`;
68
+ const rawScopedName = replaceFormat(scopedName, name, hashContent);
69
+ const normalizedName = normalizeClassName(rawScopedName);
70
+ return isInNodeModules || isGlobalStyle
71
+ ? name // Use the original name for global or node_modules styles
72
+ : classNamePrefix + normalizedName // Apply prefix and normalize
54
73
  },
55
74
  getJSON: (cssFileName, json) => (modulesExported[cssFileName] = json),
56
75
  }),
@@ -143,11 +162,12 @@ const libStylePlugin = (options = {}) => {
143
162
 
144
163
  const cssFilePath = customCSSPath ? customCSSPath(id) : getFilePath();
145
164
  const cssFileInjectedPath = customCSSInjectedPath ? customCSSInjectedPath(cssFilePath) : cssFilePath;
165
+ const cssFilePathWithoutSlash = cssFilePath.startsWith("/") ? cssFilePath.substring(1) : cssFilePath;
146
166
 
147
167
  // create a new css file with the generated hash class names
148
168
  this.emitFile({
149
169
  type: "asset",
150
- fileName: cssFilePath.replace("/", "").replace(loader.regex, ".css"),
170
+ fileName: cssFilePathWithoutSlash.replace(loader.regex, ".css"),
151
171
  source: postCssResult.extracted.code,
152
172
  });
153
173
 
package/lib/index.js CHANGED
@@ -20,6 +20,20 @@ const replaceFormat = (formatString, fileName, cssContent) => {
20
20
  return formatString.replace("[local]", fileName).replace(/\[hash:(.*?)(:\d+)?\]/, hashToUse)
21
21
  };
22
22
 
23
+ /**
24
+ * Ensures generated class names are valid CSS identifiers.
25
+ * - Replaces invalid characters with `_`
26
+ * - Ensures class names do not start with a number
27
+ * @param {string} name - Original class name
28
+ * @returns {string} - Valid CSS class name
29
+ */
30
+ const normalizeClassName = (hash) => {
31
+ // Replace invalid characters with '_'
32
+ let sanitized = hash.replace(/[^a-zA-Z0-9-_]/g, "_");
33
+ if (/^[0-9]/.test(sanitized)) sanitized = `_${sanitized}`;
34
+ return sanitized
35
+ };
36
+
23
37
  const DEFAULT_SCOPED_NAME = "[local]_[hash:hex:6]";
24
38
 
25
39
  /**
@@ -46,13 +60,18 @@ const postCssLoader = async ({code, fiePath, options}) => {
46
60
 
47
61
  const modulesExported = {};
48
62
 
49
- const isGlobalStyle = /\.global.(css|scss|sass|less|stylus)$/.test(fiePath);
63
+ const isGlobalStyle = /\.global\.(css|scss|sass|less|stylus)$/.test(fiePath);
50
64
  const isInNodeModules = /[\\/]node_modules[\\/]/.test(fiePath);
51
65
 
52
66
  const postCssPluginsWithCssModules = [
53
67
  postcssModules({
54
68
  generateScopedName: (name, filename, css) => {
55
- return isInNodeModules || isGlobalStyle ? name : classNamePrefix + replaceFormat(scopedName, name, css)
69
+ const hashContent = `${filename}:${name}:${css}`;
70
+ const rawScopedName = replaceFormat(scopedName, name, hashContent);
71
+ const normalizedName = normalizeClassName(rawScopedName);
72
+ return isInNodeModules || isGlobalStyle
73
+ ? name // Use the original name for global or node_modules styles
74
+ : classNamePrefix + normalizedName // Apply prefix and normalize
56
75
  },
57
76
  getJSON: (cssFileName, json) => (modulesExported[cssFileName] = json),
58
77
  }),
@@ -145,11 +164,12 @@ const libStylePlugin = (options = {}) => {
145
164
 
146
165
  const cssFilePath = customCSSPath ? customCSSPath(id) : getFilePath();
147
166
  const cssFileInjectedPath = customCSSInjectedPath ? customCSSInjectedPath(cssFilePath) : cssFilePath;
167
+ const cssFilePathWithoutSlash = cssFilePath.startsWith("/") ? cssFilePath.substring(1) : cssFilePath;
148
168
 
149
169
  // create a new css file with the generated hash class names
150
170
  this.emitFile({
151
171
  type: "asset",
152
- fileName: cssFilePath.replace("/", "").replace(loader.regex, ".css"),
172
+ fileName: cssFilePathWithoutSlash.replace(loader.regex, ".css"),
153
173
  source: postCssResult.extracted.code,
154
174
  });
155
175
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rollup-plugin-lib-style",
3
- "version": "2.3.0",
3
+ "version": "2.3.2",
4
4
  "description": "A Rollup plugin that converts CSS and extensions for CSS into CSS modules and imports the generated CSS files",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.es.js",