Skip to content

Commit 812941e

Browse files
committed
fix: parse <style> tags
1 parent 8655b71 commit 812941e

File tree

4 files changed

+107
-16
lines changed

4 files changed

+107
-16
lines changed

README.md

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,18 @@ export default {
2323

2424
## Options
2525

26-
| Property | Description |
27-
| ---------- | ------------------------------------------------------------------------ |
28-
| include | Files to include |
29-
| exclude | Files to exclude |
30-
| env | Environment variable, defaults to `process.env.NODE_ENV` where available |
31-
| styleRegex | Custom regex for selecting CSS in file |
32-
| configPath | Path to directory that contains postcss.config.js |
26+
| Property | Description |
27+
| --------------- | ------------------------------------------------------------------------ |
28+
| configPath | Path to directory that contains postcss.config.js |
29+
| env | Environment variable, defaults to `process.env.NODE_ENV` where available |
30+
| exclude | Files to exclude |
31+
| failOnError | Allows errors to propagate when `true`, otherwise warnings are thrown |
32+
| from | Input file name (usually set by rollup) |
33+
| include | Files to include |
34+
| plugins | Array of PostCSS plugins, defaults to `postcss.config.js` |
35+
| styleDelineator | Custom delineator for parsing styles in a file, default is /`/ |
36+
| styleRegex | Custom regex for selecting CSS in file |
37+
| to | Output file name (usually set by rollup) |
3338

3439
## Template Literals in JavaScript
3540

@@ -55,7 +60,20 @@ The default regex for selecting template literals in a file is:
5560
/(?:css`)((.|\n)+?)(?=(`(\n|;|,)))/gi;
5661
```
5762

58-
## Config
63+
The lookahead in the above RegExp statement allows for multiple matches of styles in the same file.
64+
65+
Customize the regex that is used to parse inline CSS with the `styleRegex` and `styleDelineator` options.
66+
67+
For example, to parse inline `<style>` tags:
68+
69+
```js
70+
inlinePostCSS({
71+
styleRegex: /(?:<style>)((.|\n)+?)(?=(<\/style>))/gi,
72+
styleDelineator: /<\/?style>/g,
73+
});
74+
```
75+
76+
## postcss.config.js
5977

6078
This plugin honors `postcss.config.js` in the root directory and will look for environment variables based on the current `NODE_ENV`. The example postcss.config.js below demonstrates minifying CSS with the `postcss-csso` plugin only when the NODE_ENV is set to `prod`.
6179

src/index.ts

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,32 @@ import { createFilter } from 'rollup-pluginutils';
55

66
const postcss = require('postcss');
77

8-
export default function inlinePostCSS(options: any = {}) {
8+
declare interface InlinePostCSSOptions {
9+
configPath?: string;
10+
include?: string[];
11+
exclude?: string[];
12+
env?: string;
13+
failOnError?: boolean;
14+
from?: string;
15+
plugins?: any[];
16+
styleDelineator?: string;
17+
styleRegex?: RegExp;
18+
to?: string;
19+
}
20+
21+
export default function inlinePostCSS(options: InlinePostCSSOptions = {}) {
922
const filter = createFilter(options.include, options.exclude);
1023
const styleRegex = options.styleRegex
1124
? options.styleRegex
1225
: /(?:css`)((.|\n)+?)(?=(`(\n|;|,)))/gi;
13-
const hasCustomRegex = options.styleRegex ? true : false;
26+
1427
return {
1528
name: 'inline-postcss',
1629
transform(code, id) {
1730
if (!filter(id)) {
1831
return;
1932
}
33+
2034
if (!code.match(styleRegex)) {
2135
return;
2236
}
@@ -63,16 +77,27 @@ export default function inlinePostCSS(options: any = {}) {
6377
.filter((key) => config.plugins[key])
6478
.map((key) => require(key));
6579

66-
const matches = code.match(styleRegex);
80+
const styleDelineator = options.styleDelineator
81+
? options.styleDelineator
82+
: /`/;
83+
84+
let matches = code.match(styleRegex);
6785

6886
return Promise.all(
69-
matches.map((css) =>
70-
postcss(outputConfig).process(css.split('`')[1], postcssOptions)
87+
matches.map((css: string) =>
88+
postcss(outputConfig).process(
89+
styleDelineator ? css.split(styleDelineator)[1] : css,
90+
postcssOptions
91+
)
7192
)
72-
).then((transforms: any) => {
73-
let mappings = '';
93+
).then((transforms: any[]) => {
7494
transforms.forEach((transform, index) => {
75-
code = code.replace(matches[index].split('`')[1], transform.css);
95+
code = code.replace(
96+
styleDelineator
97+
? matches[index].split(styleDelineator)[1]
98+
: matches[index],
99+
transform.css
100+
);
76101
});
77102
return {
78103
code,

test/fixtures/custom-template.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export const styleTemplate = `<style>
2+
:host {
3+
background: #abcefe;
4+
cursor: pointer;
5+
color: white;
6+
font-weight: 400;
7+
}
8+
</style>
9+
`;
10+
11+
export const anotherStyle = `<style>
12+
:host {
13+
background: #abcefe;
14+
cursor: pointer;
15+
color: white;
16+
font-weight: 400;
17+
}
18+
</style>
19+
`;

test/index.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,35 @@ test('should process file with custom regex', async () => {
7676
expect(await res.isMinified('custom.js')).toBe(true);
7777
});
7878

79+
test('should process file with legacy custom regex', async () => {
80+
const res = await write({
81+
input: 'component.js',
82+
output: 'custom-legacy.js',
83+
outDir: 'test/extract',
84+
plugin: inlinePostCSS({
85+
styleRegex: /css\`((?:\\.|[^"\\])*)\`/gi,
86+
}),
87+
options: {},
88+
});
89+
expect(await res.hasRGBColorValues('custom-legacy.js')).toBe(true);
90+
expect(await res.isMinified('custom-legacy.js')).toBe(true);
91+
});
92+
93+
test('should process file with style template', async () => {
94+
const res = await write({
95+
input: 'custom-template.js',
96+
output: 'custom-template.js',
97+
outDir: 'test/extract',
98+
plugin: inlinePostCSS({
99+
styleRegex: /(?:<style>)((.|\n)+?)(?=(<\/style>))/gi,
100+
styleDelineator: /<\/?style>/g,
101+
configPath: path.join(__dirname, 'config'),
102+
}),
103+
options: {},
104+
});
105+
expect(await res.hasRGBColorValues('custom-template.js')).toBe(true);
106+
});
107+
79108
test('should reference postcss.config.js', async () => {
80109
const res = await write({
81110
input: 'component.js',

0 commit comments

Comments
 (0)