Skip to content

Commit e1550da

Browse files
Add serialize CSS utilities (#623)
Co-authored-by: Michael Taranto <[email protected]>
1 parent bec1cd8 commit e1550da

File tree

14 files changed

+89
-37
lines changed

14 files changed

+89
-37
lines changed

.changeset/friendly-turkeys-play.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
2+
'@vanilla-extract/esbuild-plugin': patch
23
'@vanilla-extract/integration': patch
34
'@vanilla-extract/webpack-plugin': patch
45
---

.changeset/large-fans-appear.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@vanilla-extract/integration': major
3+
---
4+
5+
BREAKING CHANGE
6+
7+
`getSourceFromVirtualCssFile` is now async.

.changeset/nasty-pillows-chew.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@vanilla-extract/integration': major
3+
---
4+
5+
Add `serializeCss` and `deserializeCss` utilities.
6+
7+
BREAKING CHANGE
8+
9+
Remove `base64Source` from `serializeVirtualCssPath`. Use the new `serializeCss` and `deserializeCss` functions if required.

packages/esbuild-plugin/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export function vanillaExtractPlugin({
4343
build.onLoad(
4444
{ filter: /.*/, namespace: vanillaCssNamespace },
4545
async ({ path }) => {
46-
let { source } = getSourceFromVirtualCssFile(path);
46+
let { source } = await getSourceFromVirtualCssFile(path);
4747

4848
if (typeof processCss === 'function') {
4949
source = await processCss(source);

packages/integration/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export { getPackageInfo } from './packageInfo';
88
export { compile, vanillaExtractFilescopePlugin } from './compile';
99
export { hash } from './hash';
1010
export { addFileScope } from './addFileScope';
11+
export { serializeCss, deserializeCss } from './serialize';
12+
1113
export * from './filters';
1214

1315
export type { IdentifierOption } from './processVanillaFile';

packages/integration/src/processVanillaFile.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ import evalCode from 'eval';
55
import { stringify } from 'javascript-stringify';
66
import isPlainObject from 'lodash/isPlainObject';
77
import outdent from 'outdent';
8+
89
import { hash } from './hash';
9-
import zlib from 'zlib';
10+
import { serializeCss } from './serialize';
1011

1112
const originalNodeEnv = process.env.NODE_ENV;
1213

@@ -35,7 +36,6 @@ interface ProcessVanillaFileOptions {
3536
identOption?: IdentifierOption;
3637
serializeVirtualCssPath?: (file: {
3738
fileName: string;
38-
base64Source: string;
3939
fileScope: FileScope;
4040
source: string;
4141
}) => string | Promise<string>;
@@ -110,9 +110,6 @@ export async function processVanillaFile({
110110
cssObjs: fileScopeCss,
111111
}).join('\n');
112112

113-
const compressedCSS = zlib.gzipSync(css);
114-
const base64Source = compressedCSS.toString('base64');
115-
116113
const fileName = `${
117114
fileScope.packageName
118115
? `${fileScope.packageName}/${fileScope.filePath}`
@@ -124,7 +121,6 @@ export async function processVanillaFile({
124121
if (serializeVirtualCssPath) {
125122
const serializedResult = serializeVirtualCssPath({
126123
fileName,
127-
base64Source,
128124
fileScope,
129125
source: css,
130126
});
@@ -135,7 +131,9 @@ export async function processVanillaFile({
135131
virtualCssFilePath = await serializedResult;
136132
}
137133
} else {
138-
virtualCssFilePath = `import '${fileName}?source=${base64Source}';`;
134+
const serializedCss = await serializeCss(css);
135+
136+
virtualCssFilePath = `import '${fileName}?source=${serializedCss}';`;
139137
}
140138

141139
cssImports.push(virtualCssFilePath);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { gzip, gunzip } from 'zlib';
2+
import { promisify } from 'util';
3+
4+
const zip = promisify(gzip);
5+
const unzip = promisify(gunzip);
6+
7+
// The byte threshold for applying compression, below which compressing would out-weigh its value.
8+
const compressionThreshold = 1000;
9+
const compressionFlag = '#';
10+
11+
export async function serializeCss(source: string) {
12+
if (source.length > compressionThreshold) {
13+
const compressedSource = await zip(source);
14+
15+
return compressionFlag + compressedSource.toString('base64');
16+
}
17+
18+
return Buffer.from(source, 'utf-8').toString('base64');
19+
}
20+
21+
export async function deserializeCss(source: string) {
22+
if (source.indexOf(compressionFlag) > -1) {
23+
const decompressedSource = await unzip(
24+
Buffer.from(source.replace(compressionFlag, ''), 'base64'),
25+
);
26+
27+
return decompressedSource.toString('utf-8');
28+
}
29+
30+
return Buffer.from(source, 'base64').toString('utf-8');
31+
}
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
import zlib from 'zlib';
1+
import { deserializeCss } from './serialize';
22

3-
export function getSourceFromVirtualCssFile(id: string) {
3+
export async function getSourceFromVirtualCssFile(id: string) {
44
const match = id.match(/^(?<fileName>.*)\?source=(?<source>.*)$/) ?? [];
55

66
if (!match || !match.groups) {
77
throw new Error('No source in vanilla CSS file');
88
}
99

10-
const decompressedSource = zlib.gunzipSync(
11-
Buffer.from(match.groups.source, 'base64'),
12-
);
10+
const source = await deserializeCss(match.groups.source);
1311

1412
return {
1513
fileName: match.groups.fileName,
16-
source: decompressedSource.toString('utf-8'),
14+
source,
1715
};
1816
}

packages/webpack-plugin/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,24 @@
1818
"module": "./extracted/dist/vanilla-extract-webpack-plugin-extracted.esm.js",
1919
"default": "./extracted/dist/vanilla-extract-webpack-plugin-extracted.cjs.js"
2020
},
21-
"./virtual": {
22-
"module": "./virtual/dist/vanilla-extract-webpack-plugin-virtual.esm.js",
23-
"default": "./virtual/dist/vanilla-extract-webpack-plugin-virtual.cjs.js"
21+
"./virtualFileLoader": {
22+
"module": "./virtualFileLoader/dist/vanilla-extract-webpack-plugin-virtualFileLoader.esm.js",
23+
"default": "./virtualFileLoader/dist/vanilla-extract-webpack-plugin-virtualFileLoader.cjs.js"
2424
}
2525
},
2626
"preconstruct": {
2727
"entrypoints": [
2828
"index.ts",
2929
"loader.ts",
3030
"extracted.js",
31-
"virtual.ts"
31+
"virtualFileLoader.ts"
3232
]
3333
},
3434
"files": [
3535
"/dist",
3636
"/loader",
3737
"/extracted",
38-
"/virtual"
38+
"/virtualFileLoader"
3939
],
4040
"repository": {
4141
"type": "git",

packages/webpack-plugin/src/loader.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@ import {
66
processVanillaFile,
77
addFileScope,
88
PackageInfo,
9+
serializeCss,
910
} from '@vanilla-extract/integration';
1011

1112
import type { LoaderContext } from './types';
1213
import { debug, formatResourcePath } from './logger';
1314
import { ChildCompiler } from './compiler';
1415

1516
const virtualLoader = require.resolve(
16-
path.join(path.dirname(require.resolve('../../package.json')), 'virtual'),
17+
path.join(
18+
path.dirname(require.resolve('../../package.json')),
19+
'virtualFileLoader',
20+
),
1721
);
1822

1923
const emptyCssExtractionFile = require.resolve(
@@ -76,9 +80,10 @@ export function pitch(this: LoaderContext) {
7680
filePath: this.resourcePath,
7781
identOption:
7882
identifiers ?? (this.mode === 'production' ? 'short' : 'debug'),
79-
serializeVirtualCssPath: ({ fileName, base64Source }) => {
83+
serializeVirtualCssPath: async ({ fileName, source }) => {
84+
const serializedCss = await serializeCss(source);
8085
const virtualResourceLoader = `${virtualLoader}?${JSON.stringify({
81-
source: base64Source,
86+
source: serializedCss,
8287
})}`;
8388

8489
const request = loaderUtils.stringifyRequest(

0 commit comments

Comments
 (0)