Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

svelte-preprocess-cssmodules

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svelte-preprocess-cssmodules - npm Package Compare versions

Comparing version 2.1.0-rc.1 to 2.1.0-rc.2

8

CHANGELOG.md
# Svelte preprocess CSS Modules, changelog
## 2.1.0-rc.2 (Oct 7, 2021)
### Features
- Add option `useAsDefaultScoping` to enable cssModules globally without the need of the `module` attribute
### Breaking changes
- Rename option `allowedAttributes` to `includeAttributes`
- Add option `parseExternalStylesheet` to manually enable the parsing of imported stylesheets *(no more enabled by default)*
## 2.1.0-rc.1 (Oct 6, 2021)

@@ -4,0 +12,0 @@ - Add ESM distribution

30

dist/index.js

@@ -15,21 +15,29 @@ "use strict";

const lib_1 = require("./lib");
let pluginOptions = {
mode: 'native',
includePaths: [],
localIdentName: '[local]-[hash:base64:6]',
getLocalIdent: lib_1.getLocalIdent,
hashSeeder: ['style', 'filepath', 'classname'],
allowedAttributes: [],
const defaultOptions = () => {
return {
getLocalIdent: lib_1.getLocalIdent,
hashSeeder: ['style', 'filepath', 'classname'],
includeAttributes: [],
includePaths: [],
localIdentName: '[local]-[hash:base64:6]',
mode: 'native',
parseExternalStylesheet: false,
parseStyleTag: true,
useAsDefaultScoping: false,
};
};
let pluginOptions;
const markup = ({ content, filename }) => __awaiter(void 0, void 0, void 0, function* () {
const isIncluded = yield lib_1.isFileIncluded(pluginOptions.includePaths, filename);
if (!isIncluded) {
if (!isIncluded || (!pluginOptions.parseStyleTag && !pluginOptions.parseExternalStylesheet)) {
return { code: content };
}
const ast = compiler_1.parse(content, { filename });
if (!lib_1.hasModuleAttribute(ast) && !lib_1.hasModuleImports(content)) {
if (!pluginOptions.useAsDefaultScoping &&
!lib_1.hasModuleAttribute(ast) &&
!lib_1.hasModuleImports(content)) {
return { code: content };
}
let { mode, hashSeeder } = pluginOptions;
if (lib_1.hasModuleAttribute(ast)) {
if (pluginOptions.parseStyleTag && lib_1.hasModuleAttribute(ast)) {
const moduleAttribute = ast.css.attributes.find((item) => item.name === 'module');

@@ -66,3 +74,3 @@ mode = moduleAttribute.value !== true ? moduleAttribute.value[0].data : mode;

exports.default = module.exports = (options) => {
pluginOptions = Object.assign(Object.assign({}, pluginOptions), options);
pluginOptions = Object.assign(Object.assign({}, defaultOptions()), options);
return {

@@ -69,0 +77,0 @@ markup,

@@ -26,3 +26,3 @@ "use strict";

const directiveLength = 'class:'.length;
const allowedAttributes = ['class', ...processor.options.allowedAttributes];
const allowedAttributes = ['class', ...processor.options.includeAttributes];
compiler_1.walk(processor.ast.html, {

@@ -29,0 +29,0 @@ enter(baseNode) {

@@ -35,7 +35,8 @@ "use strict";

this.parse = () => {
if (lib_1.hasModuleAttribute(this.ast)) {
if (this.options.parseStyleTag &&
(lib_1.hasModuleAttribute(this.ast) || (this.options.useAsDefaultScoping && this.ast.css))) {
this.isParsingImports = false;
this.styleParser(this);
}
if (lib_1.hasModuleImports(this.rawContent)) {
if (this.options.parseExternalStylesheet && lib_1.hasModuleImports(this.rawContent)) {
this.isParsingImports = true;

@@ -42,0 +43,0 @@ parsers_1.parseImportDeclaration(this);

@@ -1,9 +0,12 @@

import { GetLocalIdent } from '../lib';
import type { GetLocalIdent } from '../lib';
export declare type PluginOptions = {
mode: 'native' | 'mixed' | 'scoped';
getLocalIdent: GetLocalIdent;
hashSeeder: Array<'style' | 'filepath' | 'classname'>;
includeAttributes: string[];
includePaths: string[];
localIdentName: string;
getLocalIdent: GetLocalIdent;
hashSeeder: Array<'style' | 'filepath' | 'classname'>;
allowedAttributes: string[];
mode: 'native' | 'mixed' | 'scoped';
parseExternalStylesheet: boolean;
parseStyleTag: boolean;
useAsDefaultScoping: boolean;
};

@@ -10,0 +13,0 @@ export interface PreprocessorOptions {

{
"name": "svelte-preprocess-cssmodules",
"version": "2.1.0-rc.1",
"version": "2.1.0-rc.2",
"description": "Svelte preprocessor to generate CSS Modules classname on Svelte components",

@@ -22,3 +22,3 @@ "keywords": [

"build:esm": "tsc --module esnext --target esnext --outDir dist/esm && node tasks/parser.mjs && rm -rf dist/esm/",
"dev": "npm run build -- -w",
"dev": "npm run build:cjs -- -w",
"lint": "eslint --ext .ts --fix ./src",

@@ -25,0 +25,0 @@ "format": "prettier --write --loglevel warn ./{src,test}",

@@ -30,3 +30,3 @@ # Svelte preprocess CSS Modules

Add `module` attribute to the `<style>` tag to enable cssModules in the component.
Add the `module` attribute to the `<style>` tag to enable cssModules

@@ -217,7 +217,46 @@ ```html

When used on a class, `:local()` applies the svelte scoping system to the selector. This could be useful when targetting global classnames.
```html
<style module>
.actions {
padding: 10px;
}
/* target a css framework classname without replacing it*/
:local(.btn-primary) {
margin-right: 10px;
}
</style>
<div class="actions">
<button class="btn btn-primary">Ok</button>
<button class="btn btn-default">Cancel</button>
</div>
```
*Generating*
```html
<style>
.actions-7Fhti9 {
padding: 10px;
}
.btn-primary.svelte-saq8ts {
margin-right: 10px;
}
</style>
<div class="actions-7Fhti9">
<button class="btn btn-primary svelte-saq8ts">Ok</button>
<button class="btn btn-default">Cancel</button>
</div>
```
## Import styles from an external stylesheet
Alternatively, styles can be created into an external file and imported onto a svelte component from the `<script>` tag. The name referring to the import can then be used in the markup targetting any existing classname of the stylesheet.
Alternatively, styles can be created into an external file and imported onto a svelte component from the `<script>` tag. The name referring to the import can then be used in the markup targetting any existing classname of the stylesheet.
The css file must follow the convention `FILENAME.module.css` in order to be processed.
- The option `parseExternalSylesheet` need to be enabled.
- The css file must follow the convention `FILENAME.module.css` in order to be processed.

@@ -502,24 +541,13 @@ **Note:** *The import option is only meant for stylesheets relative to the component. You will have to set your own bundler in order to import *node_modules* packages css files.*

| ------------- | ------------- | ------------- | ------------- |
| `mode` | `native\|mixed\|scoped` | `native` | The preprocess mode to use
| `localIdentName` | `{String}` | `"[local]-[hash:base64:6]"` | A rule using any available token |
| `getLocalIdent` | `Function` | `undefined` | Generate the classname by specifying a function instead of using the built-in interpolation |
| `hashSeeder` | `{Array}` | `['style', 'filepath', 'classname']` | An array of keys to base the hash on |
| `allowedAttributes` | `{Array}` | `[]` | An array of attributes to parse along with `class` |
| `includeAttributes` | `{Array}` | `[]` | An array of attributes to parse along with `class` |
| `includePaths` | `{Array}` | `[]` (Any) | An array of paths to be processed |
| `getLocalIdent` | `Function` | `undefined` | Generate the classname by specifying a function instead of using the built-in interpolation |
| `localIdentName` | `{String}` | `"[local]-[hash:base64:6]"` | A rule using any available token |
| `mode` | `native\|mixed\|scoped` | `native` | The preprocess mode to use
| `parseExternalStylesheet` | `{Boolean}` | `false` | Enable parsing on imported external stylesheet |
| `parseStyleTag` | `{Boolean}` | `true` | Enable parsing on style tag |
| `useAsDefaultScoping` | `{Boolean}` | `false` | Replace svelte scoping globally |
**`localIdentName`**
Inspired by [webpack interpolateName](https://github.com/webpack/loader-utils#interpolatename), here is the list of tokens:
- `[local]` the targeted classname
- `[ext]` the extension of the resource
- `[name]` the basename of the resource
- `[path]` the path of the resource
- `[folder]` the folder the resource is in
- `[contenthash]` or `[hash]` *(they are the same)* the hash of the resource content (by default it's the hex digest of the md4 hash)
- `[<hashType>:contenthash:<digestType>:<length>]` optionally one can configure
- other hashTypes, i. e. `sha1`, `md4`, `md5`, `sha256`, `sha512`
- other digestTypes, i. e. `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`
- and `length` the length in chars
**`hashSeeder`**

@@ -566,4 +594,28 @@

**`allowedAttributes`**
**`getLocalIdent`**
Customize the creation of the classname instead of relying on the built-in function.
```ts
function getLocalIdent(
context: {
context: string, // the context path
resourcePath: string, // path + filename
},
localIdentName: {
template: string, // the template rule
interpolatedName: string, // the built-in generated classname
},
className: string, // the classname string
content: {
markup: string, // the markup content
style: string, // the style content
}
): string {
return `your_generated_classname`;
}
```
**`includeAttributes`**
Add other attributes than `class` to be parsed by the preprocesser

@@ -576,3 +628,3 @@

cssModules({
allowedAttributes: ['data-color', 'classname'],
includeAttributes: ['data-color', 'classname'],
})

@@ -602,26 +654,3 @@ ],

**`getLocalIdent`**
Customize the creation of the classname instead of relying on the built-in function.
```ts
function getLocalIdent(
context: {
context: string, // the context path
resourcePath: string, // path + filename
},
localIdentName: {
template: string, // the template rule
interpolatedName: string, // the built-in generated classname
},
className: string, // the classname string
content: {
markup: string, // the markup content
style: string, // the style content
}
): string {
return `your_generated_classname`;
}
```
*Example of use*

@@ -661,2 +690,46 @@

**`localIdentName`**
Inspired by [webpack interpolateName](https://github.com/webpack/loader-utils#interpolatename), here is the list of tokens:
- `[local]` the targeted classname
- `[ext]` the extension of the resource
- `[name]` the basename of the resource
- `[path]` the path of the resource
- `[folder]` the folder the resource is in
- `[contenthash]` or `[hash]` *(they are the same)* the hash of the resource content (by default it's the hex digest of the md4 hash)
- `[<hashType>:contenthash:<digestType>:<length>]` optionally one can configure
- other hashTypes, i. e. `sha1`, `md4`, `md5`, `sha256`, `sha512`
- other digestTypes, i. e. `hex`, `base26`, `base32`, `base36`, `base49`, `base52`, `base58`, `base62`, `base64`
- and `length` the length in chars
**`useAsDefaultScoping`**
Globally replace the default svelte scoping by the cssModules scoping. As a result, the `module` attribute to `<style>` becomes unnecessary.
```js
// Preprocess config
...
preprocess: [
cssModules([
useAsDefaultScoping: true
]),
],
...
```
```html
<h1 class="title">Welcome</h1>
<style>
.title { color: blue }
</style>
```
*Generating*
```html
<h1 class="title-erYt1">Welcome</h1>
<style>
.title-erYt1 { color: blue }
</style>
```
## Migrating from v1

@@ -684,3 +757,2 @@ If you want to migrate an existing project to `v2` keeping the approach of the 1st version, follow the steps below:

## Code Example

@@ -713,16 +785,11 @@

position: fixed;
...
}
header {
...
.wrapper {
padding: 0.5rem 1rem;
}
.body {
flex: 1 0 0;
...
}
footer {
...
}
button {
...
background-color: white;
}

@@ -735,7 +802,7 @@ .cancel {

<section class="modal">
<header>My Modal Title</header>
<div class="body">
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit.</p>
<header class="wrapper">My Modal Title</header>
<div class="body wrapper">
<p>Lorem ipsum dolor sit, amet consectetur.</p>
</div>
<footer>
<footer class="wrapper">
<button>Ok</button>

@@ -747,3 +814,3 @@ <button class="cancel">Cancel</button>

***OR** Svelte Component using `import`*
***OR** Svelte Component importing external stylesheet*

@@ -754,6 +821,4 @@ ```css

position: fixed;
...
}
[...]
...
```

@@ -766,7 +831,7 @@ ```html

<section class={style.modal}>
<header>My Modal Title</header>
<div class={style.body}>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit.</p>
<header class={style.wrapper}>My Modal Title</header>
<div class="{style.body} {style.wrapper}">
<p>Lorem ipsum dolor sit, amet consectetur.</p>
</div>
<footer>
<footer class={style.wrapper}>
<button>Ok</button>

@@ -784,16 +849,11 @@ <button class={style.cancel}>Cancel</button>

position: fixed;
...
}
header {
...
.Re123xDTGv {
padding: 0.5rem 1rem;
}
._1HPUBXtzNG {
flex: 1 0 0;
...
}
footer {
...
}
button {
...
background-color: white;
}

@@ -806,7 +866,7 @@ ._1xhJxRwWs7 {

<section class="_329TyLUs9c">
<header>My Modal Title</header>
<div class="_1HPUBXtzNG">
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit.</p>
<header class="Re123xDTGv">My Modal Title</header>
<div class="_1HPUBXtzNG Re123xDTGv">
<p>Lorem ipsum dolor sit, amet consectetur.</p>
</div>
<footer>
<footer class="Re123xDTGv">
<button>Ok</button>

@@ -820,3 +880,3 @@ <button class="_1xhJxRwWs7">Cancel</button>

While the native CSS Scoped system should be largely enough to avoid class conflict, it could find its limit when working on a hybrid project. On a non full Svelte application, the thought on the class naming would not be less different than what we would do on a regular html page. For example, on the modal component above, It would have been wiser to namespace some of the classes such as `.modal-body` and `.modal-cancel` in order to prevent inheriting styles from other `.body` and `.cancel` classes.
While the native CSS Scoped system should be largely enough to avoid class conflict, it could find its limit when working on a hybrid project. On a non full Svelte application, paying attention to the name of a class would be no less different than to a regular html project. For example, on the modal component above, It would have been wiser to namespace some of the classes such as `.modal-body` and `.modal-cancel` in order to prevent inheriting styles from other `.body` and `.cancel` classes.

@@ -823,0 +883,0 @@ ## License

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc