Skip to content

Commit

Permalink
[#111] Make styleId an optional string or function (#110)
Browse files Browse the repository at this point in the history
* feat: allow for unique styleId when relativeCssInjection

* fix: remove dash when there is no styleId

* fix: only run changes if styleId exists

* fix: move uuid to devDependencies + update README

* fix: PR comments

* fix: remove empty line

* fix: remove empty line

* fix: remove empty line

* fix: remove unused duplicate test

* refactor: styleId as callback function
  • Loading branch information
pedrosousa13 committed Aug 7, 2023
1 parent 57f36d5 commit 8e1a392
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 6 deletions.
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ export default {
}
```

#### styleId (string)
#### styleId (string | function)

If you provide a `string` for `styleId` param the code of injection will set the `id` attribute of the `style` element
If you provide a `string` for `styleId` param, the code of injection will set the `id` attribute of the `style` element
with the value of the parameter provided. This is an example:

```ts
Expand All @@ -77,6 +77,25 @@ The output injected into the DOM will look like this example:
</head>
```

If you provide a `function` for `styleId` param, it will run that function and return a string. It's especially useful if you use `relativeCSSInjection` and want unique styleIds for each file.

```ts
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'

export default {
plugins: [
cssInjectedByJsPlugin({styleId: () => `foo-${Math.random() * 100}`}),
]
}
```

```html
<head>
<style id="foo-1234">/* Generated CSS rules */</style>
<style id="foo-4321">/* Generated CSS rules */</style>
</head>
```

#### preRenderCSSCode (function)

You can use the `preRenderCSSCode` parameter to make specific changes to your CSS before it is printed in the output JS
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default function cssInjectedByJsPlugin({
injectCode,
injectCodeFunction,
useStrictCSP,
buildOptions: config.build,
buildOptions: config.build
});

const cssAssetsFilter = (asset: OutputAsset): boolean => {
Expand Down
2 changes: 1 addition & 1 deletion src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { BuildOptions } from 'vite';
export interface BaseOptions {
injectCode?: InjectCode;
injectCodeFunction?: InjectCodeFunction;
styleId?: string;
styleId?: string | (() => string);
topExecutionPriority?: boolean;
useStrictCSP?: boolean;
}
Expand Down
12 changes: 10 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { OutputAsset, OutputBundle, OutputChunk } from 'rollup';
import type { BuildCSSInjectionConfiguration, CSSInjectionConfiguration, PluginConfiguration } from './interface';

interface InjectCodeOptions {
styleId?: string;
styleId?: string | (() => string);
useStrictCSP?: boolean;
}

Expand All @@ -29,11 +29,19 @@ export async function buildCSSInjectionCode({
}: BuildCSSInjectionConfiguration): Promise<OutputChunk | null> {
let { minify, target } = buildOptions;

const generatedStyleId = typeof styleId === 'function' ? styleId() : styleId;

const res = await build({
root: '',
configFile: false,
logLevel: 'error',
plugins: [injectionCSSCodePlugin({ cssToInject, styleId, injectCode, injectCodeFunction, useStrictCSP })],
plugins: [injectionCSSCodePlugin({
cssToInject,
styleId: generatedStyleId,
injectCode,
injectCodeFunction,
useStrictCSP
})],
build: {
write: false,
target,
Expand Down
36 changes: 36 additions & 0 deletions test/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,42 @@ describe('utils', () => {
expect(getComputedStyle(document.body).color).toBe('red');
});

test('Generate JS that applies styles with callback styleID', async () => {
const styleId = () => `styleId-${Math.random()}`;
const builds = await Promise.all([
buildCSSInjectionCode({
cssToInject: 'body { color: red; }',
styleId,
buildOptions: { minify: true, target: 'es2015' },
}),
buildCSSInjectionCode({
cssToInject: 'body { background: blue; }',
styleId,
buildOptions: { minify: true, target: 'es2015' },
})
]);

builds?.map((output) => {
const $script = document.createElement('script');
$script.textContent = output?.code || 'throw new Error("UNCAUGHT ERROR")';
document.head.appendChild($script);
});

// Doesn't error
expect(onerror).not.toBeCalled();

// StyleId applied
const styles = document.head.querySelectorAll(`style[id^=styleId-]`);

expect(styles).toHaveLength(2);
// Expect unique style ids
expect([...new Set(styles.map((style) => style.id))]).toHaveLength(2)

// Applied style!
expect(getComputedStyle(document.body).color).toBe('red');
expect(getComputedStyle(document.body).background).toBe('blue');
});

test('Generate JS that applies styles, without styleId', async () => {
const output = await buildCSSInjectionCode({
cssToInject: 'body { color: red; }',
Expand Down

0 comments on commit 8e1a392

Please sign in to comment.