From 10ca6cfcf3c56198a30ab7a2328d53cf6b1d891b Mon Sep 17 00:00:00 2001
From: Matt Jones
Date: Mon, 29 Mar 2021 14:17:45 +1100
Subject: [PATCH 01/19] Experiment
---
meta.json | 1 +
out.js | 155 +++++++++++++++++++++++++
packages/webpack-plugin/package.json | 1 +
packages/webpack-plugin/src/esbuild.js | 43 +++++++
yarn.lock | 10 ++
5 files changed, 210 insertions(+)
create mode 100644 meta.json
create mode 100644 out.js
create mode 100644 packages/webpack-plugin/src/esbuild.js
diff --git a/meta.json b/meta.json
new file mode 100644
index 000000000..8d8b724c0
--- /dev/null
+++ b/meta.json
@@ -0,0 +1 @@
+{"inputs":{"fixtures/themed/src/shared.css.ts":{"bytes":179,"imports":[]},"fixtures/themed/src/themes.css.ts":{"bytes":886,"imports":[]},"fixtures/themed/src/styles.css.ts":{"bytes":1799,"imports":[{"path":"fixtures/themed/src/shared.css.ts","kind":"import-statement"},{"path":"fixtures/themed/src/themes.css.ts","kind":"import-statement"}]}},"outputs":{"styles.css.js":{"imports":[],"exports":[],"entryPoint":"fixtures/themed/src/styles.css.ts","inputs":{"fixtures/themed/src/styles.css.ts":{"bytesInOutput":1852},"fixtures/themed/src/shared.css.ts":{"bytesInOutput":201},"fixtures/themed/src/themes.css.ts":{"bytesInOutput":899}},"bytes":4405}}}
\ No newline at end of file
diff --git a/out.js b/out.js
new file mode 100644
index 000000000..59e2565eb
--- /dev/null
+++ b/out.js
@@ -0,0 +1,155 @@
+var __create = Object.create;
+var __defProp = Object.defineProperty;
+var __getProtoOf = Object.getPrototypeOf;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
+var __export = (target, all) => {
+ for (var name in all)
+ __defProp(target, name, {get: all[name], enumerable: true});
+};
+var __exportStar = (target, module2, desc) => {
+ if (module2 && typeof module2 === "object" || typeof module2 === "function") {
+ for (let key of __getOwnPropNames(module2))
+ if (!__hasOwnProp.call(target, key) && key !== "default")
+ __defProp(target, key, {get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable});
+ }
+ return target;
+};
+var __toModule = (module2) => {
+ return __exportStar(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? {get: () => module2.default, enumerable: true} : {value: module2, enumerable: true})), module2);
+};
+
+// fixtures/themed/src/styles.css.ts
+__markAsModule(exports);
+__export(exports, {
+ button: () => button,
+ container: () => container,
+ opacity: () => opacity
+});
+var import_css3 = __toModule(require("@vanilla-extract/css"));
+
+// fixtures/themed/src/shared.css.ts
+var import_css = __toModule(require("@vanilla-extract/css"));
+var shadow = (0, import_css.style)({
+ boxShadow: "0 0 5px red"
+});
+(0, import_css.globalStyle)("body", {
+ backgroundColor: "skyblue"
+});
+
+// fixtures/themed/src/themes.css.ts
+var import_css2 = __toModule(require("@vanilla-extract/css"));
+var theme = (0, import_css2.style)({});
+var vars = (0, import_css2.createGlobalTheme)(`:root, ${theme}`, {
+ colors: {
+ backgroundColor: "blue",
+ text: "white"
+ },
+ space: {
+ 1: "4px",
+ 2: "8px",
+ 3: "12px"
+ }
+});
+var altTheme = (0, import_css2.createTheme)(vars, {
+ colors: {
+ backgroundColor: "green",
+ text: "white"
+ },
+ space: {
+ 1: "8px",
+ 2: "12px",
+ 3: "16px"
+ }
+});
+var responsiveTheme = (0, import_css2.style)({
+ vars: (0, import_css2.assignVars)(vars, {
+ colors: {
+ backgroundColor: "pink",
+ text: "purple"
+ },
+ space: {
+ 1: "6px",
+ 2: "12px",
+ 3: "18px"
+ }
+ }),
+ "@media": {
+ "screen and (min-width: 768px)": {
+ vars: (0, import_css2.assignVars)(vars.colors, {
+ backgroundColor: "purple",
+ text: "pink"
+ })
+ }
+ }
+});
+
+// fixtures/themed/src/styles.css.ts
+var impact = (0, import_css3.fontFace)({
+ src: 'local("Impact")'
+});
+(0, import_css3.globalFontFace)("MyGlobalComicSans", {
+ src: 'local("Comic Sans MS")'
+});
+var slide = (0, import_css3.keyframes)({
+ "0%": {
+ transform: "translateY(-4px)"
+ },
+ "100%": {
+ transform: "translateY(4px)"
+ }
+});
+(0, import_css3.globalKeyframes)("globalSlide", {
+ "0%": {
+ transform: "translateY(-4px)"
+ },
+ "100%": {
+ transform: "translateY(4px)"
+ }
+});
+var container = (0, import_css3.style)({
+ animation: `3s infinite alternate globalSlide ease-in-out`,
+ display: "flex",
+ flexDirection: "column",
+ gap: vars.space[2],
+ padding: vars.space[3],
+ "@media": {
+ "only screen and (min-width: 500px)": {
+ border: `1px solid ${vars.colors.backgroundColor}`
+ }
+ }
+});
+var button = [
+ (0, import_css3.style)({
+ animation: `3s infinite alternate ${slide} ease-in-out`,
+ fontFamily: impact,
+ backgroundColor: (0, import_css3.fallbackVar)(vars.colors.backgroundColor, '"THIS FALLBACK VALUE SHOULD NEVER BE USED"'),
+ color: vars.colors.text,
+ "@media": {
+ "only screen and (min-width: 500px)": {
+ borderRadius: "9999px"
+ }
+ },
+ selectors: {
+ [`${altTheme} ${theme} ${container} &`]: {
+ fontFamily: "MyGlobalComicSans",
+ outline: "5px solid red"
+ }
+ }
+ }),
+ shadow
+];
+var undefinedVar1 = (0, import_css3.createVar)();
+var undefinedVar2 = (0, import_css3.createVar)();
+var opacity = (0, import_css3.mapToStyles)({
+ "1/2": (0, import_css3.fallbackVar)(undefinedVar1, "0.5"),
+ "1/4": (0, import_css3.fallbackVar)(undefinedVar1, undefinedVar2, "0.25")
+}, (value) => ({opacity: value}));
+// Annotate the CommonJS export names for ESM import in node:
+0 && (module.exports = {
+ button,
+ container,
+ opacity
+});
diff --git a/packages/webpack-plugin/package.json b/packages/webpack-plugin/package.json
index 8771e8fda..76513318e 100644
--- a/packages/webpack-plugin/package.json
+++ b/packages/webpack-plugin/package.json
@@ -31,6 +31,7 @@
"chalk": "^4.1.0",
"debug": "^4.3.1",
"dedent": "^0.7.0",
+ "esbuild": "^0.10.2",
"eval": "^0.1.6",
"javascript-stringify": "^2.0.1",
"loader-utils": "^2.0.0",
diff --git a/packages/webpack-plugin/src/esbuild.js b/packages/webpack-plugin/src/esbuild.js
new file mode 100644
index 000000000..17fa9778f
--- /dev/null
+++ b/packages/webpack-plugin/src/esbuild.js
@@ -0,0 +1,43 @@
+const esbuild = require('esbuild');
+
+let startTime = Date.now();
+let result = esbuild.buildSync({
+ entryPoints: [
+ '/Users/mjones/projects/vanilla-extract/fixtures/themed/src/styles.css.ts',
+ ],
+ metafile: true,
+ bundle: true,
+ external: ['@vanilla-extract'],
+ platform: 'node',
+ write: false,
+});
+
+console.log(Date.now() - startTime);
+
+startTime = Date.now();
+result = esbuild.buildSync({
+ entryPoints: [
+ '/Users/mjones/projects/vanilla-extract/fixtures/themed/src/styles.css.ts',
+ ],
+ metafile: true,
+ bundle: true,
+ external: ['@vanilla-extract'],
+ platform: 'node',
+ write: false,
+});
+
+console.log(Date.now() - startTime);
+
+startTime = Date.now();
+result = esbuild.buildSync({
+ entryPoints: [
+ '/Users/mjones/projects/vanilla-extract/fixtures/themed/src/styles.css.ts',
+ ],
+ metafile: true,
+ bundle: true,
+ external: ['@vanilla-extract'],
+ platform: 'node',
+ write: false,
+});
+
+console.log(Date.now() - startTime);
diff --git a/yarn.lock b/yarn.lock
index b60ebcc38..76346a05c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2708,6 +2708,7 @@ __metadata:
chalk: ^4.1.0
debug: ^4.3.1
dedent: ^0.7.0
+ esbuild: ^0.10.2
eval: ^0.1.6
javascript-stringify: ^2.0.1
loader-utils: ^2.0.0
@@ -5054,6 +5055,15 @@ __metadata:
languageName: node
linkType: hard
+"esbuild@npm:^0.10.2":
+ version: 0.10.2
+ resolution: "esbuild@npm:0.10.2"
+ bin:
+ esbuild: bin/esbuild
+ checksum: 54bb44ea101f8dedea286b321c71b9ba2c739e6979b06696009da0bdd4fc8cf61a452e055ddef5b458c25e6c7ce353ba09e56b592b2beaaffaa72b13ed9b4d6c
+ languageName: node
+ linkType: hard
+
"escalade@npm:^3.1.1":
version: 3.1.1
resolution: "escalade@npm:3.1.1"
From c12f4865594e2ace993874db5780bc97a00da05b Mon Sep 17 00:00:00 2001
From: Matt Jones
Date: Tue, 30 Mar 2021 13:56:44 +1100
Subject: [PATCH 02/19] Progress
---
fixtures/themed/esbuild-start.js | 13 +
fixtures/themed/out.js | 1750 ++++++++++++++++++++++++++
packages/esbuild-plugin/package.json | 34 +
packages/esbuild-plugin/src/index.ts | 192 +++
yarn.lock | 28 +
5 files changed, 2017 insertions(+)
create mode 100644 fixtures/themed/esbuild-start.js
create mode 100644 fixtures/themed/out.js
create mode 100644 packages/esbuild-plugin/package.json
create mode 100644 packages/esbuild-plugin/src/index.ts
diff --git a/fixtures/themed/esbuild-start.js b/fixtures/themed/esbuild-start.js
new file mode 100644
index 000000000..6efa874e4
--- /dev/null
+++ b/fixtures/themed/esbuild-start.js
@@ -0,0 +1,13 @@
+const { vanillaExtractPlugin } = require('@vanilla-extract/esbuild-plugin');
+
+require('esbuild')
+ .build({
+ entryPoints: ['src/index.ts'],
+ bundle: true,
+ plugins: [vanillaExtractPlugin()],
+ outfile: 'out.js',
+ })
+ .then(() => console.log('success'))
+ .catch((e) => {
+ console.error(e);
+ });
diff --git a/fixtures/themed/out.js b/fixtures/themed/out.js
new file mode 100644
index 000000000..d67e9c7cb
--- /dev/null
+++ b/fixtures/themed/out.js
@@ -0,0 +1,1750 @@
+(() => {
+ var __create = Object.create;
+ var __defProp = Object.defineProperty;
+ var __getProtoOf = Object.getPrototypeOf;
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
+ var __getOwnPropNames = Object.getOwnPropertyNames;
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+ var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = {exports: {}}).exports, mod), mod.exports);
+ var __exportStar = (target, module, desc) => {
+ if (module && typeof module === "object" || typeof module === "function") {
+ for (let key of __getOwnPropNames(module))
+ if (!__hasOwnProp.call(target, key) && key !== "default")
+ __defProp(target, key, {get: () => module[key], enumerable: !(desc = __getOwnPropDesc(module, key)) || desc.enumerable});
+ }
+ return target;
+ };
+ var __toModule = (module) => {
+ return __exportStar(__markAsModule(__defProp(module != null ? __create(__getProtoOf(module)) : {}, "default", module && module.__esModule && "default" in module ? {get: () => module.default, enumerable: true} : {value: module, enumerable: true})), module);
+ };
+
+ // ../../packages/css/src/utils.ts
+ function get(obj, path) {
+ let result = obj;
+ for (const key of path) {
+ result = result[key];
+ }
+ return result;
+ }
+ function forEach(obj, fn) {
+ for (const key in obj) {
+ fn(obj[key], key);
+ }
+ }
+ function omit(obj, omitKeys) {
+ let result = {};
+ for (const key in obj) {
+ if (omitKeys.indexOf(key) === -1) {
+ result[key] = obj[key];
+ }
+ }
+ return result;
+ }
+ function mapKeys(obj, fn) {
+ let result = {};
+ for (const key in obj) {
+ result[fn(obj[key], key)] = obj[key];
+ }
+ return result;
+ }
+ function walkObject(obj, fn, path = []) {
+ const clone = obj.constructor();
+ for (let key in obj) {
+ const value = obj[key];
+ const currentPath = [...path, key];
+ if (typeof value === "object") {
+ clone[key] = value ? walkObject(value, fn, currentPath) : value;
+ } else if (typeof value === "string" || typeof value === "number") {
+ clone[key] = fn(value, currentPath);
+ } else {
+ console.warn(`Skipping invalid key "${currentPath.join(".")}". Should be a string, number or object. Received: "${typeof value}"`);
+ }
+ }
+ return clone;
+ }
+ function isEqual(a, b) {
+ if (typeof a !== typeof b) {
+ return false;
+ }
+ if (typeof a === "object") {
+ const keys1 = Object.keys(a);
+ const keys2 = Object.keys(b);
+ if (keys1.length !== keys2.length) {
+ return false;
+ }
+ for (const key in a) {
+ if (!isEqual(a[key], b[key])) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return a === b;
+ }
+ }
+ var init_utils = __esm(() => {
+ });
+
+ // ../../packages/css/src/createInlineTheme.ts
+ function createInlineTheme(themeVars, tokens) {
+ const styles = {};
+ walkObject(tokens, (value, path) => {
+ const varName = get(themeVars, path);
+ styles[varName.substring(4, varName.length - 1)] = String(value);
+ });
+ Object.defineProperty(styles, "toString", {
+ value: function() {
+ return Object.keys(this).map((key) => `${key}:${this[key]}`).join(";");
+ },
+ writable: false
+ });
+ return styles;
+ }
+ var init_createInlineTheme = __esm(() => {
+ init_utils();
+ });
+
+ // ../../node_modules/cssesc/cssesc.js
+ var require_cssesc = __commonJS((exports, module) => {
+ /*! https://mths.be/cssesc v3.0.0 by @mathias */
+ "use strict";
+ var object = {};
+ var hasOwnProperty = object.hasOwnProperty;
+ var merge = function merge2(options, defaults) {
+ if (!options) {
+ return defaults;
+ }
+ var result = {};
+ for (var key in defaults) {
+ result[key] = hasOwnProperty.call(options, key) ? options[key] : defaults[key];
+ }
+ return result;
+ };
+ var regexAnySingleEscape = /[ -,\.\/:-@\[-\^`\{-~]/;
+ var regexSingleEscape = /[ -,\.\/:-@\[\]\^`\{-~]/;
+ var regexExcessiveSpaces = /(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g;
+ var cssesc5 = function cssesc6(string, options) {
+ options = merge(options, cssesc6.options);
+ if (options.quotes != "single" && options.quotes != "double") {
+ options.quotes = "single";
+ }
+ var quote = options.quotes == "double" ? '"' : "'";
+ var isIdentifier = options.isIdentifier;
+ var firstChar = string.charAt(0);
+ var output = "";
+ var counter = 0;
+ var length = string.length;
+ while (counter < length) {
+ var character = string.charAt(counter++);
+ var codePoint = character.charCodeAt();
+ var value = void 0;
+ if (codePoint < 32 || codePoint > 126) {
+ if (codePoint >= 55296 && codePoint <= 56319 && counter < length) {
+ var extra = string.charCodeAt(counter++);
+ if ((extra & 64512) == 56320) {
+ codePoint = ((codePoint & 1023) << 10) + (extra & 1023) + 65536;
+ } else {
+ counter--;
+ }
+ }
+ value = "\\" + codePoint.toString(16).toUpperCase() + " ";
+ } else {
+ if (options.escapeEverything) {
+ if (regexAnySingleEscape.test(character)) {
+ value = "\\" + character;
+ } else {
+ value = "\\" + codePoint.toString(16).toUpperCase() + " ";
+ }
+ } else if (/[\t\n\f\r\x0B]/.test(character)) {
+ value = "\\" + codePoint.toString(16).toUpperCase() + " ";
+ } else if (character == "\\" || !isIdentifier && (character == '"' && quote == character || character == "'" && quote == character) || isIdentifier && regexSingleEscape.test(character)) {
+ value = "\\" + character;
+ } else {
+ value = character;
+ }
+ }
+ output += value;
+ }
+ if (isIdentifier) {
+ if (/^-[-\d]/.test(output)) {
+ output = "\\-" + output.slice(1);
+ } else if (/\d/.test(firstChar)) {
+ output = "\\3" + firstChar + " " + output.slice(1);
+ }
+ }
+ output = output.replace(regexExcessiveSpaces, function($0, $1, $2) {
+ if ($1 && $1.length % 2) {
+ return $0;
+ }
+ return ($1 || "") + $2;
+ });
+ if (!isIdentifier && options.wrap) {
+ return quote + output + quote;
+ }
+ return output;
+ };
+ cssesc5.options = {
+ escapeEverything: false,
+ isIdentifier: false,
+ quotes: "single",
+ wrap: false
+ };
+ cssesc5.version = "3.0.0";
+ module.exports = cssesc5;
+ });
+
+ // ../../node_modules/css-selector-parser/lib/utils.js
+ var require_utils = __commonJS((exports) => {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", {value: true});
+ function isIdentStart(c) {
+ return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c === "-" || c === "_";
+ }
+ exports.isIdentStart = isIdentStart;
+ function isIdent(c) {
+ return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c >= "0" && c <= "9" || c === "-" || c === "_";
+ }
+ exports.isIdent = isIdent;
+ function isHex(c) {
+ return c >= "a" && c <= "f" || c >= "A" && c <= "F" || c >= "0" && c <= "9";
+ }
+ exports.isHex = isHex;
+ function escapeIdentifier(s) {
+ var len = s.length;
+ var result = "";
+ var i = 0;
+ while (i < len) {
+ var chr = s.charAt(i);
+ if (exports.identSpecialChars[chr]) {
+ result += "\\" + chr;
+ } else {
+ if (!(chr === "_" || chr === "-" || chr >= "A" && chr <= "Z" || chr >= "a" && chr <= "z" || i !== 0 && chr >= "0" && chr <= "9")) {
+ var charCode = chr.charCodeAt(0);
+ if ((charCode & 63488) === 55296) {
+ var extraCharCode = s.charCodeAt(i++);
+ if ((charCode & 64512) !== 55296 || (extraCharCode & 64512) !== 56320) {
+ throw Error("UCS-2(decode): illegal sequence");
+ }
+ charCode = ((charCode & 1023) << 10) + (extraCharCode & 1023) + 65536;
+ }
+ result += "\\" + charCode.toString(16) + " ";
+ } else {
+ result += chr;
+ }
+ }
+ i++;
+ }
+ return result;
+ }
+ exports.escapeIdentifier = escapeIdentifier;
+ function escapeStr(s) {
+ var len = s.length;
+ var result = "";
+ var i = 0;
+ var replacement;
+ while (i < len) {
+ var chr = s.charAt(i);
+ if (chr === '"') {
+ chr = '\\"';
+ } else if (chr === "\\") {
+ chr = "\\\\";
+ } else if ((replacement = exports.strReplacementsRev[chr]) !== void 0) {
+ chr = replacement;
+ }
+ result += chr;
+ i++;
+ }
+ return '"' + result + '"';
+ }
+ exports.escapeStr = escapeStr;
+ exports.identSpecialChars = {
+ "!": true,
+ '"': true,
+ "#": true,
+ $: true,
+ "%": true,
+ "&": true,
+ "'": true,
+ "(": true,
+ ")": true,
+ "*": true,
+ "+": true,
+ ",": true,
+ ".": true,
+ "/": true,
+ ";": true,
+ "<": true,
+ "=": true,
+ ">": true,
+ "?": true,
+ "@": true,
+ "[": true,
+ "\\": true,
+ "]": true,
+ "^": true,
+ "`": true,
+ "{": true,
+ "|": true,
+ "}": true,
+ "~": true
+ };
+ exports.strReplacementsRev = {
+ "\n": "\\n",
+ "\r": "\\r",
+ " ": "\\t",
+ "\f": "\\f",
+ "\v": "\\v"
+ };
+ exports.singleQuoteEscapeChars = {
+ n: "\n",
+ r: "\r",
+ t: " ",
+ f: "\f",
+ "\\": "\\",
+ "'": "'"
+ };
+ exports.doubleQuotesEscapeChars = {
+ n: "\n",
+ r: "\r",
+ t: " ",
+ f: "\f",
+ "\\": "\\",
+ '"': '"'
+ };
+ });
+
+ // ../../node_modules/css-selector-parser/lib/parser-context.js
+ var require_parser_context = __commonJS((exports) => {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", {value: true});
+ var utils_1 = require_utils();
+ function parseCssSelector(str, pos, pseudos, attrEqualityMods, ruleNestingOperators, substitutesEnabled) {
+ var l = str.length;
+ var chr = "";
+ function getStr(quote, escapeTable) {
+ var result = "";
+ pos++;
+ chr = str.charAt(pos);
+ while (pos < l) {
+ if (chr === quote) {
+ pos++;
+ return result;
+ } else if (chr === "\\") {
+ pos++;
+ chr = str.charAt(pos);
+ var esc = void 0;
+ if (chr === quote) {
+ result += quote;
+ } else if ((esc = escapeTable[chr]) !== void 0) {
+ result += esc;
+ } else if (utils_1.isHex(chr)) {
+ var hex = chr;
+ pos++;
+ chr = str.charAt(pos);
+ while (utils_1.isHex(chr)) {
+ hex += chr;
+ pos++;
+ chr = str.charAt(pos);
+ }
+ if (chr === " ") {
+ pos++;
+ chr = str.charAt(pos);
+ }
+ result += String.fromCharCode(parseInt(hex, 16));
+ continue;
+ } else {
+ result += chr;
+ }
+ } else {
+ result += chr;
+ }
+ pos++;
+ chr = str.charAt(pos);
+ }
+ return result;
+ }
+ function getIdent() {
+ var result = "";
+ chr = str.charAt(pos);
+ while (pos < l) {
+ if (utils_1.isIdent(chr)) {
+ result += chr;
+ } else if (chr === "\\") {
+ pos++;
+ if (pos >= l) {
+ throw Error("Expected symbol but end of file reached.");
+ }
+ chr = str.charAt(pos);
+ if (utils_1.identSpecialChars[chr]) {
+ result += chr;
+ } else if (utils_1.isHex(chr)) {
+ var hex = chr;
+ pos++;
+ chr = str.charAt(pos);
+ while (utils_1.isHex(chr)) {
+ hex += chr;
+ pos++;
+ chr = str.charAt(pos);
+ }
+ if (chr === " ") {
+ pos++;
+ chr = str.charAt(pos);
+ }
+ result += String.fromCharCode(parseInt(hex, 16));
+ continue;
+ } else {
+ result += chr;
+ }
+ } else {
+ return result;
+ }
+ pos++;
+ chr = str.charAt(pos);
+ }
+ return result;
+ }
+ function skipWhitespace() {
+ chr = str.charAt(pos);
+ var result = false;
+ while (chr === " " || chr === " " || chr === "\n" || chr === "\r" || chr === "\f") {
+ result = true;
+ pos++;
+ chr = str.charAt(pos);
+ }
+ return result;
+ }
+ function parse() {
+ var res = parseSelector();
+ if (pos < l) {
+ throw Error('Rule expected but "' + str.charAt(pos) + '" found.');
+ }
+ return res;
+ }
+ function parseSelector() {
+ var selector = parseSingleSelector();
+ if (!selector) {
+ return null;
+ }
+ var res = selector;
+ chr = str.charAt(pos);
+ while (chr === ",") {
+ pos++;
+ skipWhitespace();
+ if (res.type !== "selectors") {
+ res = {
+ type: "selectors",
+ selectors: [selector]
+ };
+ }
+ selector = parseSingleSelector();
+ if (!selector) {
+ throw Error('Rule expected after ",".');
+ }
+ res.selectors.push(selector);
+ }
+ return res;
+ }
+ function parseSingleSelector() {
+ skipWhitespace();
+ var selector = {
+ type: "ruleSet"
+ };
+ var rule = parseRule();
+ if (!rule) {
+ return null;
+ }
+ var currentRule = selector;
+ while (rule) {
+ rule.type = "rule";
+ currentRule.rule = rule;
+ currentRule = rule;
+ skipWhitespace();
+ chr = str.charAt(pos);
+ if (pos >= l || chr === "," || chr === ")") {
+ break;
+ }
+ if (ruleNestingOperators[chr]) {
+ var op = chr;
+ pos++;
+ skipWhitespace();
+ rule = parseRule();
+ if (!rule) {
+ throw Error('Rule expected after "' + op + '".');
+ }
+ rule.nestingOperator = op;
+ } else {
+ rule = parseRule();
+ if (rule) {
+ rule.nestingOperator = null;
+ }
+ }
+ }
+ return selector;
+ }
+ function parseRule() {
+ var rule = null;
+ while (pos < l) {
+ chr = str.charAt(pos);
+ if (chr === "*") {
+ pos++;
+ (rule = rule || {}).tagName = "*";
+ } else if (utils_1.isIdentStart(chr) || chr === "\\") {
+ (rule = rule || {}).tagName = getIdent();
+ } else if (chr === ".") {
+ pos++;
+ rule = rule || {};
+ (rule.classNames = rule.classNames || []).push(getIdent());
+ } else if (chr === "#") {
+ pos++;
+ (rule = rule || {}).id = getIdent();
+ } else if (chr === "[") {
+ pos++;
+ skipWhitespace();
+ var attr = {
+ name: getIdent()
+ };
+ skipWhitespace();
+ if (chr === "]") {
+ pos++;
+ } else {
+ var operator = "";
+ if (attrEqualityMods[chr]) {
+ operator = chr;
+ pos++;
+ chr = str.charAt(pos);
+ }
+ if (pos >= l) {
+ throw Error('Expected "=" but end of file reached.');
+ }
+ if (chr !== "=") {
+ throw Error('Expected "=" but "' + chr + '" found.');
+ }
+ attr.operator = operator + "=";
+ pos++;
+ skipWhitespace();
+ var attrValue = "";
+ attr.valueType = "string";
+ if (chr === '"') {
+ attrValue = getStr('"', utils_1.doubleQuotesEscapeChars);
+ } else if (chr === "'") {
+ attrValue = getStr("'", utils_1.singleQuoteEscapeChars);
+ } else if (substitutesEnabled && chr === "$") {
+ pos++;
+ attrValue = getIdent();
+ attr.valueType = "substitute";
+ } else {
+ while (pos < l) {
+ if (chr === "]") {
+ break;
+ }
+ attrValue += chr;
+ pos++;
+ chr = str.charAt(pos);
+ }
+ attrValue = attrValue.trim();
+ }
+ skipWhitespace();
+ if (pos >= l) {
+ throw Error('Expected "]" but end of file reached.');
+ }
+ if (chr !== "]") {
+ throw Error('Expected "]" but "' + chr + '" found.');
+ }
+ pos++;
+ attr.value = attrValue;
+ }
+ rule = rule || {};
+ (rule.attrs = rule.attrs || []).push(attr);
+ } else if (chr === ":") {
+ pos++;
+ var pseudoName = getIdent();
+ var pseudo = {
+ name: pseudoName
+ };
+ if (chr === "(") {
+ pos++;
+ var value = "";
+ skipWhitespace();
+ if (pseudos[pseudoName] === "selector") {
+ pseudo.valueType = "selector";
+ value = parseSelector();
+ } else {
+ pseudo.valueType = pseudos[pseudoName] || "string";
+ if (chr === '"') {
+ value = getStr('"', utils_1.doubleQuotesEscapeChars);
+ } else if (chr === "'") {
+ value = getStr("'", utils_1.singleQuoteEscapeChars);
+ } else if (substitutesEnabled && chr === "$") {
+ pos++;
+ value = getIdent();
+ pseudo.valueType = "substitute";
+ } else {
+ while (pos < l) {
+ if (chr === ")") {
+ break;
+ }
+ value += chr;
+ pos++;
+ chr = str.charAt(pos);
+ }
+ value = value.trim();
+ }
+ skipWhitespace();
+ }
+ if (pos >= l) {
+ throw Error('Expected ")" but end of file reached.');
+ }
+ if (chr !== ")") {
+ throw Error('Expected ")" but "' + chr + '" found.');
+ }
+ pos++;
+ pseudo.value = value;
+ }
+ rule = rule || {};
+ (rule.pseudos = rule.pseudos || []).push(pseudo);
+ } else {
+ break;
+ }
+ }
+ return rule;
+ }
+ return parse();
+ }
+ exports.parseCssSelector = parseCssSelector;
+ });
+
+ // ../../node_modules/css-selector-parser/lib/render.js
+ var require_render = __commonJS((exports) => {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", {value: true});
+ var utils_1 = require_utils();
+ function renderEntity(entity) {
+ var res = "";
+ switch (entity.type) {
+ case "ruleSet":
+ var currentEntity = entity.rule;
+ var parts = [];
+ while (currentEntity) {
+ if (currentEntity.nestingOperator) {
+ parts.push(currentEntity.nestingOperator);
+ }
+ parts.push(renderEntity(currentEntity));
+ currentEntity = currentEntity.rule;
+ }
+ res = parts.join(" ");
+ break;
+ case "selectors":
+ res = entity.selectors.map(renderEntity).join(", ");
+ break;
+ case "rule":
+ if (entity.tagName) {
+ if (entity.tagName === "*") {
+ res = "*";
+ } else {
+ res = utils_1.escapeIdentifier(entity.tagName);
+ }
+ }
+ if (entity.id) {
+ res += "#" + utils_1.escapeIdentifier(entity.id);
+ }
+ if (entity.classNames) {
+ res += entity.classNames.map(function(cn) {
+ return "." + utils_1.escapeIdentifier(cn);
+ }).join("");
+ }
+ if (entity.attrs) {
+ res += entity.attrs.map(function(attr) {
+ if ("operator" in attr) {
+ if (attr.valueType === "substitute") {
+ return "[" + utils_1.escapeIdentifier(attr.name) + attr.operator + "$" + attr.value + "]";
+ } else {
+ return "[" + utils_1.escapeIdentifier(attr.name) + attr.operator + utils_1.escapeStr(attr.value) + "]";
+ }
+ } else {
+ return "[" + utils_1.escapeIdentifier(attr.name) + "]";
+ }
+ }).join("");
+ }
+ if (entity.pseudos) {
+ res += entity.pseudos.map(function(pseudo) {
+ if (pseudo.valueType) {
+ if (pseudo.valueType === "selector") {
+ return ":" + utils_1.escapeIdentifier(pseudo.name) + "(" + renderEntity(pseudo.value) + ")";
+ } else if (pseudo.valueType === "substitute") {
+ return ":" + utils_1.escapeIdentifier(pseudo.name) + "($" + pseudo.value + ")";
+ } else if (pseudo.valueType === "numeric") {
+ return ":" + utils_1.escapeIdentifier(pseudo.name) + "(" + pseudo.value + ")";
+ } else {
+ return ":" + utils_1.escapeIdentifier(pseudo.name) + "(" + utils_1.escapeIdentifier(pseudo.value) + ")";
+ }
+ } else {
+ return ":" + utils_1.escapeIdentifier(pseudo.name);
+ }
+ }).join("");
+ }
+ break;
+ default:
+ throw Error('Unknown entity type: "' + entity.type + '".');
+ }
+ return res;
+ }
+ exports.renderEntity = renderEntity;
+ });
+
+ // ../../node_modules/css-selector-parser/lib/index.js
+ var require_lib = __commonJS((exports) => {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", {value: true});
+ var parser_context_1 = require_parser_context();
+ var render_1 = require_render();
+ var CssSelectorParser2 = function() {
+ function CssSelectorParser3() {
+ this.pseudos = {};
+ this.attrEqualityMods = {};
+ this.ruleNestingOperators = {};
+ this.substitutesEnabled = false;
+ }
+ CssSelectorParser3.prototype.registerSelectorPseudos = function() {
+ var pseudos = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ pseudos[_i] = arguments[_i];
+ }
+ for (var _a = 0, pseudos_1 = pseudos; _a < pseudos_1.length; _a++) {
+ var pseudo = pseudos_1[_a];
+ this.pseudos[pseudo] = "selector";
+ }
+ return this;
+ };
+ CssSelectorParser3.prototype.unregisterSelectorPseudos = function() {
+ var pseudos = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ pseudos[_i] = arguments[_i];
+ }
+ for (var _a = 0, pseudos_2 = pseudos; _a < pseudos_2.length; _a++) {
+ var pseudo = pseudos_2[_a];
+ delete this.pseudos[pseudo];
+ }
+ return this;
+ };
+ CssSelectorParser3.prototype.registerNumericPseudos = function() {
+ var pseudos = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ pseudos[_i] = arguments[_i];
+ }
+ for (var _a = 0, pseudos_3 = pseudos; _a < pseudos_3.length; _a++) {
+ var pseudo = pseudos_3[_a];
+ this.pseudos[pseudo] = "numeric";
+ }
+ return this;
+ };
+ CssSelectorParser3.prototype.unregisterNumericPseudos = function() {
+ var pseudos = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ pseudos[_i] = arguments[_i];
+ }
+ for (var _a = 0, pseudos_4 = pseudos; _a < pseudos_4.length; _a++) {
+ var pseudo = pseudos_4[_a];
+ delete this.pseudos[pseudo];
+ }
+ return this;
+ };
+ CssSelectorParser3.prototype.registerNestingOperators = function() {
+ var operators = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ operators[_i] = arguments[_i];
+ }
+ for (var _a = 0, operators_1 = operators; _a < operators_1.length; _a++) {
+ var operator = operators_1[_a];
+ this.ruleNestingOperators[operator] = true;
+ }
+ return this;
+ };
+ CssSelectorParser3.prototype.unregisterNestingOperators = function() {
+ var operators = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ operators[_i] = arguments[_i];
+ }
+ for (var _a = 0, operators_2 = operators; _a < operators_2.length; _a++) {
+ var operator = operators_2[_a];
+ delete this.ruleNestingOperators[operator];
+ }
+ return this;
+ };
+ CssSelectorParser3.prototype.registerAttrEqualityMods = function() {
+ var mods = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ mods[_i] = arguments[_i];
+ }
+ for (var _a = 0, mods_1 = mods; _a < mods_1.length; _a++) {
+ var mod = mods_1[_a];
+ this.attrEqualityMods[mod] = true;
+ }
+ return this;
+ };
+ CssSelectorParser3.prototype.unregisterAttrEqualityMods = function() {
+ var mods = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ mods[_i] = arguments[_i];
+ }
+ for (var _a = 0, mods_2 = mods; _a < mods_2.length; _a++) {
+ var mod = mods_2[_a];
+ delete this.attrEqualityMods[mod];
+ }
+ return this;
+ };
+ CssSelectorParser3.prototype.enableSubstitutes = function() {
+ this.substitutesEnabled = true;
+ return this;
+ };
+ CssSelectorParser3.prototype.disableSubstitutes = function() {
+ this.substitutesEnabled = false;
+ return this;
+ };
+ CssSelectorParser3.prototype.parse = function(str) {
+ return parser_context_1.parseCssSelector(str, 0, this.pseudos, this.attrEqualityMods, this.ruleNestingOperators, this.substitutesEnabled);
+ };
+ CssSelectorParser3.prototype.render = function(path) {
+ return render_1.renderEntity(path).trim();
+ };
+ return CssSelectorParser3;
+ }();
+ exports.CssSelectorParser = CssSelectorParser2;
+ });
+
+ // ../../node_modules/dedent/dist/dedent.js
+ var require_dedent = __commonJS((exports, module) => {
+ "use strict";
+ function dedent3(strings) {
+ var raw = void 0;
+ if (typeof strings === "string") {
+ raw = [strings];
+ } else {
+ raw = strings.raw;
+ }
+ var result = "";
+ for (var i = 0; i < raw.length; i++) {
+ result += raw[i].replace(/\\\n[ \t]*/g, "").replace(/\\`/g, "`");
+ if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {
+ result += arguments.length <= i + 1 ? void 0 : arguments[i + 1];
+ }
+ }
+ var lines = result.split("\n");
+ var mindent = null;
+ lines.forEach(function(l) {
+ var m = l.match(/^(\s+)\S+/);
+ if (m) {
+ var indent = m[1].length;
+ if (!mindent) {
+ mindent = indent;
+ } else {
+ mindent = Math.min(mindent, indent);
+ }
+ }
+ });
+ if (mindent !== null) {
+ result = lines.map(function(l) {
+ return l[0] === " " ? l.slice(mindent) : l;
+ }).join("\n");
+ }
+ result = result.trim();
+ return result.replace(/\\n/g, "\n");
+ }
+ if (typeof module !== "undefined") {
+ module.exports = dedent3;
+ }
+ });
+
+ // ../../packages/css/src/validateSelector.ts
+ function escapeRegex(string) {
+ return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
+ }
+ var import_css_selector_parser, import_cssesc, import_dedent, parser, validateSelector;
+ var init_validateSelector = __esm(() => {
+ import_css_selector_parser = __toModule(require_lib());
+ import_cssesc = __toModule(require_cssesc());
+ import_dedent = __toModule(require_dedent());
+ parser = new import_css_selector_parser.CssSelectorParser();
+ parser.registerSelectorPseudos("has");
+ parser.registerNestingOperators(">", "+", "~");
+ parser.registerAttrEqualityMods("^", "$", "*", "~");
+ parser.enableSubstitutes();
+ validateSelector = (selector, targetClassName) => {
+ const replaceTarget = () => {
+ const targetRegex = new RegExp(`.${escapeRegex((0, import_cssesc.default)(targetClassName, {isIdentifier: true}))}`, "g");
+ return selector.replace(targetRegex, "&");
+ };
+ return selector.split(",").map((selectorPart) => {
+ if (selectorPart.indexOf(targetClassName) === -1) {
+ throw new Error(import_dedent.default`
+ Invalid selector: ${replaceTarget()}
+
+ Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
+ `);
+ }
+ let currentRule;
+ try {
+ const result = parser.parse(selectorPart);
+ if (result.type === "ruleSet") {
+ currentRule = result.rule;
+ } else {
+ throw new Error();
+ }
+ } catch (err) {
+ throw new Error(`Invalid selector: ${replaceTarget()}`);
+ }
+ while (currentRule.rule) {
+ currentRule = currentRule.rule;
+ }
+ const targetRule = currentRule;
+ if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find((className) => className === targetClassName)) {
+ throw new Error(import_dedent.default`
+ Invalid selector: ${replaceTarget()}
+
+ Style selectors must end with the '&' character (along with any modifiers), e.g. ${"`${parent} &`"} or ${"`${parent} &:hover`"}.
+
+ This is to ensure that each style block only affects the styling of a single class.
+
+ If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${"`& ${child}`"}) to 'parent', you should add ${"`${parent} &`"} to 'child').
+
+ If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${"`& h1`"}, you should instead write 'globalStyle(${"`${parent} h1`"}, { ... })'
+ `);
+ }
+ });
+ };
+ });
+
+ // ../../packages/css/src/transformCss.ts
+ function dashify(str) {
+ return str.replace(/([A-Z])/g, "-$1").replace(/^ms-/, "-ms-").toLowerCase();
+ }
+ function transformCss({localClassNames: localClassNames2, cssObjs}) {
+ const stylesheet = new Stylesheet(localClassNames2);
+ for (const root2 of cssObjs) {
+ stylesheet.processCssObj(root2);
+ }
+ return stylesheet.toCss();
+ }
+ var import_cssesc2, UNITLESS, simplePseudos, DOUBLE_SPACE, simplePseudoSet, specialKeys, Stylesheet;
+ var init_transformCss = __esm(() => {
+ import_cssesc2 = __toModule(require_cssesc());
+ init_validateSelector();
+ init_utils();
+ UNITLESS = {
+ boxFlex: true,
+ boxFlexGroup: true,
+ columnCount: true,
+ flex: true,
+ flexGrow: true,
+ flexPositive: true,
+ flexShrink: true,
+ flexNegative: true,
+ fontWeight: true,
+ lineClamp: true,
+ lineHeight: true,
+ opacity: true,
+ order: true,
+ orphans: true,
+ tabSize: true,
+ widows: true,
+ zIndex: true,
+ zoom: true,
+ fillOpacity: true,
+ strokeDashoffset: true,
+ strokeOpacity: true,
+ strokeWidth: true
+ };
+ simplePseudos = [
+ ":-moz-any-link",
+ ":-moz-full-screen",
+ ":-moz-placeholder",
+ ":-moz-read-only",
+ ":-moz-read-write",
+ ":-ms-fullscreen",
+ ":-ms-input-placeholder",
+ ":-webkit-any-link",
+ ":-webkit-full-screen",
+ "::-moz-placeholder",
+ "::-moz-progress-bar",
+ "::-moz-range-progress",
+ "::-moz-range-thumb",
+ "::-moz-range-track",
+ "::-moz-selection",
+ "::-ms-backdrop",
+ "::-ms-browse",
+ "::-ms-check",
+ "::-ms-clear",
+ "::-ms-fill",
+ "::-ms-fill-lower",
+ "::-ms-fill-upper",
+ "::-ms-reveal",
+ "::-ms-thumb",
+ "::-ms-ticks-after",
+ "::-ms-ticks-before",
+ "::-ms-tooltip",
+ "::-ms-track",
+ "::-ms-value",
+ "::-webkit-backdrop",
+ "::-webkit-input-placeholder",
+ "::-webkit-progress-bar",
+ "::-webkit-progress-inner-value",
+ "::-webkit-progress-value",
+ "::-webkit-slider-runnable-track",
+ "::-webkit-slider-thumb",
+ "::after",
+ "::backdrop",
+ "::before",
+ "::cue",
+ "::first-letter",
+ "::first-line",
+ "::grammar-error",
+ "::placeholder",
+ "::selection",
+ "::spelling-error",
+ ":active",
+ ":after",
+ ":any-link",
+ ":before",
+ ":blank",
+ ":checked",
+ ":default",
+ ":defined",
+ ":disabled",
+ ":empty",
+ ":enabled",
+ ":first",
+ ":first-child",
+ ":first-letter",
+ ":first-line",
+ ":first-of-type",
+ ":focus",
+ ":focus-visible",
+ ":focus-within",
+ ":fullscreen",
+ ":hover",
+ ":in-range",
+ ":indeterminate",
+ ":invalid",
+ ":last-child",
+ ":last-of-type",
+ ":left",
+ ":link",
+ ":only-child",
+ ":only-of-type",
+ ":optional",
+ ":out-of-range",
+ ":placeholder-shown",
+ ":read-only",
+ ":read-write",
+ ":required",
+ ":right",
+ ":root",
+ ":scope",
+ ":target",
+ ":valid",
+ ":visited"
+ ];
+ DOUBLE_SPACE = " ";
+ simplePseudoSet = new Set(simplePseudos);
+ specialKeys = [...simplePseudos, "@media", "@supports", "selectors"];
+ Stylesheet = class {
+ constructor(localClassNames2) {
+ this.rules = [];
+ this.conditionalRules = [];
+ this.fontFaceRules = [];
+ this.keyframesRules = [];
+ this.localClassNameRegex = localClassNames2.length > 0 ? RegExp(`(${localClassNames2.join("|")})`, "g") : null;
+ }
+ processCssObj(root2) {
+ if (root2.type === "fontFace") {
+ this.fontFaceRules.push(root2.rule);
+ return;
+ }
+ if (root2.type === "keyframes") {
+ this.keyframesRules.push(root2);
+ return;
+ }
+ const mainRule = omit(root2.rule, specialKeys);
+ this.addRule({
+ selector: root2.selector,
+ rule: mainRule
+ });
+ this.transformSimplePsuedos(root2, root2.rule);
+ this.transformMedia(root2, root2.rule["@media"]);
+ this.transformSupports(root2, root2.rule["@supports"]);
+ this.transformSelectors(root2, root2.rule);
+ }
+ addRule(cssRule) {
+ const rule = this.transformVars(this.pixelifyProperties(cssRule.rule));
+ const selector = this.transformSelector(cssRule.selector);
+ if (cssRule.conditions) {
+ this.conditionalRules.push({
+ selector,
+ rule,
+ conditions: cssRule.conditions.sort()
+ });
+ } else {
+ this.rules.push({
+ selector,
+ rule
+ });
+ }
+ }
+ pixelifyProperties(cssRule) {
+ forEach(cssRule, (value, key) => {
+ if (typeof value === "number" && value !== 0 && !UNITLESS[key]) {
+ cssRule[key] = `${value}px`;
+ }
+ });
+ return cssRule;
+ }
+ transformVars({vars: vars2, ...rest}) {
+ if (!vars2) {
+ return rest;
+ }
+ return {
+ ...mapKeys(vars2, (_value, key) => {
+ const matches = key.match(/^var\((.*)\)$/);
+ if (matches) {
+ return matches[1];
+ }
+ return key;
+ }),
+ ...rest
+ };
+ }
+ transformSelector(selector) {
+ return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, className, index) => {
+ if (index > 0 && selector[index - 1] === ".") {
+ return className;
+ }
+ return `.${(0, import_cssesc2.default)(className, {isIdentifier: true})}`;
+ }) : selector;
+ }
+ transformSelectors(root2, rule, conditions) {
+ forEach(rule.selectors, (selectorRule, selector) => {
+ if (root2.type !== "local") {
+ throw new Error(`Selectors are not allowed within ${root2.type === "global" ? '"globalStyle"' : '"selectors"'}`);
+ }
+ const transformedSelector = this.transformSelector(selector.replace(RegExp("&", "g"), root2.selector));
+ validateSelector(transformedSelector, root2.selector);
+ this.addRule({
+ conditions,
+ selector: transformedSelector,
+ rule: omit(selectorRule, specialKeys)
+ });
+ const selectorRoot = {
+ type: "selector",
+ selector: transformedSelector,
+ rule: selectorRule
+ };
+ this.transformSupports(selectorRoot, selectorRule["@supports"], conditions);
+ this.transformMedia(selectorRoot, selectorRule["@media"], conditions);
+ });
+ }
+ transformMedia(root2, rules, parentConditions = []) {
+ forEach(rules, (mediaRule, query) => {
+ const conditions = [`@media ${query}`, ...parentConditions];
+ this.addRule({
+ conditions,
+ selector: root2.selector,
+ rule: omit(mediaRule, specialKeys)
+ });
+ if (root2.type === "local") {
+ this.transformSimplePsuedos(root2, mediaRule, conditions);
+ this.transformSelectors(root2, mediaRule, conditions);
+ }
+ this.transformSupports(root2, mediaRule["@supports"], conditions);
+ });
+ }
+ transformSupports(root2, rules, parentConditions = []) {
+ forEach(rules, (supportsRule, query) => {
+ const conditions = [`@supports ${query}`, ...parentConditions];
+ this.addRule({
+ conditions,
+ selector: root2.selector,
+ rule: omit(supportsRule, specialKeys)
+ });
+ if (root2.type === "local") {
+ this.transformSimplePsuedos(root2, supportsRule, conditions);
+ this.transformSelectors(root2, supportsRule, conditions);
+ }
+ this.transformMedia(root2, supportsRule["@media"], conditions);
+ });
+ }
+ transformSimplePsuedos(root2, rule, conditions) {
+ for (const key of Object.keys(rule)) {
+ if (simplePseudoSet.has(key)) {
+ if (root2.type !== "local") {
+ throw new Error(`Simple pseudos are not valid in ${root2.type === "global" ? '"globalStyle"' : '"selectors"'}`);
+ }
+ this.addRule({
+ conditions,
+ selector: `${root2.selector}${key}`,
+ rule: rule[key]
+ });
+ }
+ }
+ }
+ toPostcssJs() {
+ const styles = {};
+ if (this.fontFaceRules.length > 0) {
+ styles["@font-face"] = this.fontFaceRules;
+ }
+ this.keyframesRules.forEach((rule) => {
+ styles[`@keyframes ${rule.name}`] = rule.rule;
+ });
+ for (const rule of [...this.rules, ...this.conditionalRules]) {
+ if (rule.conditions && isEqual(styles[rule.selector], rule.rule)) {
+ continue;
+ }
+ if (Object.keys(rule.rule).length === 0) {
+ continue;
+ }
+ let styleNode = styles;
+ for (const condition of rule.conditions || []) {
+ if (!styleNode[condition]) {
+ styleNode[condition] = {};
+ }
+ styleNode = styleNode[condition];
+ }
+ styleNode[rule.selector] = {
+ ...styleNode[rule.selector],
+ ...rule.rule
+ };
+ }
+ return styles;
+ }
+ toCss() {
+ const styles = this.toPostcssJs();
+ function walkCss(v, indent = "") {
+ const rules = [];
+ for (const key of Object.keys(v)) {
+ const value = v[key];
+ if (value && Array.isArray(value)) {
+ rules.push(...value.map((v2) => walkCss({[key]: v2}, indent).join("\n")));
+ } else if (value && typeof value === "object") {
+ rules.push(`${indent}${key} {
+${walkCss(value, indent + DOUBLE_SPACE).join("\n")}
+${indent}}`);
+ } else {
+ rules.push(`${indent}${key.startsWith("--") ? key : dashify(key)}: ${value};`);
+ }
+ }
+ return rules;
+ }
+ return walkCss(styles);
+ }
+ };
+ });
+
+ // ../../packages/css/src/adapter.ts
+ var adapter, setAdapter, appendCss, registerClassName;
+ var init_adapter = __esm(() => {
+ adapter = {
+ appendCss: () => {
+ },
+ registerClassName: () => {
+ },
+ onEndFileScope: () => {
+ }
+ };
+ setAdapter = (newAdapter) => {
+ adapter = newAdapter;
+ };
+ appendCss = (...props) => {
+ return adapter.appendCss(...props);
+ };
+ registerClassName = (...props) => {
+ return adapter.registerClassName(...props);
+ };
+ });
+
+ // ../../packages/css/src/runtimeAdapter.ts
+ function getStylesheet(fileScope) {
+ if (stylesheets[fileScope]) {
+ return stylesheets[fileScope];
+ }
+ const styleEl = document.createElement("style");
+ document.head.appendChild(styleEl);
+ if (!styleEl.sheet) {
+ throw new Error(`Couldn't create stylesheet`);
+ }
+ stylesheets[fileScope] = styleEl.sheet;
+ return styleEl.sheet;
+ }
+ var stylesheets, localClassNames, bufferedCSSObjs, browserRuntimeAdapter;
+ var init_runtimeAdapter = __esm(() => {
+ init_transformCss();
+ init_adapter();
+ stylesheets = {};
+ localClassNames = new Set();
+ bufferedCSSObjs = [];
+ browserRuntimeAdapter = {
+ appendCss: (cssObj) => {
+ bufferedCSSObjs.push(cssObj);
+ },
+ registerClassName: (className) => {
+ localClassNames.add(className);
+ },
+ onEndFileScope: (fileScope) => {
+ const css = transformCss({
+ localClassNames: Array.from(localClassNames),
+ cssObjs: bufferedCSSObjs
+ });
+ const stylesheet = getStylesheet(fileScope);
+ const existingRuleCount = stylesheet.cssRules.length;
+ let ruleIndex = 0;
+ for (const rule of css) {
+ try {
+ if (ruleIndex < existingRuleCount) {
+ stylesheet.deleteRule(ruleIndex);
+ }
+ stylesheet.insertRule(rule, ruleIndex++);
+ } catch (e) {
+ console.warn(`Failed to insert rule
+${rule}`);
+ stylesheet.insertRule(".--placeholder-rule--{}", ruleIndex - 1);
+ }
+ }
+ while (ruleIndex < existingRuleCount) {
+ stylesheet.deleteRule(ruleIndex++);
+ }
+ bufferedCSSObjs = [];
+ }
+ };
+ if (typeof window !== "undefined") {
+ setAdapter(browserRuntimeAdapter);
+ }
+ });
+
+ // ../../node_modules/@emotion/hash/dist/hash.browser.esm.js
+ function murmur2(str) {
+ var h = 0;
+ var k, i = 0, len = str.length;
+ for (; len >= 4; ++i, len -= 4) {
+ k = str.charCodeAt(i) & 255 | (str.charCodeAt(++i) & 255) << 8 | (str.charCodeAt(++i) & 255) << 16 | (str.charCodeAt(++i) & 255) << 24;
+ k = (k & 65535) * 1540483477 + ((k >>> 16) * 59797 << 16);
+ k ^= k >>> 24;
+ h = (k & 65535) * 1540483477 + ((k >>> 16) * 59797 << 16) ^ (h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
+ }
+ switch (len) {
+ case 3:
+ h ^= (str.charCodeAt(i + 2) & 255) << 16;
+ case 2:
+ h ^= (str.charCodeAt(i + 1) & 255) << 8;
+ case 1:
+ h ^= str.charCodeAt(i) & 255;
+ h = (h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
+ }
+ h ^= h >>> 13;
+ h = (h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
+ return ((h ^ h >>> 15) >>> 0).toString(36);
+ }
+ var hash_browser_esm_default;
+ var init_hash_browser_esm = __esm(() => {
+ hash_browser_esm_default = murmur2;
+ });
+
+ // ../../packages/css/src/fileScope.ts
+ function getFileScope() {
+ if (fileScopes.length === 0) {
+ throw new Error("New styles cannot be registered dynamically after initial boot. This is to ensure that styles are statically extractible.");
+ }
+ return fileScopes[0];
+ }
+ function getAndIncrementRefCounter() {
+ return refCounter++;
+ }
+ var refCounter, fileScopes;
+ var init_fileScope = __esm(() => {
+ init_adapter();
+ refCounter = 0;
+ fileScopes = [];
+ });
+
+ // ../../packages/css/src/identifier.ts
+ function getShortFileName() {
+ const fileScope = getFileScope();
+ const matches = fileScope.match(/.*\/(.*)\..*\..*$/);
+ if (matches && matches[1]) {
+ return matches[1];
+ }
+ return "";
+ }
+ function generateIdentifier(debugId) {
+ const refCount = getAndIncrementRefCounter();
+ const identifier = process.env.NODE_ENV !== "production" && debugId ? `${getShortFileName()}_${debugId}__${hash_browser_esm_default(getFileScope())}${refCount}` : `${hash_browser_esm_default(getFileScope())}${refCount}`;
+ return identifier.match(/^[0-9]/) ? `_${identifier}` : identifier;
+ }
+ var init_identifier = __esm(() => {
+ init_hash_browser_esm();
+ init_fileScope();
+ });
+
+ // ../../packages/css/src/vars.ts
+ function createVar(debugId) {
+ const refCount = getAndIncrementRefCounter();
+ const varName = process.env.NODE_ENV !== "production" && debugId ? `${debugId}__${hash_browser_esm_default(getFileScope())}${refCount}` : `${hash_browser_esm_default(getFileScope())}${refCount}`;
+ const cssVarName = (0, import_cssesc3.default)(varName.match(/^[0-9]/) ? `_${varName}` : varName, {
+ isIdentifier: true
+ }).replace(/([A-Z])/g, "-$1").toLowerCase();
+ return `var(--${cssVarName})`;
+ }
+ function fallbackVar(...values) {
+ let finalValue = "";
+ values.reverse().forEach((value) => {
+ if (finalValue === "") {
+ finalValue = String(value);
+ } else {
+ if (typeof value !== "string" || !/^var\(--.*\)$/.test(value)) {
+ throw new Error(`Invalid variable name: ${value}`);
+ }
+ finalValue = value.replace(/\)$/, `, ${finalValue})`);
+ }
+ });
+ return finalValue;
+ }
+ function assignVars(varContract, tokens) {
+ const varSetters = {};
+ walkObject(tokens, (value, path) => {
+ varSetters[get(varContract, path)] = String(value);
+ });
+ return varSetters;
+ }
+ function createThemeVars(themeContract) {
+ return walkObject(themeContract, (_value, path) => {
+ return createVar(path.join("-"));
+ });
+ }
+ var import_cssesc3;
+ var init_vars = __esm(() => {
+ init_hash_browser_esm();
+ import_cssesc3 = __toModule(require_cssesc());
+ init_fileScope();
+ init_utils();
+ });
+
+ // ../../packages/css/src/theme.ts
+ function createGlobalTheme(selector, arg2, arg3) {
+ const shouldCreateVars = Boolean(!arg3);
+ const themeVars = shouldCreateVars ? createThemeVars(arg2) : arg2;
+ const tokens = shouldCreateVars ? arg2 : arg3;
+ appendCss({
+ type: "global",
+ selector,
+ rule: {vars: assignVars(themeVars, tokens)}
+ }, getFileScope());
+ if (shouldCreateVars) {
+ return themeVars;
+ }
+ }
+ function createTheme(arg1, arg2, arg3) {
+ const themeClassName = generateIdentifier(typeof arg2 === "object" ? arg3 : arg2);
+ registerClassName(themeClassName);
+ const vars2 = typeof arg2 === "object" ? createGlobalTheme(themeClassName, arg1, arg2) : createGlobalTheme(themeClassName, arg1);
+ return vars2 ? [themeClassName, vars2] : themeClassName;
+ }
+ var init_theme = __esm(() => {
+ init_adapter();
+ init_fileScope();
+ init_identifier();
+ init_vars();
+ });
+
+ // ../../packages/css/src/style.ts
+ function style(rule, debugId) {
+ const className = generateIdentifier(debugId);
+ registerClassName(className);
+ appendCss({type: "local", selector: className, rule}, getFileScope());
+ return className;
+ }
+ function globalStyle(selector, rule) {
+ appendCss({type: "global", selector, rule}, getFileScope());
+ }
+ function fontFace(rule, debugId) {
+ const fontFamily = `"${(0, import_cssesc4.default)(generateIdentifier(debugId), {
+ quotes: "double"
+ })}"`;
+ if ("fontFamily" in rule) {
+ throw new Error(import_dedent2.default`
+ This function creates and returns a hashed font-family name, so the "fontFamily" property should not be provided.
+
+ If you'd like to define a globally scoped custom font, you can use the "globalFontFace" function instead.
+ `);
+ }
+ appendCss({type: "fontFace", rule: {...rule, fontFamily}}, getFileScope());
+ return fontFamily;
+ }
+ function globalFontFace(fontFamily, rule) {
+ appendCss({type: "fontFace", rule: {...rule, fontFamily}}, getFileScope());
+ }
+ function keyframes(rule, debugId) {
+ const name = (0, import_cssesc4.default)(generateIdentifier(debugId), {
+ isIdentifier: true
+ });
+ appendCss({type: "keyframes", name, rule}, getFileScope());
+ return name;
+ }
+ function globalKeyframes(name, rule) {
+ appendCss({type: "keyframes", name, rule}, getFileScope());
+ }
+ function mapToStyles(...args) {
+ if (typeof args[1] === "function") {
+ const data = args[0];
+ const mapData = args[1];
+ const debugId2 = args[2];
+ const classMap2 = {};
+ for (const key in data) {
+ classMap2[key] = style(mapData(data[key], key), debugId2 ? `${debugId2}_${key}` : key);
+ }
+ return classMap2;
+ }
+ const styleMap = args[0];
+ const debugId = args[1];
+ const classMap = {};
+ for (const key in styleMap) {
+ classMap[key] = style(styleMap[key], debugId ? `${debugId}_${key}` : key);
+ }
+ return classMap;
+ }
+ var import_cssesc4, import_dedent2;
+ var init_style = __esm(() => {
+ import_cssesc4 = __toModule(require_cssesc());
+ import_dedent2 = __toModule(require_dedent());
+ init_adapter();
+ init_fileScope();
+ init_identifier();
+ });
+
+ // ../../packages/css/src/index.ts
+ var init_src = __esm(() => {
+ init_runtimeAdapter();
+ init_identifier();
+ init_theme();
+ init_style();
+ init_vars();
+ });
+
+ // src/themes.css.ts
+ var theme, vars, altTheme, responsiveTheme;
+ var init_themes_css = __esm(() => {
+ init_src();
+ theme = style({});
+ vars = createGlobalTheme(`:root, ${theme}`, {
+ colors: {
+ backgroundColor: "blue",
+ text: "white"
+ },
+ space: {
+ 1: "4px",
+ 2: "8px",
+ 3: "12px"
+ }
+ });
+ altTheme = createTheme(vars, {
+ colors: {
+ backgroundColor: "green",
+ text: "white"
+ },
+ space: {
+ 1: "8px",
+ 2: "12px",
+ 3: "16px"
+ }
+ });
+ responsiveTheme = style({
+ vars: assignVars(vars, {
+ colors: {
+ backgroundColor: "pink",
+ text: "purple"
+ },
+ space: {
+ 1: "6px",
+ 2: "12px",
+ 3: "18px"
+ }
+ }),
+ "@media": {
+ "screen and (min-width: 768px)": {
+ vars: assignVars(vars.colors, {
+ backgroundColor: "purple",
+ text: "pink"
+ })
+ }
+ }
+ });
+ });
+
+ // src/shared.css.ts
+ var shadow;
+ var init_shared_css = __esm(() => {
+ init_src();
+ shadow = style({
+ boxShadow: "0 0 5px red"
+ });
+ globalStyle("body", {
+ backgroundColor: "skyblue"
+ });
+ });
+
+ // src/styles.css.ts
+ var impact, slide, container, button, undefinedVar1, undefinedVar2, opacity;
+ var init_styles_css = __esm(() => {
+ init_src();
+ init_shared_css();
+ init_themes_css();
+ impact = fontFace({
+ src: 'local("Impact")'
+ });
+ globalFontFace("MyGlobalComicSans", {
+ src: 'local("Comic Sans MS")'
+ });
+ slide = keyframes({
+ "0%": {
+ transform: "translateY(-4px)"
+ },
+ "100%": {
+ transform: "translateY(4px)"
+ }
+ });
+ globalKeyframes("globalSlide", {
+ "0%": {
+ transform: "translateY(-4px)"
+ },
+ "100%": {
+ transform: "translateY(4px)"
+ }
+ });
+ container = style({
+ animation: `3s infinite alternate globalSlide ease-in-out`,
+ display: "flex",
+ flexDirection: "column",
+ gap: vars.space[2],
+ padding: vars.space[3],
+ "@media": {
+ "only screen and (min-width: 500px)": {
+ border: `1px solid ${vars.colors.backgroundColor}`
+ }
+ }
+ });
+ button = [
+ style({
+ animation: `3s infinite alternate ${slide} ease-in-out`,
+ fontFamily: impact,
+ backgroundColor: fallbackVar(vars.colors.backgroundColor, '"THIS FALLBACK VALUE SHOULD NEVER BE USED"'),
+ color: vars.colors.text,
+ "@media": {
+ "only screen and (min-width: 500px)": {
+ borderRadius: "9999px"
+ }
+ },
+ selectors: {
+ [`${altTheme} ${theme} ${container} &`]: {
+ fontFamily: "MyGlobalComicSans",
+ outline: "5px solid red"
+ }
+ }
+ }),
+ shadow
+ ];
+ undefinedVar1 = createVar();
+ undefinedVar2 = createVar();
+ opacity = mapToStyles({
+ "1/2": fallbackVar(undefinedVar1, "0.5"),
+ "1/4": fallbackVar(undefinedVar1, undefinedVar2, "0.25")
+ }, (value) => ({opacity: value}));
+ });
+
+ // test-nodes.json
+ var root, rootContainer, rootButton, altContainer, altButton, nestedRootContainer, nestedRootButton, inlineThemeContainer, inlineThemeButton, responsiveThemeContainer, responsiveThemeButton, test_nodes_default;
+ var init_test_nodes = __esm(() => {
+ root = "root";
+ rootContainer = "rootContainer";
+ rootButton = "rootButton";
+ altContainer = "altContainer";
+ altButton = "altButton";
+ nestedRootContainer = "nestedRootContainer";
+ nestedRootButton = "nestedRootButton";
+ inlineThemeContainer = "inlineThemeContainer";
+ inlineThemeButton = "inlineThemeButton";
+ responsiveThemeContainer = "responsiveThemeContainer";
+ responsiveThemeButton = "responsiveThemeButton";
+ test_nodes_default = {
+ root,
+ rootContainer,
+ rootButton,
+ altContainer,
+ altButton,
+ nestedRootContainer,
+ nestedRootButton,
+ inlineThemeContainer,
+ inlineThemeButton,
+ responsiveThemeContainer,
+ responsiveThemeButton
+ };
+ });
+
+ // src/index.ts
+ var require_src = __commonJS((exports, module) => {
+ init_createInlineTheme();
+ init_themes_css();
+ init_styles_css();
+ init_shared_css();
+ init_test_nodes();
+ var inlineTheme = createInlineTheme(vars, {
+ colors: {
+ backgroundColor: "orange",
+ text: "black"
+ },
+ space: {
+ 1: "4px",
+ 2: "8px",
+ 3: "12px"
+ }
+ });
+ function render() {
+ document.body.innerHTML = `
+
+ Root theme
+
+
+
+ Alt theme
+
+
+
+ Back to root theme
+
+
+
+ Inline theme
+
+
+
+ Responsive theme
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+ }
+ render();
+ if (module.hot) {
+ module.hot.accept(["./shared.css", "./styles.css", "./themes.css"], () => {
+ render();
+ });
+ }
+ });
+ require_src();
+})();
diff --git a/packages/esbuild-plugin/package.json b/packages/esbuild-plugin/package.json
new file mode 100644
index 000000000..64519b4db
--- /dev/null
+++ b/packages/esbuild-plugin/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "@vanilla-extract/esbuild-plugin",
+ "version": "0.1.0",
+ "description": "Zero-runtime Stylesheets-in-TypeScript",
+ "main": "dist/vanilla-extract-esbuild-plugin.cjs.js",
+ "module": "dist/vanilla-extract-esbuild-plugin.esm.js",
+ "files": [
+ "/dist"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/seek-oss/vanilla-extract.git",
+ "directory": "packages/esbuild-plugin"
+ },
+ "author": "SEEK",
+ "license": "MIT",
+ "peerDependencies": {
+ "esbuild": "*"
+ },
+ "dependencies": {
+ "@vanilla-extract/css": "^0.1.0",
+ "chalk": "^4.1.0",
+ "debug": "^4.3.1",
+ "dedent": "^0.7.0",
+ "eval": "^0.1.6",
+ "javascript-stringify": "^2.0.1",
+ "lodash": "^4.17.21"
+ },
+ "devDependencies": {
+ "@types/debug": "^4.1.5",
+ "@types/dedent": "^0.7.0",
+ "esbuild": "^0.11.1"
+ }
+}
diff --git a/packages/esbuild-plugin/src/index.ts b/packages/esbuild-plugin/src/index.ts
new file mode 100644
index 000000000..ae3557866
--- /dev/null
+++ b/packages/esbuild-plugin/src/index.ts
@@ -0,0 +1,192 @@
+import { join, relative } from 'path';
+import { promises as fs } from 'fs';
+
+import type { Adapter } from '@vanilla-extract/css';
+import { setAdapter } from '@vanilla-extract/css/adapter';
+import { transformCss } from '@vanilla-extract/css/transformCss';
+import dedent from 'dedent';
+import { build as esbuild, Plugin } from 'esbuild';
+// @ts-expect-error
+import evalCode from 'eval';
+import { stringify } from 'javascript-stringify';
+import isPlainObject from 'lodash/isPlainObject';
+
+const vanillaNamespace = 'vanilla-extract-ns';
+const vanillaCssNamespace = 'vanilla-extract-css-ns';
+
+const vanillaExtractFilescopePlugin: Plugin = {
+ name: 'vanilla-extract-filescope',
+ setup(build) {
+ build.onResolve({ filter: /\.css\.(js|jsx|ts|tsx)$/ }, (args) => ({
+ path: args.path,
+ namespace: vanillaNamespace,
+ }));
+
+ build.onLoad(
+ { filter: /.*/, namespace: vanillaNamespace },
+ async ({ path }) => {
+ const originalSource = await fs.readFile(path, 'utf-8');
+
+ const contents = `
+ import { setFileScope, endFileScope } from "@vanilla-extract/css/fileScope";
+ setFileScope("${path}");
+ ${originalSource}
+ endFileScope()
+ `;
+
+ return {
+ contents,
+ };
+ },
+ );
+ },
+};
+
+export function vanillaExtractPlugin(): Plugin {
+ return {
+ name: 'vanilla-extract',
+ setup(build) {
+ build.onResolve({ filter: /vanilla\.css?source=.*$/ }, (args) => ({
+ path: args.path,
+ namespace: vanillaCssNamespace,
+ }));
+
+ build.onLoad(
+ { filter: /.*/, namespace: vanillaCssNamespace },
+ ({ path }) => {
+ const url = new URL(path);
+ const sourceBase64 = url.searchParams.get('source');
+
+ if (!sourceBase64) {
+ throw new Error('No source in vanilla CSS file');
+ }
+
+ return {
+ content: Buffer.from(sourceBase64, 'base64').toString('utf-8'),
+ loader: 'css',
+ };
+ },
+ );
+
+ build.onLoad({ filter: /\.css\.(js|jsx|ts|tsx)$/ }, async ({ path }) => {
+ console.log('Found', path);
+ const result = await esbuild({
+ entryPoints: [path],
+ metafile: true,
+ bundle: true,
+ external: ['@vanilla-extract'],
+ platform: 'node',
+ write: false,
+ plugins: [vanillaExtractFilescopePlugin],
+ });
+
+ const { outputFiles } = result;
+
+ if (outputFiles.length !== 1) {
+ throw new Error('Invalid child compilation');
+ }
+
+ type Css = Parameters[0];
+ const cssByFileScope = new Map>();
+ const localClassNames = new Set();
+
+ const cssAdapter: Adapter = {
+ appendCss: (css, fileScope) => {
+ const fileScopeCss = cssByFileScope.get(fileScope) ?? [];
+
+ fileScopeCss.push(css);
+
+ cssByFileScope.set(fileScope, fileScopeCss);
+ },
+ registerClassName: (className) => {
+ localClassNames.add(className);
+ },
+ onEndFileScope: () => {},
+ };
+
+ setAdapter(cssAdapter);
+
+ const evalResult = evalCode(outputFiles[0], path, { console }, true);
+
+ const cssRequests = [];
+
+ for (const [fileScope, fileScopeCss] of cssByFileScope) {
+ const css = transformCss({
+ localClassNames: Array.from(localClassNames),
+ cssObjs: fileScopeCss,
+ }).join('\n');
+ const base64Css = Buffer.from(css, 'utf-8').toString('base64');
+
+ const absoluteFileScope = join(
+ build.initialOptions.sourceRoot ?? '',
+ fileScope,
+ );
+ const request = relative(path, absoluteFileScope);
+
+ cssRequests.push(`${request}.vanilla.css?source=${base64Css}`);
+ }
+
+ const contents = serializeVanillaModule(cssRequests, evalResult);
+
+ console.log(contents);
+
+ return {
+ contents,
+ loader: 'js',
+ };
+ });
+ },
+ };
+}
+
+const stringifyExports = (value: any) =>
+ stringify(
+ value,
+ (value, _indent, next) => {
+ const valueType = typeof value;
+ if (
+ valueType === 'string' ||
+ valueType === 'number' ||
+ valueType === 'undefined' ||
+ value === null ||
+ Array.isArray(value) ||
+ isPlainObject(value)
+ ) {
+ return next(value);
+ }
+
+ throw new Error(dedent`
+ Invalid exports.
+
+ You can only export plain objects, arrays, strings, numbers and null/undefined.
+ `);
+ },
+ 0,
+ {
+ references: true, // Allow circular references
+ maxDepth: Infinity,
+ maxValues: Infinity,
+ },
+ );
+
+const serializeVanillaModule = (
+ cssRequests: Array,
+ exports: Record,
+) => {
+ const cssImports = cssRequests.map((request) => {
+ return `import '${request}';`;
+ });
+ // // Ensure consitent import order for content hashing
+ // // Chunk ordering is fixed by the webpack plugin
+ // const sortedCssImports = sortBy(cssImports);
+
+ const moduleExports = Object.keys(exports).map((key) =>
+ key === 'default'
+ ? `export default ${stringifyExports(exports[key])};`
+ : `export var ${key} = ${stringifyExports(exports[key])};`,
+ );
+
+ const outputCode = [...cssImports, ...moduleExports];
+
+ return outputCode.join('\n');
+};
diff --git a/yarn.lock b/yarn.lock
index 76346a05c..65fd826de 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2697,6 +2697,25 @@ __metadata:
languageName: unknown
linkType: soft
+"@vanilla-extract/esbuild-plugin@workspace:packages/esbuild-plugin":
+ version: 0.0.0-use.local
+ resolution: "@vanilla-extract/esbuild-plugin@workspace:packages/esbuild-plugin"
+ dependencies:
+ "@types/debug": ^4.1.5
+ "@types/dedent": ^0.7.0
+ "@vanilla-extract/css": ^0.1.0
+ chalk: ^4.1.0
+ debug: ^4.3.1
+ dedent: ^0.7.0
+ esbuild: ^0.11.1
+ eval: ^0.1.6
+ javascript-stringify: ^2.0.1
+ lodash: ^4.17.21
+ peerDependencies:
+ esbuild: "*"
+ languageName: unknown
+ linkType: soft
+
"@vanilla-extract/webpack-plugin@workspace:packages/webpack-plugin":
version: 0.0.0-use.local
resolution: "@vanilla-extract/webpack-plugin@workspace:packages/webpack-plugin"
@@ -5064,6 +5083,15 @@ __metadata:
languageName: node
linkType: hard
+"esbuild@npm:^0.11.1":
+ version: 0.11.1
+ resolution: "esbuild@npm:0.11.1"
+ bin:
+ esbuild: bin/esbuild
+ checksum: 76d8993d3e3c6712ec4106bd5d82222bc22a51e17d0fcc1a1c4ca2253ebf6f3bd26c7f70ff2e4baaa03f41a1ff0423966db3180b401dd8330514ac6d2da1f919
+ languageName: node
+ linkType: hard
+
"escalade@npm:^3.1.1":
version: 3.1.1
resolution: "escalade@npm:3.1.1"
From d22f06834856b4944d293f749d5359f02b57fc93 Mon Sep 17 00:00:00 2001
From: Matt Jones
Date: Tue, 30 Mar 2021 21:55:30 +1100
Subject: [PATCH 03/19] Progress
---
fixtures/themed/esbuild-start.js | 13 -
fixtures/themed/out.js | 1750 -----------------
packages/esbuild-plugin/src/index.ts | 58 +-
test-helpers/package.json | 4 +-
test-helpers/src/startFixture/esbuild.ts | 94 +
test-helpers/src/startFixture/index.ts | 22 +
test-helpers/src/startFixture/types.ts | 11 +
.../webpack.ts} | 19 +-
yarn.lock | 84 +-
9 files changed, 243 insertions(+), 1812 deletions(-)
delete mode 100644 fixtures/themed/esbuild-start.js
delete mode 100644 fixtures/themed/out.js
create mode 100644 test-helpers/src/startFixture/esbuild.ts
create mode 100644 test-helpers/src/startFixture/index.ts
create mode 100644 test-helpers/src/startFixture/types.ts
rename test-helpers/src/{startFixture.ts => startFixture/webpack.ts} (90%)
diff --git a/fixtures/themed/esbuild-start.js b/fixtures/themed/esbuild-start.js
deleted file mode 100644
index 6efa874e4..000000000
--- a/fixtures/themed/esbuild-start.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const { vanillaExtractPlugin } = require('@vanilla-extract/esbuild-plugin');
-
-require('esbuild')
- .build({
- entryPoints: ['src/index.ts'],
- bundle: true,
- plugins: [vanillaExtractPlugin()],
- outfile: 'out.js',
- })
- .then(() => console.log('success'))
- .catch((e) => {
- console.error(e);
- });
diff --git a/fixtures/themed/out.js b/fixtures/themed/out.js
deleted file mode 100644
index d67e9c7cb..000000000
--- a/fixtures/themed/out.js
+++ /dev/null
@@ -1,1750 +0,0 @@
-(() => {
- var __create = Object.create;
- var __defProp = Object.defineProperty;
- var __getProtoOf = Object.getPrototypeOf;
- var __hasOwnProp = Object.prototype.hasOwnProperty;
- var __getOwnPropNames = Object.getOwnPropertyNames;
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
- var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
- var __commonJS = (cb, mod) => () => (mod || cb((mod = {exports: {}}).exports, mod), mod.exports);
- var __exportStar = (target, module, desc) => {
- if (module && typeof module === "object" || typeof module === "function") {
- for (let key of __getOwnPropNames(module))
- if (!__hasOwnProp.call(target, key) && key !== "default")
- __defProp(target, key, {get: () => module[key], enumerable: !(desc = __getOwnPropDesc(module, key)) || desc.enumerable});
- }
- return target;
- };
- var __toModule = (module) => {
- return __exportStar(__markAsModule(__defProp(module != null ? __create(__getProtoOf(module)) : {}, "default", module && module.__esModule && "default" in module ? {get: () => module.default, enumerable: true} : {value: module, enumerable: true})), module);
- };
-
- // ../../packages/css/src/utils.ts
- function get(obj, path) {
- let result = obj;
- for (const key of path) {
- result = result[key];
- }
- return result;
- }
- function forEach(obj, fn) {
- for (const key in obj) {
- fn(obj[key], key);
- }
- }
- function omit(obj, omitKeys) {
- let result = {};
- for (const key in obj) {
- if (omitKeys.indexOf(key) === -1) {
- result[key] = obj[key];
- }
- }
- return result;
- }
- function mapKeys(obj, fn) {
- let result = {};
- for (const key in obj) {
- result[fn(obj[key], key)] = obj[key];
- }
- return result;
- }
- function walkObject(obj, fn, path = []) {
- const clone = obj.constructor();
- for (let key in obj) {
- const value = obj[key];
- const currentPath = [...path, key];
- if (typeof value === "object") {
- clone[key] = value ? walkObject(value, fn, currentPath) : value;
- } else if (typeof value === "string" || typeof value === "number") {
- clone[key] = fn(value, currentPath);
- } else {
- console.warn(`Skipping invalid key "${currentPath.join(".")}". Should be a string, number or object. Received: "${typeof value}"`);
- }
- }
- return clone;
- }
- function isEqual(a, b) {
- if (typeof a !== typeof b) {
- return false;
- }
- if (typeof a === "object") {
- const keys1 = Object.keys(a);
- const keys2 = Object.keys(b);
- if (keys1.length !== keys2.length) {
- return false;
- }
- for (const key in a) {
- if (!isEqual(a[key], b[key])) {
- return false;
- }
- }
- return true;
- } else {
- return a === b;
- }
- }
- var init_utils = __esm(() => {
- });
-
- // ../../packages/css/src/createInlineTheme.ts
- function createInlineTheme(themeVars, tokens) {
- const styles = {};
- walkObject(tokens, (value, path) => {
- const varName = get(themeVars, path);
- styles[varName.substring(4, varName.length - 1)] = String(value);
- });
- Object.defineProperty(styles, "toString", {
- value: function() {
- return Object.keys(this).map((key) => `${key}:${this[key]}`).join(";");
- },
- writable: false
- });
- return styles;
- }
- var init_createInlineTheme = __esm(() => {
- init_utils();
- });
-
- // ../../node_modules/cssesc/cssesc.js
- var require_cssesc = __commonJS((exports, module) => {
- /*! https://mths.be/cssesc v3.0.0 by @mathias */
- "use strict";
- var object = {};
- var hasOwnProperty = object.hasOwnProperty;
- var merge = function merge2(options, defaults) {
- if (!options) {
- return defaults;
- }
- var result = {};
- for (var key in defaults) {
- result[key] = hasOwnProperty.call(options, key) ? options[key] : defaults[key];
- }
- return result;
- };
- var regexAnySingleEscape = /[ -,\.\/:-@\[-\^`\{-~]/;
- var regexSingleEscape = /[ -,\.\/:-@\[\]\^`\{-~]/;
- var regexExcessiveSpaces = /(^|\\+)?(\\[A-F0-9]{1,6})\x20(?![a-fA-F0-9\x20])/g;
- var cssesc5 = function cssesc6(string, options) {
- options = merge(options, cssesc6.options);
- if (options.quotes != "single" && options.quotes != "double") {
- options.quotes = "single";
- }
- var quote = options.quotes == "double" ? '"' : "'";
- var isIdentifier = options.isIdentifier;
- var firstChar = string.charAt(0);
- var output = "";
- var counter = 0;
- var length = string.length;
- while (counter < length) {
- var character = string.charAt(counter++);
- var codePoint = character.charCodeAt();
- var value = void 0;
- if (codePoint < 32 || codePoint > 126) {
- if (codePoint >= 55296 && codePoint <= 56319 && counter < length) {
- var extra = string.charCodeAt(counter++);
- if ((extra & 64512) == 56320) {
- codePoint = ((codePoint & 1023) << 10) + (extra & 1023) + 65536;
- } else {
- counter--;
- }
- }
- value = "\\" + codePoint.toString(16).toUpperCase() + " ";
- } else {
- if (options.escapeEverything) {
- if (regexAnySingleEscape.test(character)) {
- value = "\\" + character;
- } else {
- value = "\\" + codePoint.toString(16).toUpperCase() + " ";
- }
- } else if (/[\t\n\f\r\x0B]/.test(character)) {
- value = "\\" + codePoint.toString(16).toUpperCase() + " ";
- } else if (character == "\\" || !isIdentifier && (character == '"' && quote == character || character == "'" && quote == character) || isIdentifier && regexSingleEscape.test(character)) {
- value = "\\" + character;
- } else {
- value = character;
- }
- }
- output += value;
- }
- if (isIdentifier) {
- if (/^-[-\d]/.test(output)) {
- output = "\\-" + output.slice(1);
- } else if (/\d/.test(firstChar)) {
- output = "\\3" + firstChar + " " + output.slice(1);
- }
- }
- output = output.replace(regexExcessiveSpaces, function($0, $1, $2) {
- if ($1 && $1.length % 2) {
- return $0;
- }
- return ($1 || "") + $2;
- });
- if (!isIdentifier && options.wrap) {
- return quote + output + quote;
- }
- return output;
- };
- cssesc5.options = {
- escapeEverything: false,
- isIdentifier: false,
- quotes: "single",
- wrap: false
- };
- cssesc5.version = "3.0.0";
- module.exports = cssesc5;
- });
-
- // ../../node_modules/css-selector-parser/lib/utils.js
- var require_utils = __commonJS((exports) => {
- "use strict";
- Object.defineProperty(exports, "__esModule", {value: true});
- function isIdentStart(c) {
- return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c === "-" || c === "_";
- }
- exports.isIdentStart = isIdentStart;
- function isIdent(c) {
- return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c >= "0" && c <= "9" || c === "-" || c === "_";
- }
- exports.isIdent = isIdent;
- function isHex(c) {
- return c >= "a" && c <= "f" || c >= "A" && c <= "F" || c >= "0" && c <= "9";
- }
- exports.isHex = isHex;
- function escapeIdentifier(s) {
- var len = s.length;
- var result = "";
- var i = 0;
- while (i < len) {
- var chr = s.charAt(i);
- if (exports.identSpecialChars[chr]) {
- result += "\\" + chr;
- } else {
- if (!(chr === "_" || chr === "-" || chr >= "A" && chr <= "Z" || chr >= "a" && chr <= "z" || i !== 0 && chr >= "0" && chr <= "9")) {
- var charCode = chr.charCodeAt(0);
- if ((charCode & 63488) === 55296) {
- var extraCharCode = s.charCodeAt(i++);
- if ((charCode & 64512) !== 55296 || (extraCharCode & 64512) !== 56320) {
- throw Error("UCS-2(decode): illegal sequence");
- }
- charCode = ((charCode & 1023) << 10) + (extraCharCode & 1023) + 65536;
- }
- result += "\\" + charCode.toString(16) + " ";
- } else {
- result += chr;
- }
- }
- i++;
- }
- return result;
- }
- exports.escapeIdentifier = escapeIdentifier;
- function escapeStr(s) {
- var len = s.length;
- var result = "";
- var i = 0;
- var replacement;
- while (i < len) {
- var chr = s.charAt(i);
- if (chr === '"') {
- chr = '\\"';
- } else if (chr === "\\") {
- chr = "\\\\";
- } else if ((replacement = exports.strReplacementsRev[chr]) !== void 0) {
- chr = replacement;
- }
- result += chr;
- i++;
- }
- return '"' + result + '"';
- }
- exports.escapeStr = escapeStr;
- exports.identSpecialChars = {
- "!": true,
- '"': true,
- "#": true,
- $: true,
- "%": true,
- "&": true,
- "'": true,
- "(": true,
- ")": true,
- "*": true,
- "+": true,
- ",": true,
- ".": true,
- "/": true,
- ";": true,
- "<": true,
- "=": true,
- ">": true,
- "?": true,
- "@": true,
- "[": true,
- "\\": true,
- "]": true,
- "^": true,
- "`": true,
- "{": true,
- "|": true,
- "}": true,
- "~": true
- };
- exports.strReplacementsRev = {
- "\n": "\\n",
- "\r": "\\r",
- " ": "\\t",
- "\f": "\\f",
- "\v": "\\v"
- };
- exports.singleQuoteEscapeChars = {
- n: "\n",
- r: "\r",
- t: " ",
- f: "\f",
- "\\": "\\",
- "'": "'"
- };
- exports.doubleQuotesEscapeChars = {
- n: "\n",
- r: "\r",
- t: " ",
- f: "\f",
- "\\": "\\",
- '"': '"'
- };
- });
-
- // ../../node_modules/css-selector-parser/lib/parser-context.js
- var require_parser_context = __commonJS((exports) => {
- "use strict";
- Object.defineProperty(exports, "__esModule", {value: true});
- var utils_1 = require_utils();
- function parseCssSelector(str, pos, pseudos, attrEqualityMods, ruleNestingOperators, substitutesEnabled) {
- var l = str.length;
- var chr = "";
- function getStr(quote, escapeTable) {
- var result = "";
- pos++;
- chr = str.charAt(pos);
- while (pos < l) {
- if (chr === quote) {
- pos++;
- return result;
- } else if (chr === "\\") {
- pos++;
- chr = str.charAt(pos);
- var esc = void 0;
- if (chr === quote) {
- result += quote;
- } else if ((esc = escapeTable[chr]) !== void 0) {
- result += esc;
- } else if (utils_1.isHex(chr)) {
- var hex = chr;
- pos++;
- chr = str.charAt(pos);
- while (utils_1.isHex(chr)) {
- hex += chr;
- pos++;
- chr = str.charAt(pos);
- }
- if (chr === " ") {
- pos++;
- chr = str.charAt(pos);
- }
- result += String.fromCharCode(parseInt(hex, 16));
- continue;
- } else {
- result += chr;
- }
- } else {
- result += chr;
- }
- pos++;
- chr = str.charAt(pos);
- }
- return result;
- }
- function getIdent() {
- var result = "";
- chr = str.charAt(pos);
- while (pos < l) {
- if (utils_1.isIdent(chr)) {
- result += chr;
- } else if (chr === "\\") {
- pos++;
- if (pos >= l) {
- throw Error("Expected symbol but end of file reached.");
- }
- chr = str.charAt(pos);
- if (utils_1.identSpecialChars[chr]) {
- result += chr;
- } else if (utils_1.isHex(chr)) {
- var hex = chr;
- pos++;
- chr = str.charAt(pos);
- while (utils_1.isHex(chr)) {
- hex += chr;
- pos++;
- chr = str.charAt(pos);
- }
- if (chr === " ") {
- pos++;
- chr = str.charAt(pos);
- }
- result += String.fromCharCode(parseInt(hex, 16));
- continue;
- } else {
- result += chr;
- }
- } else {
- return result;
- }
- pos++;
- chr = str.charAt(pos);
- }
- return result;
- }
- function skipWhitespace() {
- chr = str.charAt(pos);
- var result = false;
- while (chr === " " || chr === " " || chr === "\n" || chr === "\r" || chr === "\f") {
- result = true;
- pos++;
- chr = str.charAt(pos);
- }
- return result;
- }
- function parse() {
- var res = parseSelector();
- if (pos < l) {
- throw Error('Rule expected but "' + str.charAt(pos) + '" found.');
- }
- return res;
- }
- function parseSelector() {
- var selector = parseSingleSelector();
- if (!selector) {
- return null;
- }
- var res = selector;
- chr = str.charAt(pos);
- while (chr === ",") {
- pos++;
- skipWhitespace();
- if (res.type !== "selectors") {
- res = {
- type: "selectors",
- selectors: [selector]
- };
- }
- selector = parseSingleSelector();
- if (!selector) {
- throw Error('Rule expected after ",".');
- }
- res.selectors.push(selector);
- }
- return res;
- }
- function parseSingleSelector() {
- skipWhitespace();
- var selector = {
- type: "ruleSet"
- };
- var rule = parseRule();
- if (!rule) {
- return null;
- }
- var currentRule = selector;
- while (rule) {
- rule.type = "rule";
- currentRule.rule = rule;
- currentRule = rule;
- skipWhitespace();
- chr = str.charAt(pos);
- if (pos >= l || chr === "," || chr === ")") {
- break;
- }
- if (ruleNestingOperators[chr]) {
- var op = chr;
- pos++;
- skipWhitespace();
- rule = parseRule();
- if (!rule) {
- throw Error('Rule expected after "' + op + '".');
- }
- rule.nestingOperator = op;
- } else {
- rule = parseRule();
- if (rule) {
- rule.nestingOperator = null;
- }
- }
- }
- return selector;
- }
- function parseRule() {
- var rule = null;
- while (pos < l) {
- chr = str.charAt(pos);
- if (chr === "*") {
- pos++;
- (rule = rule || {}).tagName = "*";
- } else if (utils_1.isIdentStart(chr) || chr === "\\") {
- (rule = rule || {}).tagName = getIdent();
- } else if (chr === ".") {
- pos++;
- rule = rule || {};
- (rule.classNames = rule.classNames || []).push(getIdent());
- } else if (chr === "#") {
- pos++;
- (rule = rule || {}).id = getIdent();
- } else if (chr === "[") {
- pos++;
- skipWhitespace();
- var attr = {
- name: getIdent()
- };
- skipWhitespace();
- if (chr === "]") {
- pos++;
- } else {
- var operator = "";
- if (attrEqualityMods[chr]) {
- operator = chr;
- pos++;
- chr = str.charAt(pos);
- }
- if (pos >= l) {
- throw Error('Expected "=" but end of file reached.');
- }
- if (chr !== "=") {
- throw Error('Expected "=" but "' + chr + '" found.');
- }
- attr.operator = operator + "=";
- pos++;
- skipWhitespace();
- var attrValue = "";
- attr.valueType = "string";
- if (chr === '"') {
- attrValue = getStr('"', utils_1.doubleQuotesEscapeChars);
- } else if (chr === "'") {
- attrValue = getStr("'", utils_1.singleQuoteEscapeChars);
- } else if (substitutesEnabled && chr === "$") {
- pos++;
- attrValue = getIdent();
- attr.valueType = "substitute";
- } else {
- while (pos < l) {
- if (chr === "]") {
- break;
- }
- attrValue += chr;
- pos++;
- chr = str.charAt(pos);
- }
- attrValue = attrValue.trim();
- }
- skipWhitespace();
- if (pos >= l) {
- throw Error('Expected "]" but end of file reached.');
- }
- if (chr !== "]") {
- throw Error('Expected "]" but "' + chr + '" found.');
- }
- pos++;
- attr.value = attrValue;
- }
- rule = rule || {};
- (rule.attrs = rule.attrs || []).push(attr);
- } else if (chr === ":") {
- pos++;
- var pseudoName = getIdent();
- var pseudo = {
- name: pseudoName
- };
- if (chr === "(") {
- pos++;
- var value = "";
- skipWhitespace();
- if (pseudos[pseudoName] === "selector") {
- pseudo.valueType = "selector";
- value = parseSelector();
- } else {
- pseudo.valueType = pseudos[pseudoName] || "string";
- if (chr === '"') {
- value = getStr('"', utils_1.doubleQuotesEscapeChars);
- } else if (chr === "'") {
- value = getStr("'", utils_1.singleQuoteEscapeChars);
- } else if (substitutesEnabled && chr === "$") {
- pos++;
- value = getIdent();
- pseudo.valueType = "substitute";
- } else {
- while (pos < l) {
- if (chr === ")") {
- break;
- }
- value += chr;
- pos++;
- chr = str.charAt(pos);
- }
- value = value.trim();
- }
- skipWhitespace();
- }
- if (pos >= l) {
- throw Error('Expected ")" but end of file reached.');
- }
- if (chr !== ")") {
- throw Error('Expected ")" but "' + chr + '" found.');
- }
- pos++;
- pseudo.value = value;
- }
- rule = rule || {};
- (rule.pseudos = rule.pseudos || []).push(pseudo);
- } else {
- break;
- }
- }
- return rule;
- }
- return parse();
- }
- exports.parseCssSelector = parseCssSelector;
- });
-
- // ../../node_modules/css-selector-parser/lib/render.js
- var require_render = __commonJS((exports) => {
- "use strict";
- Object.defineProperty(exports, "__esModule", {value: true});
- var utils_1 = require_utils();
- function renderEntity(entity) {
- var res = "";
- switch (entity.type) {
- case "ruleSet":
- var currentEntity = entity.rule;
- var parts = [];
- while (currentEntity) {
- if (currentEntity.nestingOperator) {
- parts.push(currentEntity.nestingOperator);
- }
- parts.push(renderEntity(currentEntity));
- currentEntity = currentEntity.rule;
- }
- res = parts.join(" ");
- break;
- case "selectors":
- res = entity.selectors.map(renderEntity).join(", ");
- break;
- case "rule":
- if (entity.tagName) {
- if (entity.tagName === "*") {
- res = "*";
- } else {
- res = utils_1.escapeIdentifier(entity.tagName);
- }
- }
- if (entity.id) {
- res += "#" + utils_1.escapeIdentifier(entity.id);
- }
- if (entity.classNames) {
- res += entity.classNames.map(function(cn) {
- return "." + utils_1.escapeIdentifier(cn);
- }).join("");
- }
- if (entity.attrs) {
- res += entity.attrs.map(function(attr) {
- if ("operator" in attr) {
- if (attr.valueType === "substitute") {
- return "[" + utils_1.escapeIdentifier(attr.name) + attr.operator + "$" + attr.value + "]";
- } else {
- return "[" + utils_1.escapeIdentifier(attr.name) + attr.operator + utils_1.escapeStr(attr.value) + "]";
- }
- } else {
- return "[" + utils_1.escapeIdentifier(attr.name) + "]";
- }
- }).join("");
- }
- if (entity.pseudos) {
- res += entity.pseudos.map(function(pseudo) {
- if (pseudo.valueType) {
- if (pseudo.valueType === "selector") {
- return ":" + utils_1.escapeIdentifier(pseudo.name) + "(" + renderEntity(pseudo.value) + ")";
- } else if (pseudo.valueType === "substitute") {
- return ":" + utils_1.escapeIdentifier(pseudo.name) + "($" + pseudo.value + ")";
- } else if (pseudo.valueType === "numeric") {
- return ":" + utils_1.escapeIdentifier(pseudo.name) + "(" + pseudo.value + ")";
- } else {
- return ":" + utils_1.escapeIdentifier(pseudo.name) + "(" + utils_1.escapeIdentifier(pseudo.value) + ")";
- }
- } else {
- return ":" + utils_1.escapeIdentifier(pseudo.name);
- }
- }).join("");
- }
- break;
- default:
- throw Error('Unknown entity type: "' + entity.type + '".');
- }
- return res;
- }
- exports.renderEntity = renderEntity;
- });
-
- // ../../node_modules/css-selector-parser/lib/index.js
- var require_lib = __commonJS((exports) => {
- "use strict";
- Object.defineProperty(exports, "__esModule", {value: true});
- var parser_context_1 = require_parser_context();
- var render_1 = require_render();
- var CssSelectorParser2 = function() {
- function CssSelectorParser3() {
- this.pseudos = {};
- this.attrEqualityMods = {};
- this.ruleNestingOperators = {};
- this.substitutesEnabled = false;
- }
- CssSelectorParser3.prototype.registerSelectorPseudos = function() {
- var pseudos = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- pseudos[_i] = arguments[_i];
- }
- for (var _a = 0, pseudos_1 = pseudos; _a < pseudos_1.length; _a++) {
- var pseudo = pseudos_1[_a];
- this.pseudos[pseudo] = "selector";
- }
- return this;
- };
- CssSelectorParser3.prototype.unregisterSelectorPseudos = function() {
- var pseudos = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- pseudos[_i] = arguments[_i];
- }
- for (var _a = 0, pseudos_2 = pseudos; _a < pseudos_2.length; _a++) {
- var pseudo = pseudos_2[_a];
- delete this.pseudos[pseudo];
- }
- return this;
- };
- CssSelectorParser3.prototype.registerNumericPseudos = function() {
- var pseudos = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- pseudos[_i] = arguments[_i];
- }
- for (var _a = 0, pseudos_3 = pseudos; _a < pseudos_3.length; _a++) {
- var pseudo = pseudos_3[_a];
- this.pseudos[pseudo] = "numeric";
- }
- return this;
- };
- CssSelectorParser3.prototype.unregisterNumericPseudos = function() {
- var pseudos = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- pseudos[_i] = arguments[_i];
- }
- for (var _a = 0, pseudos_4 = pseudos; _a < pseudos_4.length; _a++) {
- var pseudo = pseudos_4[_a];
- delete this.pseudos[pseudo];
- }
- return this;
- };
- CssSelectorParser3.prototype.registerNestingOperators = function() {
- var operators = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- operators[_i] = arguments[_i];
- }
- for (var _a = 0, operators_1 = operators; _a < operators_1.length; _a++) {
- var operator = operators_1[_a];
- this.ruleNestingOperators[operator] = true;
- }
- return this;
- };
- CssSelectorParser3.prototype.unregisterNestingOperators = function() {
- var operators = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- operators[_i] = arguments[_i];
- }
- for (var _a = 0, operators_2 = operators; _a < operators_2.length; _a++) {
- var operator = operators_2[_a];
- delete this.ruleNestingOperators[operator];
- }
- return this;
- };
- CssSelectorParser3.prototype.registerAttrEqualityMods = function() {
- var mods = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- mods[_i] = arguments[_i];
- }
- for (var _a = 0, mods_1 = mods; _a < mods_1.length; _a++) {
- var mod = mods_1[_a];
- this.attrEqualityMods[mod] = true;
- }
- return this;
- };
- CssSelectorParser3.prototype.unregisterAttrEqualityMods = function() {
- var mods = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- mods[_i] = arguments[_i];
- }
- for (var _a = 0, mods_2 = mods; _a < mods_2.length; _a++) {
- var mod = mods_2[_a];
- delete this.attrEqualityMods[mod];
- }
- return this;
- };
- CssSelectorParser3.prototype.enableSubstitutes = function() {
- this.substitutesEnabled = true;
- return this;
- };
- CssSelectorParser3.prototype.disableSubstitutes = function() {
- this.substitutesEnabled = false;
- return this;
- };
- CssSelectorParser3.prototype.parse = function(str) {
- return parser_context_1.parseCssSelector(str, 0, this.pseudos, this.attrEqualityMods, this.ruleNestingOperators, this.substitutesEnabled);
- };
- CssSelectorParser3.prototype.render = function(path) {
- return render_1.renderEntity(path).trim();
- };
- return CssSelectorParser3;
- }();
- exports.CssSelectorParser = CssSelectorParser2;
- });
-
- // ../../node_modules/dedent/dist/dedent.js
- var require_dedent = __commonJS((exports, module) => {
- "use strict";
- function dedent3(strings) {
- var raw = void 0;
- if (typeof strings === "string") {
- raw = [strings];
- } else {
- raw = strings.raw;
- }
- var result = "";
- for (var i = 0; i < raw.length; i++) {
- result += raw[i].replace(/\\\n[ \t]*/g, "").replace(/\\`/g, "`");
- if (i < (arguments.length <= 1 ? 0 : arguments.length - 1)) {
- result += arguments.length <= i + 1 ? void 0 : arguments[i + 1];
- }
- }
- var lines = result.split("\n");
- var mindent = null;
- lines.forEach(function(l) {
- var m = l.match(/^(\s+)\S+/);
- if (m) {
- var indent = m[1].length;
- if (!mindent) {
- mindent = indent;
- } else {
- mindent = Math.min(mindent, indent);
- }
- }
- });
- if (mindent !== null) {
- result = lines.map(function(l) {
- return l[0] === " " ? l.slice(mindent) : l;
- }).join("\n");
- }
- result = result.trim();
- return result.replace(/\\n/g, "\n");
- }
- if (typeof module !== "undefined") {
- module.exports = dedent3;
- }
- });
-
- // ../../packages/css/src/validateSelector.ts
- function escapeRegex(string) {
- return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
- }
- var import_css_selector_parser, import_cssesc, import_dedent, parser, validateSelector;
- var init_validateSelector = __esm(() => {
- import_css_selector_parser = __toModule(require_lib());
- import_cssesc = __toModule(require_cssesc());
- import_dedent = __toModule(require_dedent());
- parser = new import_css_selector_parser.CssSelectorParser();
- parser.registerSelectorPseudos("has");
- parser.registerNestingOperators(">", "+", "~");
- parser.registerAttrEqualityMods("^", "$", "*", "~");
- parser.enableSubstitutes();
- validateSelector = (selector, targetClassName) => {
- const replaceTarget = () => {
- const targetRegex = new RegExp(`.${escapeRegex((0, import_cssesc.default)(targetClassName, {isIdentifier: true}))}`, "g");
- return selector.replace(targetRegex, "&");
- };
- return selector.split(",").map((selectorPart) => {
- if (selectorPart.indexOf(targetClassName) === -1) {
- throw new Error(import_dedent.default`
- Invalid selector: ${replaceTarget()}
-
- Selectors must target the ampersand character ('&'), which refers to the generated class name, e.g. '&:nth-child(2n)'
- `);
- }
- let currentRule;
- try {
- const result = parser.parse(selectorPart);
- if (result.type === "ruleSet") {
- currentRule = result.rule;
- } else {
- throw new Error();
- }
- } catch (err) {
- throw new Error(`Invalid selector: ${replaceTarget()}`);
- }
- while (currentRule.rule) {
- currentRule = currentRule.rule;
- }
- const targetRule = currentRule;
- if (!Array.isArray(targetRule.classNames) || !targetRule.classNames.find((className) => className === targetClassName)) {
- throw new Error(import_dedent.default`
- Invalid selector: ${replaceTarget()}
-
- Style selectors must end with the '&' character (along with any modifiers), e.g. ${"`${parent} &`"} or ${"`${parent} &:hover`"}.
-
- This is to ensure that each style block only affects the styling of a single class.
-
- If your selector is targeting another class, you should move it to the style definition for that class, e.g. given we have styles for 'parent' and 'child' elements, instead of adding a selector of ${"`& ${child}`"}) to 'parent', you should add ${"`${parent} &`"} to 'child').
-
- If your selector is targeting something global, use the 'globalStyle' function instead, e.g. if you wanted to write ${"`& h1`"}, you should instead write 'globalStyle(${"`${parent} h1`"}, { ... })'
- `);
- }
- });
- };
- });
-
- // ../../packages/css/src/transformCss.ts
- function dashify(str) {
- return str.replace(/([A-Z])/g, "-$1").replace(/^ms-/, "-ms-").toLowerCase();
- }
- function transformCss({localClassNames: localClassNames2, cssObjs}) {
- const stylesheet = new Stylesheet(localClassNames2);
- for (const root2 of cssObjs) {
- stylesheet.processCssObj(root2);
- }
- return stylesheet.toCss();
- }
- var import_cssesc2, UNITLESS, simplePseudos, DOUBLE_SPACE, simplePseudoSet, specialKeys, Stylesheet;
- var init_transformCss = __esm(() => {
- import_cssesc2 = __toModule(require_cssesc());
- init_validateSelector();
- init_utils();
- UNITLESS = {
- boxFlex: true,
- boxFlexGroup: true,
- columnCount: true,
- flex: true,
- flexGrow: true,
- flexPositive: true,
- flexShrink: true,
- flexNegative: true,
- fontWeight: true,
- lineClamp: true,
- lineHeight: true,
- opacity: true,
- order: true,
- orphans: true,
- tabSize: true,
- widows: true,
- zIndex: true,
- zoom: true,
- fillOpacity: true,
- strokeDashoffset: true,
- strokeOpacity: true,
- strokeWidth: true
- };
- simplePseudos = [
- ":-moz-any-link",
- ":-moz-full-screen",
- ":-moz-placeholder",
- ":-moz-read-only",
- ":-moz-read-write",
- ":-ms-fullscreen",
- ":-ms-input-placeholder",
- ":-webkit-any-link",
- ":-webkit-full-screen",
- "::-moz-placeholder",
- "::-moz-progress-bar",
- "::-moz-range-progress",
- "::-moz-range-thumb",
- "::-moz-range-track",
- "::-moz-selection",
- "::-ms-backdrop",
- "::-ms-browse",
- "::-ms-check",
- "::-ms-clear",
- "::-ms-fill",
- "::-ms-fill-lower",
- "::-ms-fill-upper",
- "::-ms-reveal",
- "::-ms-thumb",
- "::-ms-ticks-after",
- "::-ms-ticks-before",
- "::-ms-tooltip",
- "::-ms-track",
- "::-ms-value",
- "::-webkit-backdrop",
- "::-webkit-input-placeholder",
- "::-webkit-progress-bar",
- "::-webkit-progress-inner-value",
- "::-webkit-progress-value",
- "::-webkit-slider-runnable-track",
- "::-webkit-slider-thumb",
- "::after",
- "::backdrop",
- "::before",
- "::cue",
- "::first-letter",
- "::first-line",
- "::grammar-error",
- "::placeholder",
- "::selection",
- "::spelling-error",
- ":active",
- ":after",
- ":any-link",
- ":before",
- ":blank",
- ":checked",
- ":default",
- ":defined",
- ":disabled",
- ":empty",
- ":enabled",
- ":first",
- ":first-child",
- ":first-letter",
- ":first-line",
- ":first-of-type",
- ":focus",
- ":focus-visible",
- ":focus-within",
- ":fullscreen",
- ":hover",
- ":in-range",
- ":indeterminate",
- ":invalid",
- ":last-child",
- ":last-of-type",
- ":left",
- ":link",
- ":only-child",
- ":only-of-type",
- ":optional",
- ":out-of-range",
- ":placeholder-shown",
- ":read-only",
- ":read-write",
- ":required",
- ":right",
- ":root",
- ":scope",
- ":target",
- ":valid",
- ":visited"
- ];
- DOUBLE_SPACE = " ";
- simplePseudoSet = new Set(simplePseudos);
- specialKeys = [...simplePseudos, "@media", "@supports", "selectors"];
- Stylesheet = class {
- constructor(localClassNames2) {
- this.rules = [];
- this.conditionalRules = [];
- this.fontFaceRules = [];
- this.keyframesRules = [];
- this.localClassNameRegex = localClassNames2.length > 0 ? RegExp(`(${localClassNames2.join("|")})`, "g") : null;
- }
- processCssObj(root2) {
- if (root2.type === "fontFace") {
- this.fontFaceRules.push(root2.rule);
- return;
- }
- if (root2.type === "keyframes") {
- this.keyframesRules.push(root2);
- return;
- }
- const mainRule = omit(root2.rule, specialKeys);
- this.addRule({
- selector: root2.selector,
- rule: mainRule
- });
- this.transformSimplePsuedos(root2, root2.rule);
- this.transformMedia(root2, root2.rule["@media"]);
- this.transformSupports(root2, root2.rule["@supports"]);
- this.transformSelectors(root2, root2.rule);
- }
- addRule(cssRule) {
- const rule = this.transformVars(this.pixelifyProperties(cssRule.rule));
- const selector = this.transformSelector(cssRule.selector);
- if (cssRule.conditions) {
- this.conditionalRules.push({
- selector,
- rule,
- conditions: cssRule.conditions.sort()
- });
- } else {
- this.rules.push({
- selector,
- rule
- });
- }
- }
- pixelifyProperties(cssRule) {
- forEach(cssRule, (value, key) => {
- if (typeof value === "number" && value !== 0 && !UNITLESS[key]) {
- cssRule[key] = `${value}px`;
- }
- });
- return cssRule;
- }
- transformVars({vars: vars2, ...rest}) {
- if (!vars2) {
- return rest;
- }
- return {
- ...mapKeys(vars2, (_value, key) => {
- const matches = key.match(/^var\((.*)\)$/);
- if (matches) {
- return matches[1];
- }
- return key;
- }),
- ...rest
- };
- }
- transformSelector(selector) {
- return this.localClassNameRegex ? selector.replace(this.localClassNameRegex, (_, className, index) => {
- if (index > 0 && selector[index - 1] === ".") {
- return className;
- }
- return `.${(0, import_cssesc2.default)(className, {isIdentifier: true})}`;
- }) : selector;
- }
- transformSelectors(root2, rule, conditions) {
- forEach(rule.selectors, (selectorRule, selector) => {
- if (root2.type !== "local") {
- throw new Error(`Selectors are not allowed within ${root2.type === "global" ? '"globalStyle"' : '"selectors"'}`);
- }
- const transformedSelector = this.transformSelector(selector.replace(RegExp("&", "g"), root2.selector));
- validateSelector(transformedSelector, root2.selector);
- this.addRule({
- conditions,
- selector: transformedSelector,
- rule: omit(selectorRule, specialKeys)
- });
- const selectorRoot = {
- type: "selector",
- selector: transformedSelector,
- rule: selectorRule
- };
- this.transformSupports(selectorRoot, selectorRule["@supports"], conditions);
- this.transformMedia(selectorRoot, selectorRule["@media"], conditions);
- });
- }
- transformMedia(root2, rules, parentConditions = []) {
- forEach(rules, (mediaRule, query) => {
- const conditions = [`@media ${query}`, ...parentConditions];
- this.addRule({
- conditions,
- selector: root2.selector,
- rule: omit(mediaRule, specialKeys)
- });
- if (root2.type === "local") {
- this.transformSimplePsuedos(root2, mediaRule, conditions);
- this.transformSelectors(root2, mediaRule, conditions);
- }
- this.transformSupports(root2, mediaRule["@supports"], conditions);
- });
- }
- transformSupports(root2, rules, parentConditions = []) {
- forEach(rules, (supportsRule, query) => {
- const conditions = [`@supports ${query}`, ...parentConditions];
- this.addRule({
- conditions,
- selector: root2.selector,
- rule: omit(supportsRule, specialKeys)
- });
- if (root2.type === "local") {
- this.transformSimplePsuedos(root2, supportsRule, conditions);
- this.transformSelectors(root2, supportsRule, conditions);
- }
- this.transformMedia(root2, supportsRule["@media"], conditions);
- });
- }
- transformSimplePsuedos(root2, rule, conditions) {
- for (const key of Object.keys(rule)) {
- if (simplePseudoSet.has(key)) {
- if (root2.type !== "local") {
- throw new Error(`Simple pseudos are not valid in ${root2.type === "global" ? '"globalStyle"' : '"selectors"'}`);
- }
- this.addRule({
- conditions,
- selector: `${root2.selector}${key}`,
- rule: rule[key]
- });
- }
- }
- }
- toPostcssJs() {
- const styles = {};
- if (this.fontFaceRules.length > 0) {
- styles["@font-face"] = this.fontFaceRules;
- }
- this.keyframesRules.forEach((rule) => {
- styles[`@keyframes ${rule.name}`] = rule.rule;
- });
- for (const rule of [...this.rules, ...this.conditionalRules]) {
- if (rule.conditions && isEqual(styles[rule.selector], rule.rule)) {
- continue;
- }
- if (Object.keys(rule.rule).length === 0) {
- continue;
- }
- let styleNode = styles;
- for (const condition of rule.conditions || []) {
- if (!styleNode[condition]) {
- styleNode[condition] = {};
- }
- styleNode = styleNode[condition];
- }
- styleNode[rule.selector] = {
- ...styleNode[rule.selector],
- ...rule.rule
- };
- }
- return styles;
- }
- toCss() {
- const styles = this.toPostcssJs();
- function walkCss(v, indent = "") {
- const rules = [];
- for (const key of Object.keys(v)) {
- const value = v[key];
- if (value && Array.isArray(value)) {
- rules.push(...value.map((v2) => walkCss({[key]: v2}, indent).join("\n")));
- } else if (value && typeof value === "object") {
- rules.push(`${indent}${key} {
-${walkCss(value, indent + DOUBLE_SPACE).join("\n")}
-${indent}}`);
- } else {
- rules.push(`${indent}${key.startsWith("--") ? key : dashify(key)}: ${value};`);
- }
- }
- return rules;
- }
- return walkCss(styles);
- }
- };
- });
-
- // ../../packages/css/src/adapter.ts
- var adapter, setAdapter, appendCss, registerClassName;
- var init_adapter = __esm(() => {
- adapter = {
- appendCss: () => {
- },
- registerClassName: () => {
- },
- onEndFileScope: () => {
- }
- };
- setAdapter = (newAdapter) => {
- adapter = newAdapter;
- };
- appendCss = (...props) => {
- return adapter.appendCss(...props);
- };
- registerClassName = (...props) => {
- return adapter.registerClassName(...props);
- };
- });
-
- // ../../packages/css/src/runtimeAdapter.ts
- function getStylesheet(fileScope) {
- if (stylesheets[fileScope]) {
- return stylesheets[fileScope];
- }
- const styleEl = document.createElement("style");
- document.head.appendChild(styleEl);
- if (!styleEl.sheet) {
- throw new Error(`Couldn't create stylesheet`);
- }
- stylesheets[fileScope] = styleEl.sheet;
- return styleEl.sheet;
- }
- var stylesheets, localClassNames, bufferedCSSObjs, browserRuntimeAdapter;
- var init_runtimeAdapter = __esm(() => {
- init_transformCss();
- init_adapter();
- stylesheets = {};
- localClassNames = new Set();
- bufferedCSSObjs = [];
- browserRuntimeAdapter = {
- appendCss: (cssObj) => {
- bufferedCSSObjs.push(cssObj);
- },
- registerClassName: (className) => {
- localClassNames.add(className);
- },
- onEndFileScope: (fileScope) => {
- const css = transformCss({
- localClassNames: Array.from(localClassNames),
- cssObjs: bufferedCSSObjs
- });
- const stylesheet = getStylesheet(fileScope);
- const existingRuleCount = stylesheet.cssRules.length;
- let ruleIndex = 0;
- for (const rule of css) {
- try {
- if (ruleIndex < existingRuleCount) {
- stylesheet.deleteRule(ruleIndex);
- }
- stylesheet.insertRule(rule, ruleIndex++);
- } catch (e) {
- console.warn(`Failed to insert rule
-${rule}`);
- stylesheet.insertRule(".--placeholder-rule--{}", ruleIndex - 1);
- }
- }
- while (ruleIndex < existingRuleCount) {
- stylesheet.deleteRule(ruleIndex++);
- }
- bufferedCSSObjs = [];
- }
- };
- if (typeof window !== "undefined") {
- setAdapter(browserRuntimeAdapter);
- }
- });
-
- // ../../node_modules/@emotion/hash/dist/hash.browser.esm.js
- function murmur2(str) {
- var h = 0;
- var k, i = 0, len = str.length;
- for (; len >= 4; ++i, len -= 4) {
- k = str.charCodeAt(i) & 255 | (str.charCodeAt(++i) & 255) << 8 | (str.charCodeAt(++i) & 255) << 16 | (str.charCodeAt(++i) & 255) << 24;
- k = (k & 65535) * 1540483477 + ((k >>> 16) * 59797 << 16);
- k ^= k >>> 24;
- h = (k & 65535) * 1540483477 + ((k >>> 16) * 59797 << 16) ^ (h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
- }
- switch (len) {
- case 3:
- h ^= (str.charCodeAt(i + 2) & 255) << 16;
- case 2:
- h ^= (str.charCodeAt(i + 1) & 255) << 8;
- case 1:
- h ^= str.charCodeAt(i) & 255;
- h = (h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
- }
- h ^= h >>> 13;
- h = (h & 65535) * 1540483477 + ((h >>> 16) * 59797 << 16);
- return ((h ^ h >>> 15) >>> 0).toString(36);
- }
- var hash_browser_esm_default;
- var init_hash_browser_esm = __esm(() => {
- hash_browser_esm_default = murmur2;
- });
-
- // ../../packages/css/src/fileScope.ts
- function getFileScope() {
- if (fileScopes.length === 0) {
- throw new Error("New styles cannot be registered dynamically after initial boot. This is to ensure that styles are statically extractible.");
- }
- return fileScopes[0];
- }
- function getAndIncrementRefCounter() {
- return refCounter++;
- }
- var refCounter, fileScopes;
- var init_fileScope = __esm(() => {
- init_adapter();
- refCounter = 0;
- fileScopes = [];
- });
-
- // ../../packages/css/src/identifier.ts
- function getShortFileName() {
- const fileScope = getFileScope();
- const matches = fileScope.match(/.*\/(.*)\..*\..*$/);
- if (matches && matches[1]) {
- return matches[1];
- }
- return "";
- }
- function generateIdentifier(debugId) {
- const refCount = getAndIncrementRefCounter();
- const identifier = process.env.NODE_ENV !== "production" && debugId ? `${getShortFileName()}_${debugId}__${hash_browser_esm_default(getFileScope())}${refCount}` : `${hash_browser_esm_default(getFileScope())}${refCount}`;
- return identifier.match(/^[0-9]/) ? `_${identifier}` : identifier;
- }
- var init_identifier = __esm(() => {
- init_hash_browser_esm();
- init_fileScope();
- });
-
- // ../../packages/css/src/vars.ts
- function createVar(debugId) {
- const refCount = getAndIncrementRefCounter();
- const varName = process.env.NODE_ENV !== "production" && debugId ? `${debugId}__${hash_browser_esm_default(getFileScope())}${refCount}` : `${hash_browser_esm_default(getFileScope())}${refCount}`;
- const cssVarName = (0, import_cssesc3.default)(varName.match(/^[0-9]/) ? `_${varName}` : varName, {
- isIdentifier: true
- }).replace(/([A-Z])/g, "-$1").toLowerCase();
- return `var(--${cssVarName})`;
- }
- function fallbackVar(...values) {
- let finalValue = "";
- values.reverse().forEach((value) => {
- if (finalValue === "") {
- finalValue = String(value);
- } else {
- if (typeof value !== "string" || !/^var\(--.*\)$/.test(value)) {
- throw new Error(`Invalid variable name: ${value}`);
- }
- finalValue = value.replace(/\)$/, `, ${finalValue})`);
- }
- });
- return finalValue;
- }
- function assignVars(varContract, tokens) {
- const varSetters = {};
- walkObject(tokens, (value, path) => {
- varSetters[get(varContract, path)] = String(value);
- });
- return varSetters;
- }
- function createThemeVars(themeContract) {
- return walkObject(themeContract, (_value, path) => {
- return createVar(path.join("-"));
- });
- }
- var import_cssesc3;
- var init_vars = __esm(() => {
- init_hash_browser_esm();
- import_cssesc3 = __toModule(require_cssesc());
- init_fileScope();
- init_utils();
- });
-
- // ../../packages/css/src/theme.ts
- function createGlobalTheme(selector, arg2, arg3) {
- const shouldCreateVars = Boolean(!arg3);
- const themeVars = shouldCreateVars ? createThemeVars(arg2) : arg2;
- const tokens = shouldCreateVars ? arg2 : arg3;
- appendCss({
- type: "global",
- selector,
- rule: {vars: assignVars(themeVars, tokens)}
- }, getFileScope());
- if (shouldCreateVars) {
- return themeVars;
- }
- }
- function createTheme(arg1, arg2, arg3) {
- const themeClassName = generateIdentifier(typeof arg2 === "object" ? arg3 : arg2);
- registerClassName(themeClassName);
- const vars2 = typeof arg2 === "object" ? createGlobalTheme(themeClassName, arg1, arg2) : createGlobalTheme(themeClassName, arg1);
- return vars2 ? [themeClassName, vars2] : themeClassName;
- }
- var init_theme = __esm(() => {
- init_adapter();
- init_fileScope();
- init_identifier();
- init_vars();
- });
-
- // ../../packages/css/src/style.ts
- function style(rule, debugId) {
- const className = generateIdentifier(debugId);
- registerClassName(className);
- appendCss({type: "local", selector: className, rule}, getFileScope());
- return className;
- }
- function globalStyle(selector, rule) {
- appendCss({type: "global", selector, rule}, getFileScope());
- }
- function fontFace(rule, debugId) {
- const fontFamily = `"${(0, import_cssesc4.default)(generateIdentifier(debugId), {
- quotes: "double"
- })}"`;
- if ("fontFamily" in rule) {
- throw new Error(import_dedent2.default`
- This function creates and returns a hashed font-family name, so the "fontFamily" property should not be provided.
-
- If you'd like to define a globally scoped custom font, you can use the "globalFontFace" function instead.
- `);
- }
- appendCss({type: "fontFace", rule: {...rule, fontFamily}}, getFileScope());
- return fontFamily;
- }
- function globalFontFace(fontFamily, rule) {
- appendCss({type: "fontFace", rule: {...rule, fontFamily}}, getFileScope());
- }
- function keyframes(rule, debugId) {
- const name = (0, import_cssesc4.default)(generateIdentifier(debugId), {
- isIdentifier: true
- });
- appendCss({type: "keyframes", name, rule}, getFileScope());
- return name;
- }
- function globalKeyframes(name, rule) {
- appendCss({type: "keyframes", name, rule}, getFileScope());
- }
- function mapToStyles(...args) {
- if (typeof args[1] === "function") {
- const data = args[0];
- const mapData = args[1];
- const debugId2 = args[2];
- const classMap2 = {};
- for (const key in data) {
- classMap2[key] = style(mapData(data[key], key), debugId2 ? `${debugId2}_${key}` : key);
- }
- return classMap2;
- }
- const styleMap = args[0];
- const debugId = args[1];
- const classMap = {};
- for (const key in styleMap) {
- classMap[key] = style(styleMap[key], debugId ? `${debugId}_${key}` : key);
- }
- return classMap;
- }
- var import_cssesc4, import_dedent2;
- var init_style = __esm(() => {
- import_cssesc4 = __toModule(require_cssesc());
- import_dedent2 = __toModule(require_dedent());
- init_adapter();
- init_fileScope();
- init_identifier();
- });
-
- // ../../packages/css/src/index.ts
- var init_src = __esm(() => {
- init_runtimeAdapter();
- init_identifier();
- init_theme();
- init_style();
- init_vars();
- });
-
- // src/themes.css.ts
- var theme, vars, altTheme, responsiveTheme;
- var init_themes_css = __esm(() => {
- init_src();
- theme = style({});
- vars = createGlobalTheme(`:root, ${theme}`, {
- colors: {
- backgroundColor: "blue",
- text: "white"
- },
- space: {
- 1: "4px",
- 2: "8px",
- 3: "12px"
- }
- });
- altTheme = createTheme(vars, {
- colors: {
- backgroundColor: "green",
- text: "white"
- },
- space: {
- 1: "8px",
- 2: "12px",
- 3: "16px"
- }
- });
- responsiveTheme = style({
- vars: assignVars(vars, {
- colors: {
- backgroundColor: "pink",
- text: "purple"
- },
- space: {
- 1: "6px",
- 2: "12px",
- 3: "18px"
- }
- }),
- "@media": {
- "screen and (min-width: 768px)": {
- vars: assignVars(vars.colors, {
- backgroundColor: "purple",
- text: "pink"
- })
- }
- }
- });
- });
-
- // src/shared.css.ts
- var shadow;
- var init_shared_css = __esm(() => {
- init_src();
- shadow = style({
- boxShadow: "0 0 5px red"
- });
- globalStyle("body", {
- backgroundColor: "skyblue"
- });
- });
-
- // src/styles.css.ts
- var impact, slide, container, button, undefinedVar1, undefinedVar2, opacity;
- var init_styles_css = __esm(() => {
- init_src();
- init_shared_css();
- init_themes_css();
- impact = fontFace({
- src: 'local("Impact")'
- });
- globalFontFace("MyGlobalComicSans", {
- src: 'local("Comic Sans MS")'
- });
- slide = keyframes({
- "0%": {
- transform: "translateY(-4px)"
- },
- "100%": {
- transform: "translateY(4px)"
- }
- });
- globalKeyframes("globalSlide", {
- "0%": {
- transform: "translateY(-4px)"
- },
- "100%": {
- transform: "translateY(4px)"
- }
- });
- container = style({
- animation: `3s infinite alternate globalSlide ease-in-out`,
- display: "flex",
- flexDirection: "column",
- gap: vars.space[2],
- padding: vars.space[3],
- "@media": {
- "only screen and (min-width: 500px)": {
- border: `1px solid ${vars.colors.backgroundColor}`
- }
- }
- });
- button = [
- style({
- animation: `3s infinite alternate ${slide} ease-in-out`,
- fontFamily: impact,
- backgroundColor: fallbackVar(vars.colors.backgroundColor, '"THIS FALLBACK VALUE SHOULD NEVER BE USED"'),
- color: vars.colors.text,
- "@media": {
- "only screen and (min-width: 500px)": {
- borderRadius: "9999px"
- }
- },
- selectors: {
- [`${altTheme} ${theme} ${container} &`]: {
- fontFamily: "MyGlobalComicSans",
- outline: "5px solid red"
- }
- }
- }),
- shadow
- ];
- undefinedVar1 = createVar();
- undefinedVar2 = createVar();
- opacity = mapToStyles({
- "1/2": fallbackVar(undefinedVar1, "0.5"),
- "1/4": fallbackVar(undefinedVar1, undefinedVar2, "0.25")
- }, (value) => ({opacity: value}));
- });
-
- // test-nodes.json
- var root, rootContainer, rootButton, altContainer, altButton, nestedRootContainer, nestedRootButton, inlineThemeContainer, inlineThemeButton, responsiveThemeContainer, responsiveThemeButton, test_nodes_default;
- var init_test_nodes = __esm(() => {
- root = "root";
- rootContainer = "rootContainer";
- rootButton = "rootButton";
- altContainer = "altContainer";
- altButton = "altButton";
- nestedRootContainer = "nestedRootContainer";
- nestedRootButton = "nestedRootButton";
- inlineThemeContainer = "inlineThemeContainer";
- inlineThemeButton = "inlineThemeButton";
- responsiveThemeContainer = "responsiveThemeContainer";
- responsiveThemeButton = "responsiveThemeButton";
- test_nodes_default = {
- root,
- rootContainer,
- rootButton,
- altContainer,
- altButton,
- nestedRootContainer,
- nestedRootButton,
- inlineThemeContainer,
- inlineThemeButton,
- responsiveThemeContainer,
- responsiveThemeButton
- };
- });
-
- // src/index.ts
- var require_src = __commonJS((exports, module) => {
- init_createInlineTheme();
- init_themes_css();
- init_styles_css();
- init_shared_css();
- init_test_nodes();
- var inlineTheme = createInlineTheme(vars, {
- colors: {
- backgroundColor: "orange",
- text: "black"
- },
- space: {
- 1: "4px",
- 2: "8px",
- 3: "12px"
- }
- });
- function render() {
- document.body.innerHTML = `
-
- Root theme
-
-
-
- Alt theme
-
-
-
- Back to root theme
-
-
-
- Inline theme
-
-
-
- Responsive theme
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
- }
- render();
- if (module.hot) {
- module.hot.accept(["./shared.css", "./styles.css", "./themes.css"], () => {
- render();
- });
- }
- });
- require_src();
-})();
diff --git a/packages/esbuild-plugin/src/index.ts b/packages/esbuild-plugin/src/index.ts
index ae3557866..8498eeb38 100644
--- a/packages/esbuild-plugin/src/index.ts
+++ b/packages/esbuild-plugin/src/index.ts
@@ -1,4 +1,4 @@
-import { join, relative } from 'path';
+import { dirname } from 'path';
import { promises as fs } from 'fs';
import type { Adapter } from '@vanilla-extract/css';
@@ -11,34 +11,28 @@ import evalCode from 'eval';
import { stringify } from 'javascript-stringify';
import isPlainObject from 'lodash/isPlainObject';
-const vanillaNamespace = 'vanilla-extract-ns';
const vanillaCssNamespace = 'vanilla-extract-css-ns';
const vanillaExtractFilescopePlugin: Plugin = {
name: 'vanilla-extract-filescope',
setup(build) {
- build.onResolve({ filter: /\.css\.(js|jsx|ts|tsx)$/ }, (args) => ({
- path: args.path,
- namespace: vanillaNamespace,
- }));
+ build.onLoad({ filter: /\.css\.(js|jsx|ts|tsx)$/ }, async ({ path }) => {
+ console.log('Loading child filescope', path);
- build.onLoad(
- { filter: /.*/, namespace: vanillaNamespace },
- async ({ path }) => {
- const originalSource = await fs.readFile(path, 'utf-8');
+ const originalSource = await fs.readFile(path, 'utf-8');
- const contents = `
+ const contents = `
import { setFileScope, endFileScope } from "@vanilla-extract/css/fileScope";
setFileScope("${path}");
${originalSource}
endFileScope()
`;
- return {
- contents,
- };
- },
- );
+ return {
+ contents,
+ resolveDir: dirname(path),
+ };
+ });
},
};
@@ -46,7 +40,7 @@ export function vanillaExtractPlugin(): Plugin {
return {
name: 'vanilla-extract',
setup(build) {
- build.onResolve({ filter: /vanilla\.css?source=.*$/ }, (args) => ({
+ build.onResolve({ filter: /vanilla\.css\?source=.*$/ }, (args) => ({
path: args.path,
namespace: vanillaCssNamespace,
}));
@@ -54,22 +48,20 @@ export function vanillaExtractPlugin(): Plugin {
build.onLoad(
{ filter: /.*/, namespace: vanillaCssNamespace },
({ path }) => {
- const url = new URL(path);
- const sourceBase64 = url.searchParams.get('source');
+ const [, source] = path.match(/\?source=(.*)$/) ?? [];
- if (!sourceBase64) {
+ if (!source) {
throw new Error('No source in vanilla CSS file');
}
return {
- content: Buffer.from(sourceBase64, 'base64').toString('utf-8'),
+ contents: Buffer.from(source, 'base64').toString('utf-8'),
loader: 'css',
};
},
);
build.onLoad({ filter: /\.css\.(js|jsx|ts|tsx)$/ }, async ({ path }) => {
- console.log('Found', path);
const result = await esbuild({
entryPoints: [path],
metafile: true,
@@ -78,11 +70,12 @@ export function vanillaExtractPlugin(): Plugin {
platform: 'node',
write: false,
plugins: [vanillaExtractFilescopePlugin],
+ treeShaking: 'ignore-annotations',
});
const { outputFiles } = result;
- if (outputFiles.length !== 1) {
+ if (!outputFiles || outputFiles.length !== 1) {
throw new Error('Invalid child compilation');
}
@@ -106,7 +99,14 @@ export function vanillaExtractPlugin(): Plugin {
setAdapter(cssAdapter);
- const evalResult = evalCode(outputFiles[0], path, { console }, true);
+ const sourceWithBoundLoaderInstance = `require('@vanilla-extract/css/adapter').setAdapter(__adapter__);${outputFiles[0].text}`;
+
+ const evalResult = evalCode(
+ sourceWithBoundLoaderInstance,
+ path,
+ { console, __adapter__: cssAdapter },
+ true,
+ );
const cssRequests = [];
@@ -117,19 +117,11 @@ export function vanillaExtractPlugin(): Plugin {
}).join('\n');
const base64Css = Buffer.from(css, 'utf-8').toString('base64');
- const absoluteFileScope = join(
- build.initialOptions.sourceRoot ?? '',
- fileScope,
- );
- const request = relative(path, absoluteFileScope);
-
- cssRequests.push(`${request}.vanilla.css?source=${base64Css}`);
+ cssRequests.push(`${fileScope}.vanilla.css?source=${base64Css}`);
}
const contents = serializeVanillaModule(cssRequests, evalResult);
- console.log(contents);
-
return {
contents,
loader: 'js',
diff --git a/test-helpers/package.json b/test-helpers/package.json
index 8b21dab17..eeaaeaf1e 100644
--- a/test-helpers/package.json
+++ b/test-helpers/package.json
@@ -18,12 +18,14 @@
"minimist": "^1.2.5",
"path-browserify": "^1.0.1",
"portfinder": "^1.0.28",
+ "serve-handler": "^6.1.3",
"style-loader": "^2.0.0",
"webpack": "^5.27.1",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.7.3"
},
"devDependencies": {
- "@types/minimist": "^1"
+ "@types/minimist": "^1",
+ "@types/serve-handler": "^6"
}
}
diff --git a/test-helpers/src/startFixture/esbuild.ts b/test-helpers/src/startFixture/esbuild.ts
new file mode 100644
index 000000000..d68c456ca
--- /dev/null
+++ b/test-helpers/src/startFixture/esbuild.ts
@@ -0,0 +1,94 @@
+import path from 'path';
+import { promises as fs } from 'fs';
+
+import { vanillaExtractPlugin } from '@vanilla-extract/esbuild-plugin';
+import { build } from 'esbuild';
+import handler from 'serve-handler';
+import http from 'http';
+
+import { TestServer } from './types';
+
+export interface EsbuildFixtureOptions {
+ type: 'esbuild';
+ mode?: 'development' | 'production';
+ port?: number;
+}
+export const startEsbuildFixture = async (
+ fixtureName: string,
+ { mode = 'development', port = 3000 }: EsbuildFixtureOptions = {
+ type: 'esbuild',
+ },
+): Promise => {
+ const entry = require.resolve(`@fixtures/${fixtureName}`);
+ const outdir = path.join(
+ path.dirname(require.resolve(`@fixtures/${fixtureName}/package.json`)),
+ 'dist',
+ );
+
+ const result = await build({
+ entryPoints: [entry],
+ platform: 'browser',
+ bundle: true,
+ minify: mode === 'production',
+ plugins: [vanillaExtractPlugin()],
+ outdir,
+ watch: true,
+ });
+
+ const scripts = [];
+ const stylesheets = [];
+
+ for (const file of result.outputFiles || []) {
+ if (file.path.endsWith('.css')) {
+ stylesheets.push(
+ ``,
+ );
+ } else if (file.path.endsWith('.js')) {
+ scripts.push(``);
+ } else {
+ console.warn('Unsupported output file:', file.path);
+ }
+ }
+
+ await fs.writeFile(
+ path.join(outdir, 'index.html'),
+ `
+
+
+
+
+ esbuild - dicture
+ ${stylesheets.join('\n')}
+
+
+ ${scripts.join('\n')}
+
+
+ `,
+ );
+
+ const server = http.createServer((request, response) => {
+ return handler(request, response, { public: outdir });
+ });
+
+ const url = `http://localhost:${port}`;
+
+ server.listen(port, () => {
+ console.log(`Running at ${url}`);
+ });
+
+ return {
+ type: 'esbuild',
+ url,
+ close: () =>
+ new Promise((resolve) => {
+ if (result.stop) {
+ result.stop();
+ }
+
+ server.close(() => {
+ resolve();
+ });
+ }),
+ };
+};
diff --git a/test-helpers/src/startFixture/index.ts b/test-helpers/src/startFixture/index.ts
new file mode 100644
index 000000000..b1943be8c
--- /dev/null
+++ b/test-helpers/src/startFixture/index.ts
@@ -0,0 +1,22 @@
+import { startWebpackFixture, WebpackFixtureOptions } from './webpack';
+import { startEsbuildFixture, EsbuildFixtureOptions } from './esbuild';
+
+type StyleType = 'browser' | 'mini-css-extract' | 'style-loader' | 'esbuild';
+
+export interface TestServer {
+ type: StyleType;
+ url: string;
+ close: () => Promise;
+}
+
+type FixtureOptions = EsbuildFixtureOptions | WebpackFixtureOptions;
+export async function startFixture(
+ fixtureName: string,
+ options: FixtureOptions,
+): Promise {
+ if (options.type === 'esbuild') {
+ return startEsbuildFixture(fixtureName, options);
+ }
+
+ return startWebpackFixture(fixtureName, options);
+}
diff --git a/test-helpers/src/startFixture/types.ts b/test-helpers/src/startFixture/types.ts
new file mode 100644
index 000000000..8f25eb724
--- /dev/null
+++ b/test-helpers/src/startFixture/types.ts
@@ -0,0 +1,11 @@
+export type BuildType =
+ | 'browser'
+ | 'mini-css-extract'
+ | 'style-loader'
+ | 'esbuild';
+
+export interface TestServer {
+ type: BuildType;
+ url: string;
+ close: () => Promise;
+}
diff --git a/test-helpers/src/startFixture.ts b/test-helpers/src/startFixture/webpack.ts
similarity index 90%
rename from test-helpers/src/startFixture.ts
rename to test-helpers/src/startFixture/webpack.ts
index 2af5a06de..b4326c927 100644
--- a/test-helpers/src/startFixture.ts
+++ b/test-helpers/src/startFixture/webpack.ts
@@ -6,7 +6,8 @@ import webpackMerge from 'webpack-merge';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
-import { stylesheetName } from './getStylesheet';
+import { stylesheetName } from '../getStylesheet';
+import { TestServer } from './types';
export const getTestNodes = (fixture: string) =>
require(`@fixtures/${fixture}/test-nodes.json`);
@@ -52,22 +53,14 @@ const defaultWebpackConfig: Configuration = {
],
};
-type StyleType = 'browser' | 'mini-css-extract' | 'style-loader';
-
-export interface TestServer {
- type: StyleType;
- url: string;
- close: () => Promise;
-}
-
-export interface FixtureOptions {
- type?: StyleType;
+export interface WebpackFixtureOptions {
+ type?: 'browser' | 'mini-css-extract' | 'style-loader';
hot?: boolean;
mode?: 'development' | 'production';
basePort?: number;
logLevel?: Configuration['stats'];
}
-export const startFixture = (
+export const startWebpackFixture = (
fixtureName: string,
{
type = 'mini-css-extract',
@@ -75,7 +68,7 @@ export const startFixture = (
mode = 'development',
basePort,
logLevel = 'errors-only',
- }: FixtureOptions = {},
+ }: WebpackFixtureOptions = {},
): Promise =>
new Promise(async (resolve) => {
console.log(
diff --git a/yarn.lock b/yarn.lock
index 629904f2c..e7c06348c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2556,6 +2556,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/serve-handler@npm:^6":
+ version: 6.1.0
+ resolution: "@types/serve-handler@npm:6.1.0"
+ dependencies:
+ "@types/node": "*"
+ checksum: f62ce46967a126038e32e88fa97bab108b346a76ad5be14725594b34efddf175bbcf596815535f192390d974c2e415641b896aee1becfa0b07961d3faaf85d36
+ languageName: node
+ linkType: hard
+
"@types/serve-static@npm:*":
version: 1.13.9
resolution: "@types/serve-static@npm:1.13.9"
@@ -4226,6 +4235,13 @@ __metadata:
languageName: node
linkType: hard
+"content-disposition@npm:0.5.2":
+ version: 0.5.2
+ resolution: "content-disposition@npm:0.5.2"
+ checksum: 5d54ba7c9a6e865d1fea321e43d9e56be091aa20706f4632a236ebe7824ed3cb0eac314b80e76a9db2092d287d69add03efcaf743068ee0be1f71159c14a134c
+ languageName: node
+ linkType: hard
+
"content-disposition@npm:0.5.3":
version: 0.5.3
resolution: "content-disposition@npm:0.5.3"
@@ -5533,6 +5549,15 @@ __metadata:
languageName: node
linkType: hard
+"fast-url-parser@npm:1.1.3":
+ version: 1.1.3
+ resolution: "fast-url-parser@npm:1.1.3"
+ dependencies:
+ punycode: ^1.3.2
+ checksum: 8dbc306b736e32963fe4391a581401c422d826497ce5cacf6e7c60525febfbcea477fbc5b012fe3316f6634a20fa00882168c5ed792ff3ef904c5bc6a11a598d
+ languageName: node
+ linkType: hard
+
"fastq@npm:^1.6.0":
version: 1.11.0
resolution: "fastq@npm:1.11.0"
@@ -8301,6 +8326,22 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
+"mime-db@npm:~1.33.0":
+ version: 1.33.0
+ resolution: "mime-db@npm:1.33.0"
+ checksum: f33acedd5b2bfd57fe987aa01c209abd3c6f762c6746c2a1ffefa77f8c10d39a2af9a591bd44f39f8d42a5ee30e43407cfd8535392773f211c2c7d7b6def90d4
+ languageName: node
+ linkType: hard
+
+"mime-types@npm:2.1.18":
+ version: 2.1.18
+ resolution: "mime-types@npm:2.1.18"
+ dependencies:
+ mime-db: ~1.33.0
+ checksum: f1e2fed4f9d04a0d158c48b42f8ac5f1a655b27399674f7bd9f16e6784221ec4c2d30b20f24174f741ee6aa2556170f63b3ec9f51cb4e99e0a04c56799c8317c
+ languageName: node
+ linkType: hard
+
"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:~2.1.17, mime-types@npm:~2.1.19, mime-types@npm:~2.1.24":
version: 2.1.29
resolution: "mime-types@npm:2.1.29"
@@ -8376,7 +8417,7 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
-"minimatch@npm:^3.0.4":
+"minimatch@npm:3.0.4, minimatch@npm:^3.0.4":
version: 3.0.4
resolution: "minimatch@npm:3.0.4"
dependencies:
@@ -9195,7 +9236,7 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
-"path-is-inside@npm:^1.0.2":
+"path-is-inside@npm:1.0.2, path-is-inside@npm:^1.0.2":
version: 1.0.2
resolution: "path-is-inside@npm:1.0.2"
checksum: 9c1841199d18398ee5f6d79f57eaa57f8eb85743353ea97c6d933423f246f044575a10c1847c638c36440b050aef82665b9cb4fc60950866cd239f3d51835ef4
@@ -9230,6 +9271,13 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
+"path-to-regexp@npm:2.2.1":
+ version: 2.2.1
+ resolution: "path-to-regexp@npm:2.2.1"
+ checksum: 1f9be3a4100c23f845892406bcdfcf79d62044ce24c1c50dca28719123ce7d338ac584e98d21d23eef2702754925511812e768523e59916777ec1f444438d9a4
+ languageName: node
+ linkType: hard
+
"path-type@npm:^3.0.0":
version: 3.0.0
resolution: "path-type@npm:3.0.0"
@@ -9568,6 +9616,13 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
+"punycode@npm:^1.3.2":
+ version: 1.4.1
+ resolution: "punycode@npm:1.4.1"
+ checksum: 5ce1e044cee2b12f1c65ccd523d7e71d6578f2c77f5c21c2e7a9d588535559c9508571d42638c131dab93cbe9a7b37bce1a7475d43fc8236c99dfe1efc36cfa5
+ languageName: node
+ linkType: hard
+
"punycode@npm:^2.1.0, punycode@npm:^2.1.1":
version: 2.1.1
resolution: "punycode@npm:2.1.1"
@@ -9653,6 +9708,13 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
+"range-parser@npm:1.2.0":
+ version: 1.2.0
+ resolution: "range-parser@npm:1.2.0"
+ checksum: 8260023192a5def4c6db4ced82e6546306937f1202417b846f2e8b565426e71697086f509a070f66fd23a57e9f96aba108f08d16d4be23d418c8c68a73b539bd
+ languageName: node
+ linkType: hard
+
"range-parser@npm:^1.2.1, range-parser@npm:~1.2.1":
version: 1.2.1
resolution: "range-parser@npm:1.2.1"
@@ -10357,6 +10419,22 @@ fsevents@^1.2.7:
languageName: node
linkType: hard
+"serve-handler@npm:^6.1.3":
+ version: 6.1.3
+ resolution: "serve-handler@npm:6.1.3"
+ dependencies:
+ bytes: 3.0.0
+ content-disposition: 0.5.2
+ fast-url-parser: 1.1.3
+ mime-types: 2.1.18
+ minimatch: 3.0.4
+ path-is-inside: 1.0.2
+ path-to-regexp: 2.2.1
+ range-parser: 1.2.0
+ checksum: 493e7556ec53bc6c8616ffc58697d93c5ebc8ddeb38de39b5381140a8467bb720fbbd58fbe91de25ea9ccc98ce8b11131ccd7e160ddf891ca5199e7f1437cc18
+ languageName: node
+ linkType: hard
+
"serve-index@npm:^1.9.1":
version: 1.9.1
resolution: "serve-index@npm:1.9.1"
@@ -11157,6 +11235,7 @@ fsevents@^1.2.7:
"@babel/core": ^7.13.10
"@types/mini-css-extract-plugin": ^1.2.2
"@types/minimist": ^1
+ "@types/serve-handler": ^6
"@types/webpack-dev-server": ^3.11.1
babel-loader: ^8.2.2
css-loader: ^5.1.3
@@ -11166,6 +11245,7 @@ fsevents@^1.2.7:
minimist: ^1.2.5
path-browserify: ^1.0.1
portfinder: ^1.0.28
+ serve-handler: ^6.1.3
style-loader: ^2.0.0
webpack: ^5.27.1
webpack-dev-server: ^3.11.2
From 9cdc27d51ed3f431736165a653ff4e292e346147 Mon Sep 17 00:00:00 2001
From: Matt Jones
Date: Thu, 1 Apr 2021 10:40:53 +1100
Subject: [PATCH 04/19] Esbuild start fixture working
---
packages/esbuild-plugin/src/index.ts | 2 -
test-helpers/src/index.ts | 3 +
test-helpers/src/startFixture/esbuild.ts | 111 +++---
tests/E2E/__snapshots__/styles.test.ts.snap | 372 ++++++++++++++++++++
tests/E2E/styles.test.ts | 7 +-
5 files changed, 438 insertions(+), 57 deletions(-)
diff --git a/packages/esbuild-plugin/src/index.ts b/packages/esbuild-plugin/src/index.ts
index 8498eeb38..85650b978 100644
--- a/packages/esbuild-plugin/src/index.ts
+++ b/packages/esbuild-plugin/src/index.ts
@@ -17,8 +17,6 @@ const vanillaExtractFilescopePlugin: Plugin = {
name: 'vanilla-extract-filescope',
setup(build) {
build.onLoad({ filter: /\.css\.(js|jsx|ts|tsx)$/ }, async ({ path }) => {
- console.log('Loading child filescope', path);
-
const originalSource = await fs.readFile(path, 'utf-8');
const contents = `
diff --git a/test-helpers/src/index.ts b/test-helpers/src/index.ts
index 3a22a6dae..728badb65 100644
--- a/test-helpers/src/index.ts
+++ b/test-helpers/src/index.ts
@@ -1,3 +1,6 @@
export * from './startFixture';
export * from './getNodeStyles';
export * from './getStylesheet';
+
+export const getTestNodes = (fixture: string) =>
+ require(`@fixtures/${fixture}/test-nodes.json`);
diff --git a/test-helpers/src/startFixture/esbuild.ts b/test-helpers/src/startFixture/esbuild.ts
index d68c456ca..7435aa0d3 100644
--- a/test-helpers/src/startFixture/esbuild.ts
+++ b/test-helpers/src/startFixture/esbuild.ts
@@ -18,46 +18,51 @@ export const startEsbuildFixture = async (
{ mode = 'development', port = 3000 }: EsbuildFixtureOptions = {
type: 'esbuild',
},
-): Promise => {
- const entry = require.resolve(`@fixtures/${fixtureName}`);
- const outdir = path.join(
- path.dirname(require.resolve(`@fixtures/${fixtureName}/package.json`)),
- 'dist',
- );
+): Promise =>
+ new Promise(async (resolve) => {
+ const entry = require.resolve(`@fixtures/${fixtureName}`);
+ const outdir = path.join(
+ path.dirname(require.resolve(`@fixtures/${fixtureName}/package.json`)),
+ 'dist',
+ );
- const result = await build({
- entryPoints: [entry],
- platform: 'browser',
- bundle: true,
- minify: mode === 'production',
- plugins: [vanillaExtractPlugin()],
- outdir,
- watch: true,
- });
+ const result = await build({
+ entryPoints: [entry],
+ metafile: true,
+ platform: 'browser',
+ bundle: true,
+ minify: mode === 'production',
+ plugins: [vanillaExtractPlugin()],
+ outdir,
+ write: true,
+ watch: true,
+ });
+
+ const scripts = [];
+ const stylesheets = [];
- const scripts = [];
- const stylesheets = [];
+ for (const filePath of Object.keys(result.metafile?.outputs || {})) {
+ const relativeFilePath = path.relative(outdir, filePath);
- for (const file of result.outputFiles || []) {
- if (file.path.endsWith('.css')) {
- stylesheets.push(
- ``,
- );
- } else if (file.path.endsWith('.js')) {
- scripts.push(``);
- } else {
- console.warn('Unsupported output file:', file.path);
+ if (relativeFilePath.endsWith('.css')) {
+ stylesheets.push(
+ ``,
+ );
+ } else if (relativeFilePath.endsWith('.js')) {
+ scripts.push(``);
+ } else {
+ console.warn('Unsupported output file:', relativeFilePath);
+ }
}
- }
- await fs.writeFile(
- path.join(outdir, 'index.html'),
- `
+ await fs.writeFile(
+ path.join(outdir, 'index.html'),
+ `
- esbuild - dicture
+ esbuild - ${fixtureName}
${stylesheets.join('\n')}
@@ -65,30 +70,28 @@ export const startEsbuildFixture = async (
`,
- );
+ );
- const server = http.createServer((request, response) => {
- return handler(request, response, { public: outdir });
- });
+ const server = http.createServer((request, response) => {
+ return handler(request, response, { public: outdir });
+ });
- const url = `http://localhost:${port}`;
+ const url = `http://localhost:${port}`;
- server.listen(port, () => {
- console.log(`Running at ${url}`);
- });
+ server.listen(port, () => {
+ resolve({
+ type: 'esbuild',
+ url,
+ close: () =>
+ new Promise((resolve) => {
+ if (result.stop) {
+ result.stop();
+ }
- return {
- type: 'esbuild',
- url,
- close: () =>
- new Promise((resolve) => {
- if (result.stop) {
- result.stop();
- }
-
- server.close(() => {
- resolve();
- });
- }),
- };
-};
+ server.close(() => {
+ resolve();
+ });
+ }),
+ });
+ });
+ });
diff --git a/tests/E2E/__snapshots__/styles.test.ts.snap b/tests/E2E/__snapshots__/styles.test.ts.snap
index 5c3a571b5..e6d352244 100644
--- a/tests/E2E/__snapshots__/styles.test.ts.snap
+++ b/tests/E2E/__snapshots__/styles.test.ts.snap
@@ -372,6 +372,378 @@ Object {
}
`;
+exports[`Styling and specificity Themed esbuild on desktop all builds should match 1`] = `
+Object {
+ "altButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "_11tj6k30",
+ "background-color" => "rgb(0, 128, 0)",
+ "color" => "rgb(255, 255, 255)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ "border-radius" => "9999px",
+ "border-top-left-radius" => "9999px",
+ "border-top-right-radius" => "9999px",
+ "border-bottom-right-radius" => "9999px",
+ "border-bottom-left-radius" => "9999px",
+ },
+ "altContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ "border" => "1px solid var(--colors-background-color__19vzfq81)",
+ },
+ "inlineThemeButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "MyGlobalComicSans",
+ "background-color" => "rgb(255, 165, 0)",
+ "color" => "rgb(0, 0, 0)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ "opacity" => "0.5",
+ "border-radius" => "9999px",
+ "border-top-left-radius" => "9999px",
+ "border-top-right-radius" => "9999px",
+ "border-bottom-right-radius" => "9999px",
+ "border-bottom-left-radius" => "9999px",
+ "outline" => "5px solid red",
+ "outline-color" => "rgb(255, 0, 0)",
+ "outline-style" => "solid",
+ "outline-width" => "5px",
+ },
+ "inlineThemeContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ "border" => "1px solid var(--colors-background-color__19vzfq81)",
+ },
+ "nestedRootButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "MyGlobalComicSans",
+ "background-color" => "rgb(0, 0, 255)",
+ "color" => "rgb(255, 255, 255)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ "border-radius" => "9999px",
+ "border-top-left-radius" => "9999px",
+ "border-top-right-radius" => "9999px",
+ "border-bottom-right-radius" => "9999px",
+ "border-bottom-left-radius" => "9999px",
+ "outline" => "5px solid red",
+ "outline-color" => "rgb(255, 0, 0)",
+ "outline-style" => "solid",
+ "outline-width" => "5px",
+ },
+ "nestedRootContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ "border" => "1px solid var(--colors-background-color__19vzfq81)",
+ },
+ "responsiveThemeButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "MyGlobalComicSans",
+ "background-color" => "rgb(128, 0, 128)",
+ "color" => "rgb(255, 192, 203)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ "border-radius" => "9999px",
+ "border-top-left-radius" => "9999px",
+ "border-top-right-radius" => "9999px",
+ "border-bottom-right-radius" => "9999px",
+ "border-bottom-left-radius" => "9999px",
+ "outline" => "5px solid red",
+ "outline-color" => "rgb(255, 0, 0)",
+ "outline-style" => "solid",
+ "outline-width" => "5px",
+ },
+ "responsiveThemeContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ "border" => "1px solid var(--colors-background-color__19vzfq81)",
+ },
+ "root": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ },
+ "rootButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "_11tj6k30",
+ "background-color" => "rgb(0, 0, 255)",
+ "color" => "rgb(255, 255, 255)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ "border-radius" => "9999px",
+ "border-top-left-radius" => "9999px",
+ "border-top-right-radius" => "9999px",
+ "border-bottom-right-radius" => "9999px",
+ "border-bottom-left-radius" => "9999px",
+ },
+ "rootContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ "border" => "1px solid var(--colors-background-color__19vzfq81)",
+ },
+}
+`;
+
+exports[`Styling and specificity Themed esbuild on mobile all builds should match 1`] = `
+Object {
+ "altButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "_11tj6k30",
+ "background-color" => "rgb(0, 128, 0)",
+ "color" => "rgb(255, 255, 255)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ },
+ "altContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ },
+ "inlineThemeButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "MyGlobalComicSans",
+ "background-color" => "rgb(255, 165, 0)",
+ "color" => "rgb(0, 0, 0)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ "opacity" => "0.5",
+ "outline" => "5px solid red",
+ "outline-color" => "rgb(255, 0, 0)",
+ "outline-style" => "solid",
+ "outline-width" => "5px",
+ },
+ "inlineThemeContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ },
+ "nestedRootButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "MyGlobalComicSans",
+ "background-color" => "rgb(0, 0, 255)",
+ "color" => "rgb(255, 255, 255)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ "outline" => "5px solid red",
+ "outline-color" => "rgb(255, 0, 0)",
+ "outline-style" => "solid",
+ "outline-width" => "5px",
+ },
+ "nestedRootContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ },
+ "responsiveThemeButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "MyGlobalComicSans",
+ "background-color" => "rgb(255, 192, 203)",
+ "color" => "rgb(128, 0, 128)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ "outline" => "5px solid red",
+ "outline-color" => "rgb(255, 0, 0)",
+ "outline-style" => "solid",
+ "outline-width" => "5px",
+ },
+ "responsiveThemeContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ },
+ "root": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ },
+ "rootButton": Map {
+ "box-shadow" => "rgb(255, 0, 0) 0px 0px 5px 0px",
+ "animation" => "3s infinite alternate _11tj6k31 ease-in-out",
+ "font-family" => "_11tj6k30",
+ "background-color" => "rgb(0, 0, 255)",
+ "color" => "rgb(255, 255, 255)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "_11tj6k31",
+ },
+ "rootContainer": Map {
+ "animation" => "3s infinite alternate globalSlide ease-in-out",
+ "display" => "flex",
+ "flex-direction" => "column",
+ "gap" => "var(--space-2__19vzfq84)",
+ "padding" => "var(--space-3__19vzfq85)",
+ "animation-duration" => "3s",
+ "animation-timing-function" => "ease-in-out",
+ "animation-delay" => "0s",
+ "animation-iteration-count" => "infinite",
+ "animation-direction" => "alternate",
+ "animation-fill-mode" => "none",
+ "animation-play-state" => "running",
+ "animation-name" => "globalSlide",
+ },
+}
+`;
+
exports[`Styling and specificity Themed mini-css-extract on desktop all builds should match 1`] = `
Object {
"altButton": Map {
diff --git a/tests/E2E/styles.test.ts b/tests/E2E/styles.test.ts
index 231fc3a6c..a6eb7d4d6 100644
--- a/tests/E2E/styles.test.ts
+++ b/tests/E2E/styles.test.ts
@@ -6,7 +6,12 @@ import {
} from 'test-helpers';
import { Viewport } from 'puppeteer';
-const compileTypes = ['browser', 'mini-css-extract', 'style-loader'] as const;
+const compileTypes = [
+ 'browser',
+ 'mini-css-extract',
+ 'style-loader',
+ 'esbuild',
+] as const;
async function getPageStyles(
url: string,
From 18cf29302a3885a42979fd47470b7253d1da5e8a Mon Sep 17 00:00:00 2001
From: Matt Jones
Date: Thu, 1 Apr 2021 17:18:26 +1100
Subject: [PATCH 05/19] Add stylesheet tests
---
packages/esbuild-plugin/package.json | 2 +-
packages/esbuild-plugin/src/index.ts | 14 +-
test-helpers/src/getStylesheet.ts | 2 +-
test-helpers/src/startFixture/esbuild.ts | 6 +-
test-helpers/src/startFixture/index.ts | 33 ++-
test-helpers/src/startFixture/webpack.ts | 24 +-
test-helpers/src/startFixtureCLI.ts | 2 +-
.../__snapshots__/stylesheets.test.ts.snap | 241 ++++++++++++++++++
tests/E2E/stylesheets.test.ts | 22 +-
9 files changed, 308 insertions(+), 38 deletions(-)
diff --git a/packages/esbuild-plugin/package.json b/packages/esbuild-plugin/package.json
index 64519b4db..7195fae1a 100644
--- a/packages/esbuild-plugin/package.json
+++ b/packages/esbuild-plugin/package.json
@@ -15,7 +15,7 @@
"author": "SEEK",
"license": "MIT",
"peerDependencies": {
- "esbuild": "*"
+ "esbuild": "^0.11.1"
},
"dependencies": {
"@vanilla-extract/css": "^0.1.0",
diff --git a/packages/esbuild-plugin/src/index.ts b/packages/esbuild-plugin/src/index.ts
index 85650b978..920fafbc9 100644
--- a/packages/esbuild-plugin/src/index.ts
+++ b/packages/esbuild-plugin/src/index.ts
@@ -16,20 +16,22 @@ const vanillaCssNamespace = 'vanilla-extract-css-ns';
const vanillaExtractFilescopePlugin: Plugin = {
name: 'vanilla-extract-filescope',
setup(build) {
- build.onLoad({ filter: /\.css\.(js|jsx|ts|tsx)$/ }, async ({ path }) => {
+ build.onLoad({ filter: /\.(js|jsx|ts|tsx)$/ }, async ({ path }) => {
const originalSource = await fs.readFile(path, 'utf-8');
- const contents = `
+ if (originalSource.indexOf('@vanilla-extract/css/fileScope') === -1) {
+ const contents = `
import { setFileScope, endFileScope } from "@vanilla-extract/css/fileScope";
setFileScope("${path}");
${originalSource}
endFileScope()
`;
- return {
- contents,
- resolveDir: dirname(path),
- };
+ return {
+ contents,
+ resolveDir: dirname(path),
+ };
+ }
});
},
};
diff --git a/test-helpers/src/getStylesheet.ts b/test-helpers/src/getStylesheet.ts
index 2f2f546a0..39535c3b8 100644
--- a/test-helpers/src/getStylesheet.ts
+++ b/test-helpers/src/getStylesheet.ts
@@ -2,7 +2,7 @@ import got from 'got';
export const stylesheetName = 'main.css';
-export async function getStylesheet(url: string) {
+export async function getStylesheet(url: string, stylesheetName = 'main.css') {
const response = await got(`${url}/${stylesheetName}`);
return response.body;
diff --git a/test-helpers/src/startFixture/esbuild.ts b/test-helpers/src/startFixture/esbuild.ts
index 7435aa0d3..28a8ee09b 100644
--- a/test-helpers/src/startFixture/esbuild.ts
+++ b/test-helpers/src/startFixture/esbuild.ts
@@ -11,13 +11,11 @@ import { TestServer } from './types';
export interface EsbuildFixtureOptions {
type: 'esbuild';
mode?: 'development' | 'production';
- port?: number;
+ port: number;
}
export const startEsbuildFixture = async (
fixtureName: string,
- { mode = 'development', port = 3000 }: EsbuildFixtureOptions = {
- type: 'esbuild',
- },
+ { mode = 'development', port = 3000 }: EsbuildFixtureOptions,
): Promise =>
new Promise(async (resolve) => {
const entry = require.resolve(`@fixtures/${fixtureName}`);
diff --git a/test-helpers/src/startFixture/index.ts b/test-helpers/src/startFixture/index.ts
index b1943be8c..bd04e37e1 100644
--- a/test-helpers/src/startFixture/index.ts
+++ b/test-helpers/src/startFixture/index.ts
@@ -1,3 +1,5 @@
+import portfinder from 'portfinder';
+
import { startWebpackFixture, WebpackFixtureOptions } from './webpack';
import { startEsbuildFixture, EsbuildFixtureOptions } from './esbuild';
@@ -9,14 +11,35 @@ export interface TestServer {
close: () => Promise;
}
-type FixtureOptions = EsbuildFixtureOptions | WebpackFixtureOptions;
+type SharedOptions = {
+ basePort: number;
+};
+
+type FixtureOptions = SharedOptions &
+ Omit;
export async function startFixture(
fixtureName: string,
- options: FixtureOptions,
+ { type, basePort, ...options }: FixtureOptions,
): Promise {
- if (options.type === 'esbuild') {
- return startEsbuildFixture(fixtureName, options);
+ const port = await portfinder.getPortPromise({ port: basePort });
+
+ console.log(
+ [
+ `Starting ${fixtureName} fixture`,
+ ...Object.entries({
+ type,
+ port,
+ ...options,
+ }).map(([key, value]) => `- ${key}: ${value}`),
+ ].join('\n'),
+ );
+
+ if (type === 'esbuild') {
+ return startEsbuildFixture(fixtureName, {
+ type: 'esbuild',
+ port,
+ });
}
- return startWebpackFixture(fixtureName, options);
+ return startWebpackFixture(fixtureName, { type, ...options, port });
}
diff --git a/test-helpers/src/startFixture/webpack.ts b/test-helpers/src/startFixture/webpack.ts
index b4326c927..bcb645af4 100644
--- a/test-helpers/src/startFixture/webpack.ts
+++ b/test-helpers/src/startFixture/webpack.ts
@@ -1,7 +1,6 @@
import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
import WDS from 'webpack-dev-server';
import webpack, { Configuration } from 'webpack';
-import portfinder from 'portfinder';
import webpackMerge from 'webpack-merge';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
@@ -54,34 +53,23 @@ const defaultWebpackConfig: Configuration = {
};
export interface WebpackFixtureOptions {
- type?: 'browser' | 'mini-css-extract' | 'style-loader';
+ type: 'browser' | 'mini-css-extract' | 'style-loader';
hot?: boolean;
mode?: 'development' | 'production';
- basePort?: number;
+ port: number;
logLevel?: Configuration['stats'];
}
export const startWebpackFixture = (
fixtureName: string,
{
- type = 'mini-css-extract',
+ type,
hot = false,
mode = 'development',
- basePort,
+ port,
logLevel = 'errors-only',
- }: WebpackFixtureOptions = {},
+ }: WebpackFixtureOptions,
): Promise =>
new Promise(async (resolve) => {
- console.log(
- [
- `Starting ${fixtureName} fixture`,
- ...Object.entries({
- type,
- hot,
- mode,
- }).map(([key, value]) => `- ${key}: ${value}`),
- ].join('\n'),
- );
-
const fixtureEntry = require.resolve(`@fixtures/${fixtureName}`);
const config = webpackMerge(defaultWebpackConfig, {
entry: fixtureEntry,
@@ -103,8 +91,6 @@ export const startWebpackFixture = (
});
const compiler = webpack(config);
- const port = await portfinder.getPortPromise({ port: basePort });
-
const server = new WDS(compiler, {
hot,
stats: logLevel,
diff --git a/test-helpers/src/startFixtureCLI.ts b/test-helpers/src/startFixtureCLI.ts
index aec3334f1..a9468c97e 100644
--- a/test-helpers/src/startFixtureCLI.ts
+++ b/test-helpers/src/startFixtureCLI.ts
@@ -8,7 +8,7 @@ const {
mode,
} = parseArgs(process.argv.slice(2));
-startFixture(fixtureName, { type, hot, mode }).then((server) => {
+startFixture(fixtureName, { type, hot, mode } as any).then((server) => {
// eslint-disable-next-line no-console
console.log('Fixture running on', server.url);
});
diff --git a/tests/E2E/__snapshots__/stylesheets.test.ts.snap b/tests/E2E/__snapshots__/stylesheets.test.ts.snap
index db17191c4..65a8de717 100644
--- a/tests/E2E/__snapshots__/stylesheets.test.ts.snap
+++ b/tests/E2E/__snapshots__/stylesheets.test.ts.snap
@@ -1,5 +1,196 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`Stylesheet themed - esbuild should create valid stylesheet 1`] = `
+"/* vanilla-extract-css-ns:/Users/mjones/projects/vanilla-extract/fixtures/themed/src/shared.css.ts.vanilla.css?source=Ll8xb2tuaWluMCB7CiAgYm94LXNoYWRvdzogMCAwIDVweCByZWQ7Cn0KYm9keSB7CiAgYmFja2dyb3VuZC1jb2xvcjogc2t5Ymx1ZTsKfQ== */
+._1okniin0 {
+ box-shadow: 0 0 5px red;
+}
+body {
+ background-color: skyblue;
+}
+
+/* vanilla-extract-css-ns:/Users/mjones/projects/vanilla-extract/fixtures/themed/src/styles.css.ts.vanilla.css?source=QGZvbnQtZmFjZSB7CiAgc3JjOiBsb2NhbCgiSW1wYWN0Iik7CiAgZm9udC1mYW1pbHk6ICJfMTF0ajZrMzAiOwp9CkBmb250LWZhY2UgewogIHNyYzogbG9jYWwoIkNvbWljIFNhbnMgTVMiKTsKICBmb250LWZhbWlseTogTXlHbG9iYWxDb21pY1NhbnM7Cn0KQGtleWZyYW1lcyBfMTF0ajZrMzEgewogIDAlIHsKICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtNHB4KTsKICB9CiAgMTAwJSB7CiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoNHB4KTsKICB9Cn0KQGtleWZyYW1lcyBnbG9iYWxTbGlkZSB7CiAgMCUgewogICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC00cHgpOwogIH0KICAxMDAlIHsKICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWSg0cHgpOwogIH0KfQouXzExdGo2azMyIHsKICBhbmltYXRpb246IDNzIGluZmluaXRlIGFsdGVybmF0ZSBnbG9iYWxTbGlkZSBlYXNlLWluLW91dDsKICBkaXNwbGF5OiBmbGV4OwogIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47CiAgZ2FwOiB2YXIoLS1zcGFjZS0yX18xOXZ6ZnE4NCk7CiAgcGFkZGluZzogdmFyKC0tc3BhY2UtM19fMTl2emZxODUpOwp9Ci5fMTF0ajZrMzMgewogIGFuaW1hdGlvbjogM3MgaW5maW5pdGUgYWx0ZXJuYXRlIF8xMXRqNmszMSBlYXNlLWluLW91dDsKICBmb250LWZhbWlseTogIl8xMXRqNmszMCI7CiAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tY29sb3JzLWJhY2tncm91bmQtY29sb3JfXzE5dnpmcTgxLCAiVEhJUyBGQUxMQkFDSyBWQUxVRSBTSE9VTEQgTkVWRVIgQkUgVVNFRCIpOwogIGNvbG9yOiB2YXIoLS1jb2xvcnMtdGV4dF9fMTl2emZxODIpOwp9Ci5fMTl2emZxODYgLl8xOXZ6ZnE4MCAuXzExdGo2azMyIC5fMTF0ajZrMzMgewogIGZvbnQtZmFtaWx5OiBNeUdsb2JhbENvbWljU2FuczsKICBvdXRsaW5lOiA1cHggc29saWQgcmVkOwp9Ci5zdHlsZXNfMVwvMl9fMTF0ajZrMzYgewogIG9wYWNpdHk6IHZhcigtLV8xMXRqNmszNCwgMC41KTsKfQouc3R5bGVzXzFcLzRfXzExdGo2azM3IHsKICBvcGFjaXR5OiB2YXIoLS1fMTF0ajZrMzQsIHZhcigtLV8xMXRqNmszNSwgMC4yNSkpOwp9CkBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogNTAwcHgpIHsKICAuXzExdGo2azMyIHsKICAgIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLWNvbG9ycy1iYWNrZ3JvdW5kLWNvbG9yX18xOXZ6ZnE4MSk7CiAgfQogIC5fMTF0ajZrMzMgewogICAgYm9yZGVyLXJhZGl1czogOTk5OXB4OwogIH0KfQ== */
+@font-face {
+ src: local(\\"Impact\\");
+ font-family: \\"_11tj6k30\\";
+}
+@font-face {
+ src: local(\\"Comic Sans MS\\");
+ font-family: MyGlobalComicSans;
+}
+@keyframes _11tj6k31 {
+ 0% {
+ transform: translateY(-4px);
+ }
+ 100% {
+ transform: translateY(4px);
+ }
+}
+@keyframes globalSlide {
+ 0% {
+ transform: translateY(-4px);
+ }
+ 100% {
+ transform: translateY(4px);
+ }
+}
+._11tj6k32 {
+ animation: 3s infinite alternate globalSlide ease-in-out;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2__19vzfq84);
+ padding: var(--space-3__19vzfq85);
+}
+._11tj6k33 {
+ animation: 3s infinite alternate _11tj6k31 ease-in-out;
+ font-family: \\"_11tj6k30\\";
+ background-color: var(--colors-background-color__19vzfq81, \\"THIS FALLBACK VALUE SHOULD NEVER BE USED\\");
+ color: var(--colors-text__19vzfq82);
+}
+._19vzfq86 ._19vzfq80 ._11tj6k32 ._11tj6k33 {
+ font-family: MyGlobalComicSans;
+ outline: 5px solid red;
+}
+.styles_1\\\\/2__11tj6k36 {
+ opacity: var(--_11tj6k34, 0.5);
+}
+.styles_1\\\\/4__11tj6k37 {
+ opacity: var(--_11tj6k34, var(--_11tj6k35, 0.25));
+}
+@media only screen and (min-width: 500px) {
+ ._11tj6k32 {
+ border: 1px solid var(--colors-background-color__19vzfq81);
+ }
+ ._11tj6k33 {
+ border-radius: 9999px;
+ }
+}
+
+/* vanilla-extract-css-ns:/Users/mjones/projects/vanilla-extract/fixtures/themed/src/themes.css.ts.vanilla.css?source=OnJvb3QsIC5fMTl2emZxODAgewogIC0tY29sb3JzLWJhY2tncm91bmQtY29sb3JfXzE5dnpmcTgxOiBibHVlOwogIC0tY29sb3JzLXRleHRfXzE5dnpmcTgyOiB3aGl0ZTsKICAtLXNwYWNlLTFfXzE5dnpmcTgzOiA0cHg7CiAgLS1zcGFjZS0yX18xOXZ6ZnE4NDogOHB4OwogIC0tc3BhY2UtM19fMTl2emZxODU6IDEycHg7Cn0KLl8xOXZ6ZnE4NiB7CiAgLS1jb2xvcnMtYmFja2dyb3VuZC1jb2xvcl9fMTl2emZxODE6IGdyZWVuOwogIC0tY29sb3JzLXRleHRfXzE5dnpmcTgyOiB3aGl0ZTsKICAtLXNwYWNlLTFfXzE5dnpmcTgzOiA4cHg7CiAgLS1zcGFjZS0yX18xOXZ6ZnE4NDogMTJweDsKICAtLXNwYWNlLTNfXzE5dnpmcTg1OiAxNnB4Owp9Ci5fMTl2emZxODcgewogIC0tY29sb3JzLWJhY2tncm91bmQtY29sb3JfXzE5dnpmcTgxOiBwaW5rOwogIC0tY29sb3JzLXRleHRfXzE5dnpmcTgyOiBwdXJwbGU7CiAgLS1zcGFjZS0xX18xOXZ6ZnE4MzogNnB4OwogIC0tc3BhY2UtMl9fMTl2emZxODQ6IDEycHg7CiAgLS1zcGFjZS0zX18xOXZ6ZnE4NTogMThweDsKfQpAbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA3NjhweCkgewogIC5fMTl2emZxODcgewogICAgLS1jb2xvcnMtYmFja2dyb3VuZC1jb2xvcl9fMTl2emZxODE6IHB1cnBsZTsKICAgIC0tY29sb3JzLXRleHRfXzE5dnpmcTgyOiBwaW5rOwogIH0KfQ== */
+:root,
+._19vzfq80 {
+ --colors-background-color__19vzfq81: blue;
+ --colors-text__19vzfq82: white;
+ --space-1__19vzfq83: 4px;
+ --space-2__19vzfq84: 8px;
+ --space-3__19vzfq85: 12px;
+}
+._19vzfq86 {
+ --colors-background-color__19vzfq81: green;
+ --colors-text__19vzfq82: white;
+ --space-1__19vzfq83: 8px;
+ --space-2__19vzfq84: 12px;
+ --space-3__19vzfq85: 16px;
+}
+._19vzfq87 {
+ --colors-background-color__19vzfq81: pink;
+ --colors-text__19vzfq82: purple;
+ --space-1__19vzfq83: 6px;
+ --space-2__19vzfq84: 12px;
+ --space-3__19vzfq85: 18px;
+}
+@media screen and (min-width: 768px) {
+ ._19vzfq87 {
+ --colors-background-color__19vzfq81: purple;
+ --colors-text__19vzfq82: pink;
+ }
+}
+"
+`;
+
+exports[`Stylesheet themed - webpack should create valid stylesheet 1`] = `
+":root, .themes_theme__40jr0n0 {
+ --colors-background-color__40jr0n1: blue;
+ --colors-text__40jr0n2: white;
+ --space-1__40jr0n3: 4px;
+ --space-2__40jr0n4: 8px;
+ --space-3__40jr0n5: 12px;
+}
+.themes_altTheme__40jr0n6 {
+ --colors-background-color__40jr0n1: green;
+ --colors-text__40jr0n2: white;
+ --space-1__40jr0n3: 8px;
+ --space-2__40jr0n4: 12px;
+ --space-3__40jr0n5: 16px;
+}
+.themes_responsiveTheme__40jr0n7 {
+ --colors-background-color__40jr0n1: pink;
+ --colors-text__40jr0n2: purple;
+ --space-1__40jr0n3: 6px;
+ --space-2__40jr0n4: 12px;
+ --space-3__40jr0n5: 18px;
+}
+@media screen and (min-width: 768px) {
+ .themes_responsiveTheme__40jr0n7 {
+ --colors-background-color__40jr0n1: purple;
+ --colors-text__40jr0n2: pink;
+ }
+}
+.shared_shadow__fb6bqk0 {
+ box-shadow: 0 0 5px red;
+}
+body {
+ background-color: skyblue;
+}
+@font-face {
+ src: local(\\"Impact\\");
+ font-family: \\"styles_impact__bh8jtc0\\";
+}
+@font-face {
+ src: local(\\"Comic Sans MS\\");
+ font-family: MyGlobalComicSans;
+}
+@keyframes styles_slide__bh8jtc1 {
+ 0% {
+ transform: translateY(-4px);
+ }
+ 100% {
+ transform: translateY(4px);
+ }
+}
+@keyframes globalSlide {
+ 0% {
+ transform: translateY(-4px);
+ }
+ 100% {
+ transform: translateY(4px);
+ }
+}
+.styles_container__bh8jtc2 {
+ animation: 3s infinite alternate globalSlide ease-in-out;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2__40jr0n4);
+ padding: var(--space-3__40jr0n5);
+}
+.styles_button__bh8jtc3 {
+ animation: 3s infinite alternate styles_slide__bh8jtc1 ease-in-out;
+ font-family: \\"styles_impact__bh8jtc0\\";
+ background-color: var(--colors-background-color__40jr0n1, \\"THIS FALLBACK VALUE SHOULD NEVER BE USED\\");
+ color: var(--colors-text__40jr0n2);
+}
+.themes_altTheme__40jr0n6 .themes_theme__40jr0n0 .styles_container__bh8jtc2 .styles_button__bh8jtc3 {
+ font-family: MyGlobalComicSans;
+ outline: 5px solid red;
+}
+.styles_opacity_1\\\\/2__bh8jtc6 {
+ opacity: var(--undefined-var1__bh8jtc4, 0.5);
+}
+.styles_opacity_1\\\\/4__bh8jtc7 {
+ opacity: var(--undefined-var1__bh8jtc4, var(--undefined-var2__bh8jtc5, 0.25));
+}
+@media only screen and (min-width: 500px) {
+ .styles_container__bh8jtc2 {
+ border: 1px solid var(--colors-background-color__40jr0n1);
+ }
+ .styles_button__bh8jtc3 {
+ border-radius: 9999px;
+ }
+}
+
+/*# sourceMappingURL=main.css.map*/"
+`;
+
exports[`Stylesheet themed should create valid stylesheet 1`] = `
":root, .themes_theme__40jr0n0 {
--colors-background-color__40jr0n1: blue;
@@ -93,6 +284,56 @@ body {
/*# sourceMappingURL=main.css.map*/"
`;
+exports[`Stylesheet unused-modules - esbuild should create valid stylesheet 1`] = `
+"/* vanilla-extract-css-ns:/Users/mjones/projects/vanilla-extract/fixtures/unused-modules/src/global.css.ts.vanilla.css?source=Ym9keSB7CiAgYmFja2dyb3VuZC1jb2xvcjogbGF2ZW5kZXI7Cn0= */
+body {
+ background-color: lavender;
+}
+
+/* vanilla-extract-css-ns:/Users/mjones/projects/vanilla-extract/fixtures/unused-modules/src/reset/reset.css.ts.vanilla.css?source=Lm4xdG5tMjAgewogIGJveC1zaXppbmc6IGJvcmRlci1ib3g7Cn0= */
+.n1tnm20 {
+ box-sizing: border-box;
+}
+
+/* vanilla-extract-css-ns:/Users/mjones/projects/vanilla-extract/fixtures/unused-modules/src/shared/shared.css.ts.vanilla.css?source=Ym9keSB7CiAgYm9yZGVyOiA1cHggc29saWQgYmxhY2s7Cn0KLmVyNTVjNTAgewogIGRpc3BsYXk6IGZsZXg7Cn0= */
+body {
+ border: 5px solid black;
+}
+.er55c50 {
+ display: flex;
+}
+
+/* vanilla-extract-css-ns:/Users/mjones/projects/vanilla-extract/fixtures/unused-modules/src/used/used.css.ts.vanilla.css?source=Ll8xYm90cnVkMCB7CiAgaGVpZ2h0OiAxMDBweDsKICB3aWR0aDogMTAwcHg7CiAgYmFja2dyb3VuZDogZ3JlZW47Cn0= */
+._1botrud0 {
+ height: 100px;
+ width: 100px;
+ background: green;
+}
+"
+`;
+
+exports[`Stylesheet unused-modules - webpack should create valid stylesheet 1`] = `
+"body {
+ background-color: lavender;
+}
+.reset_default__uwiqg30 {
+ box-sizing: border-box;
+}
+body {
+ border: 5px solid black;
+}
+.shared_default__1qsu10z0 {
+ display: flex;
+}
+.used_className__1q2bj4l0 {
+ height: 100px;
+ width: 100px;
+ background: green;
+}
+
+/*# sourceMappingURL=main.css.map*/"
+`;
+
exports[`Stylesheet unused-modules should create valid stylesheet 1`] = `
"body {
background-color: lavender;
diff --git a/tests/E2E/stylesheets.test.ts b/tests/E2E/stylesheets.test.ts
index c409fcac3..4b7b1fcda 100644
--- a/tests/E2E/stylesheets.test.ts
+++ b/tests/E2E/stylesheets.test.ts
@@ -3,7 +3,7 @@ import { getStylesheet, startFixture, TestServer } from 'test-helpers';
const fixtures = ['unused-modules', 'themed'];
describe('Stylesheet', () => {
- describe.each(fixtures)('%s', (fixture) => {
+ describe.each(fixtures)('%s - webpack', (fixture) => {
let server: TestServer;
beforeAll(async () => {
@@ -22,4 +22,24 @@ describe('Stylesheet', () => {
await server.close();
});
});
+
+ describe.each(fixtures)('%s - esbuild', (fixture) => {
+ let server: TestServer;
+
+ beforeAll(async () => {
+ server = await startFixture(fixture, {
+ type: 'esbuild',
+ mode: 'production',
+ basePort: 9000,
+ });
+ });
+
+ it('should create valid stylesheet', async () => {
+ expect(await getStylesheet(server.url, 'index.css')).toMatchSnapshot();
+ });
+
+ afterAll(async () => {
+ await server.close();
+ });
+ });
});
From ac2d02ad1d3de5e4b769aa66e17d3ce176fcc31e Mon Sep 17 00:00:00 2001
From: Matt Jones
Date: Thu, 1 Apr 2021 22:14:12 +1100
Subject: [PATCH 06/19] Document esbuild plugin
---
README.md | 26 +++++++++++++++-
packages/esbuild-plugin/src/index.ts | 19 +++++++++---
packages/webpack-plugin/src/esbuild.js | 43 --------------------------
3 files changed, 39 insertions(+), 49 deletions(-)
delete mode 100644 packages/webpack-plugin/src/esbuild.js
diff --git a/README.md b/README.md
index 2fc966e3d..1253ce09d 100644
--- a/README.md
+++ b/README.md
@@ -76,6 +76,7 @@ document.write(`
- [Setup](#setup)
- [webpack](#webpack)
+ - [esbuild](#esbuild)
- [Gatsby](#gatsby)
- [API](#api)
- [style](#style)
@@ -101,7 +102,7 @@ document.write(`
## Setup
-There are currently a couple of integrations to choose from.
+There are currently a few integrations to choose from.
### webpack
@@ -159,6 +160,29 @@ module.exports = {
```
+### esbuild
+
+> Note: We don't currently support automatic readable class names in dev for esbuild.
+
+1. Install the dependencies.
+
+```bash
+$ yarn add --dev @vanilla-extract/css @vanilla-extract/esbuild-plugin
+```
+
+2. Add the [esbuild](https://esbuild.github.io/) plugin to your build script.
+
+```js
+const { vanillaExtractPlugin } = require('@vanilla-extract/esbuild-plugin');
+
+require('esbuild').buildSync({
+ entryPoints: ['app.ts'],
+ bundle: true,
+ plugins: [vanillaExtractPlugin()],
+ outfile: 'out.js',
+})
+```
+
### Gatsby
To add to your [Gatsby](https://www.gatsbyjs.com) site, use the [gatsby-plugin-vanilla-extract](https://github.com/KyleAMathews/gatsby-plugin-vanilla-extract) plugin.
diff --git a/packages/esbuild-plugin/src/index.ts b/packages/esbuild-plugin/src/index.ts
index 920fafbc9..4ac4f8b11 100644
--- a/packages/esbuild-plugin/src/index.ts
+++ b/packages/esbuild-plugin/src/index.ts
@@ -36,7 +36,14 @@ const vanillaExtractFilescopePlugin: Plugin = {
},
};
-export function vanillaExtractPlugin(): Plugin {
+interface VanillaExtractPluginOptions {
+ outputCss?: boolean;
+ externals?: Array;
+}
+export function vanillaExtractPlugin({
+ outputCss = true,
+ externals = [],
+}: VanillaExtractPluginOptions = {}): Plugin {
return {
name: 'vanilla-extract',
setup(build) {
@@ -66,7 +73,7 @@ export function vanillaExtractPlugin(): Plugin {
entryPoints: [path],
metafile: true,
bundle: true,
- external: ['@vanilla-extract'],
+ external: ['@vanilla-extract', ...externals],
platform: 'node',
write: false,
plugins: [vanillaExtractFilescopePlugin],
@@ -85,11 +92,13 @@ export function vanillaExtractPlugin(): Plugin {
const cssAdapter: Adapter = {
appendCss: (css, fileScope) => {
- const fileScopeCss = cssByFileScope.get(fileScope) ?? [];
+ if (outputCss) {
+ const fileScopeCss = cssByFileScope.get(fileScope) ?? [];
- fileScopeCss.push(css);
+ fileScopeCss.push(css);
- cssByFileScope.set(fileScope, fileScopeCss);
+ cssByFileScope.set(fileScope, fileScopeCss);
+ }
},
registerClassName: (className) => {
localClassNames.add(className);
diff --git a/packages/webpack-plugin/src/esbuild.js b/packages/webpack-plugin/src/esbuild.js
deleted file mode 100644
index 17fa9778f..000000000
--- a/packages/webpack-plugin/src/esbuild.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const esbuild = require('esbuild');
-
-let startTime = Date.now();
-let result = esbuild.buildSync({
- entryPoints: [
- '/Users/mjones/projects/vanilla-extract/fixtures/themed/src/styles.css.ts',
- ],
- metafile: true,
- bundle: true,
- external: ['@vanilla-extract'],
- platform: 'node',
- write: false,
-});
-
-console.log(Date.now() - startTime);
-
-startTime = Date.now();
-result = esbuild.buildSync({
- entryPoints: [
- '/Users/mjones/projects/vanilla-extract/fixtures/themed/src/styles.css.ts',
- ],
- metafile: true,
- bundle: true,
- external: ['@vanilla-extract'],
- platform: 'node',
- write: false,
-});
-
-console.log(Date.now() - startTime);
-
-startTime = Date.now();
-result = esbuild.buildSync({
- entryPoints: [
- '/Users/mjones/projects/vanilla-extract/fixtures/themed/src/styles.css.ts',
- ],
- metafile: true,
- bundle: true,
- external: ['@vanilla-extract'],
- platform: 'node',
- write: false,
-});
-
-console.log(Date.now() - startTime);
From b5060598fd802af189bdc2953931e609d2a366ca Mon Sep 17 00:00:00 2001
From: Matt Jones
Date: Thu, 1 Apr 2021 22:27:33 +1100
Subject: [PATCH 07/19] Remove old files
---
meta.json | 1 -
out.js | 155 ------------------------------------------------------
2 files changed, 156 deletions(-)
delete mode 100644 meta.json
delete mode 100644 out.js
diff --git a/meta.json b/meta.json
deleted file mode 100644
index 8d8b724c0..000000000
--- a/meta.json
+++ /dev/null
@@ -1 +0,0 @@
-{"inputs":{"fixtures/themed/src/shared.css.ts":{"bytes":179,"imports":[]},"fixtures/themed/src/themes.css.ts":{"bytes":886,"imports":[]},"fixtures/themed/src/styles.css.ts":{"bytes":1799,"imports":[{"path":"fixtures/themed/src/shared.css.ts","kind":"import-statement"},{"path":"fixtures/themed/src/themes.css.ts","kind":"import-statement"}]}},"outputs":{"styles.css.js":{"imports":[],"exports":[],"entryPoint":"fixtures/themed/src/styles.css.ts","inputs":{"fixtures/themed/src/styles.css.ts":{"bytesInOutput":1852},"fixtures/themed/src/shared.css.ts":{"bytesInOutput":201},"fixtures/themed/src/themes.css.ts":{"bytesInOutput":899}},"bytes":4405}}}
\ No newline at end of file
diff --git a/out.js b/out.js
deleted file mode 100644
index 59e2565eb..000000000
--- a/out.js
+++ /dev/null
@@ -1,155 +0,0 @@
-var __create = Object.create;
-var __defProp = Object.defineProperty;
-var __getProtoOf = Object.getPrototypeOf;
-var __hasOwnProp = Object.prototype.hasOwnProperty;
-var __getOwnPropNames = Object.getOwnPropertyNames;
-var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
-var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
-var __export = (target, all) => {
- for (var name in all)
- __defProp(target, name, {get: all[name], enumerable: true});
-};
-var __exportStar = (target, module2, desc) => {
- if (module2 && typeof module2 === "object" || typeof module2 === "function") {
- for (let key of __getOwnPropNames(module2))
- if (!__hasOwnProp.call(target, key) && key !== "default")
- __defProp(target, key, {get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable});
- }
- return target;
-};
-var __toModule = (module2) => {
- return __exportStar(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? {get: () => module2.default, enumerable: true} : {value: module2, enumerable: true})), module2);
-};
-
-// fixtures/themed/src/styles.css.ts
-__markAsModule(exports);
-__export(exports, {
- button: () => button,
- container: () => container,
- opacity: () => opacity
-});
-var import_css3 = __toModule(require("@vanilla-extract/css"));
-
-// fixtures/themed/src/shared.css.ts
-var import_css = __toModule(require("@vanilla-extract/css"));
-var shadow = (0, import_css.style)({
- boxShadow: "0 0 5px red"
-});
-(0, import_css.globalStyle)("body", {
- backgroundColor: "skyblue"
-});
-
-// fixtures/themed/src/themes.css.ts
-var import_css2 = __toModule(require("@vanilla-extract/css"));
-var theme = (0, import_css2.style)({});
-var vars = (0, import_css2.createGlobalTheme)(`:root, ${theme}`, {
- colors: {
- backgroundColor: "blue",
- text: "white"
- },
- space: {
- 1: "4px",
- 2: "8px",
- 3: "12px"
- }
-});
-var altTheme = (0, import_css2.createTheme)(vars, {
- colors: {
- backgroundColor: "green",
- text: "white"
- },
- space: {
- 1: "8px",
- 2: "12px",
- 3: "16px"
- }
-});
-var responsiveTheme = (0, import_css2.style)({
- vars: (0, import_css2.assignVars)(vars, {
- colors: {
- backgroundColor: "pink",
- text: "purple"
- },
- space: {
- 1: "6px",
- 2: "12px",
- 3: "18px"
- }
- }),
- "@media": {
- "screen and (min-width: 768px)": {
- vars: (0, import_css2.assignVars)(vars.colors, {
- backgroundColor: "purple",
- text: "pink"
- })
- }
- }
-});
-
-// fixtures/themed/src/styles.css.ts
-var impact = (0, import_css3.fontFace)({
- src: 'local("Impact")'
-});
-(0, import_css3.globalFontFace)("MyGlobalComicSans", {
- src: 'local("Comic Sans MS")'
-});
-var slide = (0, import_css3.keyframes)({
- "0%": {
- transform: "translateY(-4px)"
- },
- "100%": {
- transform: "translateY(4px)"
- }
-});
-(0, import_css3.globalKeyframes)("globalSlide", {
- "0%": {
- transform: "translateY(-4px)"
- },
- "100%": {
- transform: "translateY(4px)"
- }
-});
-var container = (0, import_css3.style)({
- animation: `3s infinite alternate globalSlide ease-in-out`,
- display: "flex",
- flexDirection: "column",
- gap: vars.space[2],
- padding: vars.space[3],
- "@media": {
- "only screen and (min-width: 500px)": {
- border: `1px solid ${vars.colors.backgroundColor}`
- }
- }
-});
-var button = [
- (0, import_css3.style)({
- animation: `3s infinite alternate ${slide} ease-in-out`,
- fontFamily: impact,
- backgroundColor: (0, import_css3.fallbackVar)(vars.colors.backgroundColor, '"THIS FALLBACK VALUE SHOULD NEVER BE USED"'),
- color: vars.colors.text,
- "@media": {
- "only screen and (min-width: 500px)": {
- borderRadius: "9999px"
- }
- },
- selectors: {
- [`${altTheme} ${theme} ${container} &`]: {
- fontFamily: "MyGlobalComicSans",
- outline: "5px solid red"
- }
- }
- }),
- shadow
-];
-var undefinedVar1 = (0, import_css3.createVar)();
-var undefinedVar2 = (0, import_css3.createVar)();
-var opacity = (0, import_css3.mapToStyles)({
- "1/2": (0, import_css3.fallbackVar)(undefinedVar1, "0.5"),
- "1/4": (0, import_css3.fallbackVar)(undefinedVar1, undefinedVar2, "0.25")
-}, (value) => ({opacity: value}));
-// Annotate the CommonJS export names for ESM import in node:
-0 && (module.exports = {
- button,
- container,
- opacity
-});
From f22d342f53a061db707344775ad99568dd286b7b Mon Sep 17 00:00:00 2001
From: Matt Jones
Date: Thu, 1 Apr 2021 22:29:38 +1100
Subject: [PATCH 08/19] Remove unused deps
---
packages/esbuild-plugin/package.json | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/packages/esbuild-plugin/package.json b/packages/esbuild-plugin/package.json
index 7195fae1a..682581747 100644
--- a/packages/esbuild-plugin/package.json
+++ b/packages/esbuild-plugin/package.json
@@ -1,6 +1,6 @@
{
"name": "@vanilla-extract/esbuild-plugin",
- "version": "0.1.0",
+ "version": "0.0.1",
"description": "Zero-runtime Stylesheets-in-TypeScript",
"main": "dist/vanilla-extract-esbuild-plugin.cjs.js",
"module": "dist/vanilla-extract-esbuild-plugin.esm.js",
@@ -20,14 +20,12 @@
"dependencies": {
"@vanilla-extract/css": "^0.1.0",
"chalk": "^4.1.0",
- "debug": "^4.3.1",
"dedent": "^0.7.0",
"eval": "^0.1.6",
"javascript-stringify": "^2.0.1",
"lodash": "^4.17.21"
},
"devDependencies": {
- "@types/debug": "^4.1.5",
"@types/dedent": "^0.7.0",
"esbuild": "^0.11.1"
}
From 8adfbd7b9b798607e70b50463654ab94eaf68885 Mon Sep 17 00:00:00 2001
From: Matt Jones
Date: Thu, 1 Apr 2021 23:17:27 +1100
Subject: [PATCH 09/19] Add projectRoot option
---
README.md | 5 +-
packages/esbuild-plugin/src/index.ts | 29 ++-
packages/webpack-plugin/package.json | 1 -
test-helpers/package.json | 4 +-
test-helpers/src/startFixture/esbuild.ts | 100 +++-----
tests/E2E/__snapshots__/styles.test.ts.snap | 98 ++++----
.../__snapshots__/stylesheets.test.ts.snap | 219 +++++-------------
tests/E2E/stylesheets.test.ts | 2 +-
yarn.lock | 98 +-------
9 files changed, 164 insertions(+), 392 deletions(-)
diff --git a/README.md b/README.md
index 1253ce09d..2f4d8f916 100644
--- a/README.md
+++ b/README.md
@@ -162,7 +162,10 @@ module.exports = {
### esbuild
-> Note: We don't currently support automatic readable class names in dev for esbuild.
+Current limitations:
+
+- No automatic readable class names in dev
+- The `projectRoot` plugin option must be set to get deterministic class name hashes between build systems
1. Install the dependencies.
diff --git a/packages/esbuild-plugin/src/index.ts b/packages/esbuild-plugin/src/index.ts
index 4ac4f8b11..cef5e9af2 100644
--- a/packages/esbuild-plugin/src/index.ts
+++ b/packages/esbuild-plugin/src/index.ts
@@ -1,4 +1,4 @@
-import { dirname } from 'path';
+import { dirname, relative } from 'path';
import { promises as fs } from 'fs';
import type { Adapter } from '@vanilla-extract/css';
@@ -13,16 +13,23 @@ import isPlainObject from 'lodash/isPlainObject';
const vanillaCssNamespace = 'vanilla-extract-css-ns';
-const vanillaExtractFilescopePlugin: Plugin = {
+interface FilescopePluginOptions {
+ projectRoot?: string;
+}
+const vanillaExtractFilescopePlugin = ({
+ projectRoot,
+}: FilescopePluginOptions): Plugin => ({
name: 'vanilla-extract-filescope',
setup(build) {
build.onLoad({ filter: /\.(js|jsx|ts|tsx)$/ }, async ({ path }) => {
const originalSource = await fs.readFile(path, 'utf-8');
if (originalSource.indexOf('@vanilla-extract/css/fileScope') === -1) {
+ const fileScope = projectRoot ? relative(projectRoot, path) : path;
+
const contents = `
import { setFileScope, endFileScope } from "@vanilla-extract/css/fileScope";
- setFileScope("${path}");
+ setFileScope("${fileScope}");
${originalSource}
endFileScope()
`;
@@ -34,23 +41,27 @@ const vanillaExtractFilescopePlugin: Plugin = {
}
});
},
-};
+});
interface VanillaExtractPluginOptions {
outputCss?: boolean;
externals?: Array;
+ projectRoot?: string;
}
export function vanillaExtractPlugin({
outputCss = true,
externals = [],
+ projectRoot,
}: VanillaExtractPluginOptions = {}): Plugin {
return {
name: 'vanilla-extract',
setup(build) {
- build.onResolve({ filter: /vanilla\.css\?source=.*$/ }, (args) => ({
- path: args.path,
- namespace: vanillaCssNamespace,
- }));
+ build.onResolve({ filter: /vanilla\.css\?source=.*$/ }, (args) => {
+ return {
+ path: args.path,
+ namespace: vanillaCssNamespace,
+ };
+ });
build.onLoad(
{ filter: /.*/, namespace: vanillaCssNamespace },
@@ -76,7 +87,7 @@ export function vanillaExtractPlugin({
external: ['@vanilla-extract', ...externals],
platform: 'node',
write: false,
- plugins: [vanillaExtractFilescopePlugin],
+ plugins: [vanillaExtractFilescopePlugin({ projectRoot })],
treeShaking: 'ignore-annotations',
});
diff --git a/packages/webpack-plugin/package.json b/packages/webpack-plugin/package.json
index 76513318e..8771e8fda 100644
--- a/packages/webpack-plugin/package.json
+++ b/packages/webpack-plugin/package.json
@@ -31,7 +31,6 @@
"chalk": "^4.1.0",
"debug": "^4.3.1",
"dedent": "^0.7.0",
- "esbuild": "^0.10.2",
"eval": "^0.1.6",
"javascript-stringify": "^2.0.1",
"loader-utils": "^2.0.0",
diff --git a/test-helpers/package.json b/test-helpers/package.json
index eeaaeaf1e..8b21dab17 100644
--- a/test-helpers/package.json
+++ b/test-helpers/package.json
@@ -18,14 +18,12 @@
"minimist": "^1.2.5",
"path-browserify": "^1.0.1",
"portfinder": "^1.0.28",
- "serve-handler": "^6.1.3",
"style-loader": "^2.0.0",
"webpack": "^5.27.1",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.7.3"
},
"devDependencies": {
- "@types/minimist": "^1",
- "@types/serve-handler": "^6"
+ "@types/minimist": "^1"
}
}
diff --git a/test-helpers/src/startFixture/esbuild.ts b/test-helpers/src/startFixture/esbuild.ts
index 28a8ee09b..288523e3a 100644
--- a/test-helpers/src/startFixture/esbuild.ts
+++ b/test-helpers/src/startFixture/esbuild.ts
@@ -2,9 +2,7 @@ import path from 'path';
import { promises as fs } from 'fs';
import { vanillaExtractPlugin } from '@vanilla-extract/esbuild-plugin';
-import { build } from 'esbuild';
-import handler from 'serve-handler';
-import http from 'http';
+import { serve } from 'esbuild';
import { TestServer } from './types';
@@ -16,80 +14,50 @@ export interface EsbuildFixtureOptions {
export const startEsbuildFixture = async (
fixtureName: string,
{ mode = 'development', port = 3000 }: EsbuildFixtureOptions,
-): Promise =>
- new Promise(async (resolve) => {
- const entry = require.resolve(`@fixtures/${fixtureName}`);
- const outdir = path.join(
- path.dirname(require.resolve(`@fixtures/${fixtureName}/package.json`)),
- 'dist',
- );
-
- const result = await build({
+): Promise => {
+ const entry = require.resolve(`@fixtures/${fixtureName}`);
+ const projectRoot = path.dirname(
+ require.resolve(`@fixtures/${fixtureName}/package.json`),
+ );
+ const outdir = path.join(projectRoot, 'dist');
+
+ const server = await serve(
+ { servedir: outdir, port },
+ {
entryPoints: [entry],
metafile: true,
platform: 'browser',
bundle: true,
minify: mode === 'production',
- plugins: [vanillaExtractPlugin()],
+ plugins: [vanillaExtractPlugin({ projectRoot })],
outdir,
- write: true,
- watch: true,
- });
-
- const scripts = [];
- const stylesheets = [];
-
- for (const filePath of Object.keys(result.metafile?.outputs || {})) {
- const relativeFilePath = path.relative(outdir, filePath);
-
- if (relativeFilePath.endsWith('.css')) {
- stylesheets.push(
- ``,
- );
- } else if (relativeFilePath.endsWith('.js')) {
- scripts.push(``);
- } else {
- console.warn('Unsupported output file:', relativeFilePath);
- }
- }
+ },
+ );
- await fs.writeFile(
- path.join(outdir, 'index.html'),
- `
+ await fs.writeFile(
+ path.join(outdir, 'index.html'),
+ `
-
- esbuild - ${fixtureName}
- ${stylesheets.join('\n')}
-
+
+ esbuild - ${fixtureName}
+
+
- ${scripts.join('\n')}
+