rollup-plugin-react-scoped-css 0.6.0 → 0.6.1

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.
@@ -1,37 +0,0 @@
1
- import "./App.css";
2
- import "./App.scoped.css";
3
- import React, { useState } from "react";
4
- import logo from "./logo.svg";
5
- import Sub from "./Sub";
6
- function App() {
7
- const [count, setCount] = useState(0);
8
- return React.createElement(React.Fragment, null, React.createElement("div", {
9
- className: "App",
10
- "data-v-123456": true
11
- }, React.createElement("header", {
12
- className: "App-header",
13
- "data-v-123456": true
14
- }, React.createElement("img", {
15
- src: logo,
16
- className: "App-logo",
17
- alt: "logo",
18
- "data-v-123456": true
19
- }), React.createElement("p", { "data-v-123456": true }, "Hello Vite + React!"), React.createElement("p", { "data-v-123456": true }, React.createElement("button", {
20
- type: "button",
21
- onClick: () => setCount(count2 => count2 + 1),
22
- "data-v-123456": true
23
- }, "count is: ", count)), React.createElement("p", { "data-v-123456": true }, "Edit ", React.createElement("code", { "data-v-123456": true }, "App.jsx"), " and save to test HMR updates."), React.createElement("p", { "data-v-123456": true }, React.createElement("a", {
24
- className: "App-link",
25
- href: "https://reactjs.org",
26
- target: "_blank",
27
- rel: "noopener noreferrer",
28
- "data-v-123456": true
29
- }, "Learn React"), " | ", React.createElement("a", {
30
- className: "App-link",
31
- href: "https://vitejs.dev/guide/features.html",
32
- target: "_blank",
33
- rel: "noopener noreferrer",
34
- "data-v-123456": true
35
- }, "Vite Docs"))), React.createElement(Sub, { "data-v-123456": true })));
36
- }
37
- export default App;
@@ -1,31 +0,0 @@
1
- import "./App.css";
2
- import "./App.scoped.css";
3
- import React, { useState } from "react";
4
- import logo from "./logo.svg";
5
- import Sub from "./Sub";
6
- function App() {
7
- const [count, setCount] = useState(0);
8
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", {
9
- className: "App"
10
- }, /* @__PURE__ */ React.createElement("header", {
11
- className: "App-header"
12
- }, /* @__PURE__ */ React.createElement("img", {
13
- src: logo,
14
- className: "App-logo",
15
- alt: "logo"
16
- }), /* @__PURE__ */ React.createElement("p", null, "Hello Vite + React!"), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("button", {
17
- type: "button",
18
- onClick: () => setCount((count2) => count2 + 1)
19
- }, "count is: ", count)), /* @__PURE__ */ React.createElement("p", null, "Edit ", /* @__PURE__ */ React.createElement("code", null, "App.jsx"), " and save to test HMR updates."), /* @__PURE__ */ React.createElement("p", null, /* @__PURE__ */ React.createElement("a", {
20
- className: "App-link",
21
- href: "https://reactjs.org",
22
- target: "_blank",
23
- rel: "noopener noreferrer"
24
- }, "Learn React"), " | ", /* @__PURE__ */ React.createElement("a", {
25
- className: "App-link",
26
- href: "https://vitejs.dev/guide/features.html",
27
- target: "_blank",
28
- rel: "noopener noreferrer"
29
- }, "Vite Docs"))), /* @__PURE__ */ React.createElement(Sub, null)));
30
- }
31
- export default App;
@@ -1,101 +0,0 @@
1
- import {
2
- j as jsxRuntime,
3
- r as react,
4
- R as ReactDOM,
5
- a as React
6
- } from "./vendor.1137a3d7.js";
7
- var index = "body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n";
8
- var App$1 = ".sub {\n color: green;\n}";
9
- var App_scoped = ".App {\n text-align: center;\n}\n\n.sub {\n color: blue !important;\n}\n\n.App-logo {\n height: 40vmin;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .App-logo {\n animation: App-logo-spin infinite 20s linear;\n }\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\nbutton {\n font-size: calc(10px + 2vmin);\n}\n";
10
- var logo = "/assets/logo.ecc203fb.svg";
11
- var Sub_scoped = ".sub {\n color: red;\n}\n.sub__test {\n margin: 0;\n}\n.sub h2 {\n font-weight: 300;\n font-size: 3rem;\n}\n\nh2 {\n font-size: 10rem;\n}\n\n.drawer {\n width: 400px;\n}\n.drawer__list-item {\n padding: 0;\n}\n.drawer__list-item-icon {\n margin-right: 1rem;\n}\n.drawer__link {\n display: flex;\n width: 300px;\n padding: 1rem;\n align-items: center;\n text-decoration: none;\n border: 0;\n outline: 0;\n background: transparent;\n font-family: \"Quicksand\", \"Roboto\", sans-serif;\n font-size: 1rem;\n font-weight: 400;\n}\n.drawer__link:hover {\n background-color: #fafafa;\n}";
12
- const jsx = jsxRuntime.exports.jsx;
13
- const jsxs = jsxRuntime.exports.jsxs;
14
- const Fragment = jsxRuntime.exports.Fragment;
15
- function Sub() {
16
- return jsx("div", {
17
- className: "sub",
18
- children: jsx("h2", {
19
- children: "Sub",
20
- "data-v-123456": true
21
- }),
22
- "data-v-123456": true
23
- });
24
- }
25
- function App() {
26
- const [count, setCount] = react.exports.useState(0);
27
- return jsx(Fragment, {
28
- children: jsxs("div", {
29
- className: "App",
30
- children: [
31
- jsxs("header", {
32
- className: "App-header",
33
- children: [
34
- jsx("img", {
35
- src: logo,
36
- className: "App-logo",
37
- alt: "logo",
38
- "data-v-123456": true
39
- }),
40
- jsx("p", {
41
- children: "Hello Vite + React!",
42
- "data-v-123456": true
43
- }),
44
- jsx("p", {
45
- children: jsxs("button", {
46
- type: "button",
47
- onClick: () => setCount(count2 => count2 + 1),
48
- children: [
49
- "count is: ",
50
- count
51
- ],
52
- "data-v-123456": true
53
- }),
54
- "data-v-123456": true
55
- }),
56
- jsxs("p", {
57
- children: [
58
- "Edit ",
59
- jsx("code", {
60
- children: "App.jsx",
61
- "data-v-123456": true
62
- }),
63
- " and save to test HMR updates."
64
- ],
65
- "data-v-123456": true
66
- }),
67
- jsxs("p", {
68
- children: [
69
- jsx("a", {
70
- className: "App-link",
71
- href: "https://reactjs.org",
72
- target: "_blank",
73
- rel: "noopener noreferrer",
74
- children: "Learn React",
75
- "data-v-123456": true
76
- }),
77
- " | ",
78
- jsx("a", {
79
- className: "App-link",
80
- href: "https://vitejs.dev/guide/features.html",
81
- target: "_blank",
82
- rel: "noopener noreferrer",
83
- children: "Vite Docs",
84
- "data-v-123456": true
85
- })
86
- ],
87
- "data-v-123456": true
88
- })
89
- ],
90
- "data-v-123456": true
91
- }),
92
- jsx(Fragment, { children: jsx(Sub, { "data-v-123456": true }) })
93
- ],
94
- "data-v-123456": true
95
- })
96
- });
97
- }
98
- ReactDOM.render(jsx(React.StrictMode, {
99
- children: jsx(App, { "data-v-123456": true }),
100
- "data-v-123456": true
101
- }), document.getElementById("root"));
@@ -1,64 +0,0 @@
1
- import { j as jsxRuntime, r as react, R as ReactDOM, a as React } from "./vendor.1137a3d7.js";
2
- var index = "body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n";
3
- var App$1 = ".sub {\n color: green;\n}";
4
- var App_scoped = ".App {\n text-align: center;\n}\n\n.sub {\n color: blue !important;\n}\n\n.App-logo {\n height: 40vmin;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .App-logo {\n animation: App-logo-spin infinite 20s linear;\n }\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\nbutton {\n font-size: calc(10px + 2vmin);\n}\n";
5
- var logo = "/assets/logo.ecc203fb.svg";
6
- var Sub_scoped = '.sub {\n color: red;\n}\n.sub__test {\n margin: 0;\n}\n.sub h2 {\n font-weight: 300;\n font-size: 3rem;\n}\n\nh2 {\n font-size: 10rem;\n}\n\n.drawer {\n width: 400px;\n}\n.drawer__list-item {\n padding: 0;\n}\n.drawer__list-item-icon {\n margin-right: 1rem;\n}\n.drawer__link {\n display: flex;\n width: 300px;\n padding: 1rem;\n align-items: center;\n text-decoration: none;\n border: 0;\n outline: 0;\n background: transparent;\n font-family: "Quicksand", "Roboto", sans-serif;\n font-size: 1rem;\n font-weight: 400;\n}\n.drawer__link:hover {\n background-color: #fafafa;\n}';
7
- const jsx = jsxRuntime.exports.jsx;
8
- const jsxs = jsxRuntime.exports.jsxs;
9
- const Fragment = jsxRuntime.exports.Fragment;
10
- function Sub() {
11
- return /* @__PURE__ */ jsx("div", {
12
- className: "sub",
13
- children: /* @__PURE__ */ jsx("h2", {
14
- children: "Sub"
15
- })
16
- });
17
- }
18
- function App() {
19
- const [count, setCount] = react.exports.useState(0);
20
- return /* @__PURE__ */ jsx(Fragment, {
21
- children: /* @__PURE__ */ jsxs("div", {
22
- className: "App",
23
- children: [/* @__PURE__ */ jsxs("header", {
24
- className: "App-header",
25
- children: [/* @__PURE__ */ jsx("img", {
26
- src: logo,
27
- className: "App-logo",
28
- alt: "logo"
29
- }), /* @__PURE__ */ jsx("p", {
30
- children: "Hello Vite + React!"
31
- }), /* @__PURE__ */ jsx("p", {
32
- children: /* @__PURE__ */ jsxs("button", {
33
- type: "button",
34
- onClick: () => setCount((count2) => count2 + 1),
35
- children: ["count is: ", count]
36
- })
37
- }), /* @__PURE__ */ jsxs("p", {
38
- children: ["Edit ", /* @__PURE__ */ jsx("code", {
39
- children: "App.jsx"
40
- }), " and save to test HMR updates."]
41
- }), /* @__PURE__ */ jsxs("p", {
42
- children: [/* @__PURE__ */ jsx("a", {
43
- className: "App-link",
44
- href: "https://reactjs.org",
45
- target: "_blank",
46
- rel: "noopener noreferrer",
47
- children: "Learn React"
48
- }), " | ", /* @__PURE__ */ jsx("a", {
49
- className: "App-link",
50
- href: "https://vitejs.dev/guide/features.html",
51
- target: "_blank",
52
- rel: "noopener noreferrer",
53
- children: "Vite Docs"
54
- })]
55
- })]
56
- }), /* @__PURE__ */ jsx(Fragment, {
57
- children: /* @__PURE__ */ jsx(Sub, {})
58
- })]
59
- })
60
- });
61
- }
62
- ReactDOM.render(/* @__PURE__ */ jsx(React.StrictMode, {
63
- children: /* @__PURE__ */ jsx(App, {})
64
- }), document.getElementById("root"));
@@ -1,4 +0,0 @@
1
- let array = [1, 2, 3];
2
-
3
- const multiply = (arr) => arr.map(x => x * 2);
4
- const newArray = multiply(array);
@@ -1,22 +0,0 @@
1
- import { readFile } from "fs/promises";
2
- import { resolve } from "path";
3
- import { parse } from "acorn";
4
- import { astIterator } from "./ast-iterator";
5
-
6
- describe("astIterator", () => {
7
- it("should iterate through all nodes", async () => {
8
- let iterationCount = 0;
9
- const file = await readFile(
10
- resolve(__dirname, "./__mocks__/sample-code-file.js"),
11
- { encoding: "utf-8" }
12
- );
13
- const ast = parse(file, { sourceType: "module", ecmaVersion: 2022 });
14
-
15
- for (const node of astIterator(ast)) {
16
- iterationCount++;
17
- expect(node).toBeTruthy();
18
- }
19
-
20
- expect(iterationCount).toBe(28);
21
- });
22
- });
@@ -1,32 +0,0 @@
1
- const isNode = (obj: any) => {
2
- return (
3
- typeof obj === "object" &&
4
- typeof (obj as any)?.end === "number" &&
5
- typeof (obj as any)?.start === "number" &&
6
- typeof (obj as any)?.type === "string"
7
- );
8
- };
9
-
10
- export const astIterator = function* (ast: any): IterableIterator<any> {
11
- if (!ast) {
12
- return;
13
- }
14
-
15
- for (const key of Object.keys(ast)) {
16
- // Skip useless keys
17
- if (["end", "start", "type"].includes(key)) {
18
- continue;
19
- }
20
-
21
- // If key value is an array, iterate over it
22
- if (Array.isArray(ast[key])) {
23
- for (const nodeIndex in ast[key]) {
24
- yield* astIterator(ast[key][nodeIndex]);
25
- }
26
- } else if (isNode(ast[key])) {
27
- yield* astIterator(ast[key]);
28
- }
29
- }
30
-
31
- yield ast;
32
- };
@@ -1,23 +0,0 @@
1
- import { readFile } from "fs/promises";
2
- import { resolve } from "path";
3
- import { parse } from "acorn";
4
- import { astTransformer } from "./ast-transformer";
5
-
6
- describe("astTransformer", () => {
7
- it("should iterate through all nodes", async () => {
8
- let iterationCount = 0;
9
- const file = await readFile(
10
- resolve(__dirname, "./__mocks__/sample-code-file.js"),
11
- { encoding: "utf-8" }
12
- );
13
- const ast = parse(file, { sourceType: "module", ecmaVersion: 2022 });
14
-
15
- const newAst = astTransformer(ast, (node) => {
16
- iterationCount++;
17
- expect(node).toBeTruthy();
18
- });
19
-
20
- expect(newAst).toBeDefined();
21
- expect(iterationCount).toBe(28);
22
- });
23
- });
@@ -1,28 +0,0 @@
1
- const isNode = (obj: any) => {
2
- return (
3
- typeof obj === "object" &&
4
- typeof (obj as any)?.end === "number" &&
5
- typeof (obj as any)?.start === "number" &&
6
- typeof (obj as any)?.type === "string"
7
- );
8
- };
9
-
10
- export const astTransformer = (ast: any, callback: (ast: any) => any) => {
11
- for (const key of Object.keys(ast)) {
12
- if (["end", "start", "type"].includes(key)) {
13
- continue;
14
- }
15
-
16
- if (Array.isArray(ast[key])) {
17
- for (const nodeIndex in ast[key]) {
18
- ast[key][nodeIndex] = astTransformer(ast[key][nodeIndex], callback);
19
- }
20
- } else if (isNode(ast[key])) {
21
- ast[key] = astTransformer(ast[key], callback);
22
- }
23
- }
24
-
25
- const result = callback(ast);
26
-
27
- return typeof result !== "undefined" ? result : ast;
28
- };
@@ -1,61 +0,0 @@
1
- import { resolve } from "path";
2
- import { readFile } from "fs/promises";
3
- import { parse } from "acorn";
4
- import { generate } from "escodegen";
5
- import { addHashAttributesToJsxTagsAst } from "./ast.utils";
6
-
7
- describe("AST Utils", () => {
8
- beforeEach(() => {
9
- global.implementation = null;
10
- });
11
-
12
- describe("classic implementation", () => {
13
- it("Should add the attr to the right elements", async () => {
14
- const compiled = await readFile(
15
- resolve(__dirname, "./__mocks__/classic-compiled-jsx.js"),
16
- { encoding: "utf-8" }
17
- );
18
- const compiledWithAttr = await readFile(
19
- resolve(__dirname, "./__mocks__/classic-compiled-jsx-with-attr.js"),
20
- { encoding: "utf-8" }
21
- );
22
- const ast = parse(compiled, { ecmaVersion: 2021, sourceType: "module" });
23
- const modifiedAst = addHashAttributesToJsxTagsAst(ast, "data-v-123456");
24
- const modifiedCompiled = generate(modifiedAst, {
25
- format: {
26
- indent: {
27
- style: " ",
28
- },
29
- quotes: "double",
30
- },
31
- });
32
-
33
- expect(modifiedCompiled).toEqual(compiledWithAttr);
34
- });
35
- });
36
-
37
- describe("new implementation", () => {
38
- it("Should add the attr to the right elements", async () => {
39
- const compiled = await readFile(
40
- resolve(__dirname, "./__mocks__/new-compiled-jsx.js"),
41
- { encoding: "utf-8" }
42
- );
43
- const compiledWithAttr = await readFile(
44
- resolve(__dirname, "./__mocks__/new-compiled-jsx-with-attr.js"),
45
- { encoding: "utf-8" }
46
- );
47
- const ast = parse(compiled, { ecmaVersion: 2021, sourceType: "module" });
48
- const modifiedAst = addHashAttributesToJsxTagsAst(ast, "data-v-123456");
49
- const modifiedCompiled = generate(modifiedAst, {
50
- format: {
51
- indent: {
52
- style: " ",
53
- },
54
- quotes: "double",
55
- },
56
- });
57
-
58
- expect(modifiedCompiled).toEqual(compiledWithAttr);
59
- });
60
- });
61
- });
package/src/ast.utils.ts DELETED
@@ -1,53 +0,0 @@
1
- import { astIterator } from "./ast-iterator";
2
- import { astTransformer } from "./ast-transformer";
3
- import { ClassicJsxParser } from "./parsers/classic-parser";
4
- import { JsxParser, ParserImplementations } from "./parsers/jsx-parser.model";
5
- import { NewJsxParser } from "./parsers/new-parser";
6
-
7
- declare global {
8
- // eslint-disable-next-line
9
- var implementation: null | ParserImplementations;
10
- }
11
-
12
- global.implementation = null;
13
-
14
- const classicParser = new ClassicJsxParser();
15
- const newParser = new NewJsxParser();
16
-
17
- let parser: JsxParser = classicParser;
18
-
19
- const findImplementation = (program: any) => {
20
- const implementation: ParserImplementations = ParserImplementations.classic;
21
- for (const node of astIterator(program)) {
22
- if (node.type !== "ImportDeclaration") {
23
- continue;
24
- }
25
-
26
- if (
27
- node.specifiers.some((n: any) =>
28
- ["_jsxDEV", "jsxRuntime"].includes(n.local.name)
29
- ) ||
30
- ["react/jsx-dev-runtime", "react/jsx-runtime"].includes(node.source.value)
31
- ) {
32
- return ParserImplementations.new;
33
- }
34
- }
35
- return implementation;
36
- };
37
-
38
- export function addHashAttributesToJsxTagsAst(program: any, attr: string) {
39
- // Once in the program, we can determine which parser to use
40
- if (global.implementation === null) {
41
- global.implementation = findImplementation(program);
42
-
43
- if (global.implementation === ParserImplementations.new) {
44
- parser = newParser;
45
- }
46
- }
47
-
48
- return astTransformer(program, (node: any) => {
49
- if (parser.isNodeReactElement(node) && !parser.isNodeReactFragment(node)) {
50
- return parser.extendNodeWithAttributes(node, attr);
51
- }
52
- });
53
- }
package/src/index.ts DELETED
@@ -1,164 +0,0 @@
1
- /* eslint-disable no-useless-escape */
2
- import * as path from "path";
3
- import { xxHash32 } from "js-xxhash";
4
- import { createFilter, FilterPattern } from "@rollup/pluginutils";
5
- import { compileStyle } from "@vue/component-compiler-utils";
6
- import { generate } from "escodegen";
7
-
8
- import type { Plugin } from "rollup";
9
- import { addHashAttributesToJsxTagsAst } from "./ast.utils";
10
-
11
- const getFilenameFromPath = (filePath: string) => {
12
- const parts = filePath.split("/");
13
- return parts[parts.length - 1].split("?")[0];
14
- };
15
-
16
- const getHashFromPath = (filePath: string) => {
17
- const search = "?scope=";
18
- const hash = filePath.slice(filePath.indexOf(search) + search.length);
19
- return hash;
20
- };
21
-
22
- const generateHash = (input: string, seed = 0) => {
23
- const hashNum = xxHash32(Buffer.from(input, "utf8"), seed);
24
- return hashNum.toString(16);
25
- };
26
-
27
- const addAttributesToCss = (src: string, fileName: string, hash: string) => {
28
- const { code } = compileStyle({
29
- source: src,
30
- filename: fileName,
31
- id: hash,
32
- scoped: true,
33
- trim: true,
34
- });
35
-
36
- return code;
37
- };
38
-
39
- export interface ReactScopedCssPluginOptions {
40
- /**
41
- * Which files should be included and parsed by the plugin
42
- * Default: undefined
43
- */
44
- include?: FilterPattern;
45
-
46
- /**
47
- * Which files should be exluded and that should not be parsed by the plugin
48
- * Default: undefined
49
- */
50
- exclude?: FilterPattern;
51
-
52
- /**
53
- * If you want to customize the stylesheet file pattern
54
- * if undefined or '' is passed, all files will be evaluated
55
- * Default: 'scoped'
56
- */
57
- styleFileSuffix?: string;
58
-
59
- /**
60
- * If you want to customize the attribute prefix that is added to the jsx elements
61
- * Default: 'v'
62
- */
63
- hashPrefix?: string;
64
-
65
- /**
66
- * If you want to customize the stylesheet extensions
67
- * Default: ['scss', 'css', 'sass', 'less']
68
- */
69
- styleFileExtensions?: string[];
70
-
71
- /**
72
- * If you have jsx in other file extensions
73
- * Default: ['jsx', 'tsx']
74
- */
75
- jsxFileExtensions?: string[];
76
- }
77
-
78
- export interface VitePartialPlugin extends Plugin {
79
- enforce?: "pre" | "post";
80
- }
81
-
82
- export default function reactScopedCssPlugin(
83
- optionsIn: ReactScopedCssPluginOptions = {}
84
- ): VitePartialPlugin[] {
85
- const options: Partial<ReactScopedCssPluginOptions> = {
86
- hashPrefix: "v",
87
- styleFileSuffix: "scoped",
88
- styleFileExtensions: ["scss", "css", "sass", "less"],
89
- jsxFileExtensions: ["jsx", "tsx"],
90
- ...optionsIn,
91
- };
92
-
93
- if (!options.styleFileExtensions || !options.styleFileExtensions.length) {
94
- throw new Error("You need to provide at least one style file extension");
95
- }
96
-
97
- if (!options.jsxFileExtensions || !options.jsxFileExtensions.length) {
98
- throw new Error("You need to provide at least one jsx file extension");
99
- }
100
-
101
- const filter = createFilter(options.include, options.exclude);
102
- const scopedCssRegex = options.styleFileSuffix
103
- ? new RegExp(
104
- `\.${options.styleFileSuffix}\.(${options.styleFileExtensions.join(
105
- "|"
106
- )})$`
107
- )
108
- : new RegExp(`\.(${options.styleFileExtensions.join("|")})$`);
109
- const scopedCssInFileRegex = options.styleFileSuffix
110
- ? new RegExp(
111
- `\.${options.styleFileSuffix}\.(${options.styleFileExtensions.join(
112
- "|"
113
- )})(\"|\')`
114
- )
115
- : new RegExp(`\.(${options.styleFileExtensions.join("|")})(\"|\')`);
116
- const jsxRegex = new RegExp(`\.(${options.jsxFileExtensions.join("|")})$`);
117
-
118
- return [
119
- {
120
- name: "rollup-plugin-react-scoped-css:pre",
121
- resolveId(source, importer) {
122
- if (!importer) {
123
- return;
124
- }
125
-
126
- if (scopedCssRegex.test(source) && jsxRegex.test(importer)) {
127
- const importerHash = generateHash(importer);
128
- const url = path.resolve(
129
- path.dirname(importer),
130
- `${source}?scope=${importerHash}`
131
- );
132
- return url;
133
- }
134
- },
135
- enforce: "pre",
136
- },
137
- {
138
- name: "rollup-plugin-react-scoped-css:post",
139
- transform(code, id) {
140
- if (!filter(id)) {
141
- return;
142
- }
143
- if (scopedCssInFileRegex.test(code)) {
144
- const importerHash = generateHash(id);
145
- const program = this.parse(code);
146
- const newAst = addHashAttributesToJsxTagsAst(
147
- program,
148
- `data-${options.hashPrefix}-${importerHash}`
149
- );
150
- return generate(newAst);
151
- }
152
-
153
- if (scopedCssRegex.test(getFilenameFromPath(id))) {
154
- const importerHash = getHashFromPath(id);
155
- return addAttributesToCss(
156
- code,
157
- getFilenameFromPath(id),
158
- `data-${options.hashPrefix}-${importerHash}`
159
- );
160
- }
161
- },
162
- },
163
- ];
164
- }