Skip to content

Commit e41529e

Browse files
mxmulmattcompiles
andauthored
Add snowpack-plugin (#110)
Co-authored-by: Matt Jones <[email protected]>
1 parent bc8d97b commit e41529e

File tree

16 files changed

+1294
-32
lines changed

16 files changed

+1294
-32
lines changed

.changeset/cool-beds-cheat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@vanilla-extract/integration": patch
3+
---
4+
5+
Add `fileScope` to `serializeVirtualCssPath` option
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Snowpack App</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/dist/index.js"></script>
11+
</body>
12+
</html>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Snowpack App</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/dist/index.js"></script>
11+
</body>
12+
</html>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Snowpack App</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/dist/index.js"></script>
11+
</body>
12+
</html>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Snowpack App</title>
7+
</head>
8+
<body>
9+
<div id="root"></div>
10+
<script type="module" src="/dist/index.js"></script>
11+
</body>
12+
</html>

packages/integration/src/compile.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ export const vanillaExtractFilescopePlugin = (): Plugin => ({
2222

2323
const contents = `
2424
import { setFileScope, endFileScope } from "@vanilla-extract/css/fileScope";
25-
setFileScope("${filePath}", "${packageInfo.name}");
25+
setFileScope("${filePath}", ${
26+
packageInfo.name ? `"${packageInfo.name}"` : 'undefined'
27+
});
28+
2629
${originalSource}
2730
endFileScope()
2831
`;

packages/integration/src/processVanillaFile.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ interface ProcessVanillaFileOptions {
3030
serializeVirtualCssPath?: (file: {
3131
fileName: string;
3232
base64Source: string;
33+
fileScope: FileScope;
3334
}) => string;
3435
}
3536
export function processVanillaFile({
@@ -82,21 +83,21 @@ export function processVanillaFile({
8283
const cssImports = [];
8384

8485
for (const [serialisedFileScope, fileScopeCss] of cssByFileScope) {
85-
const filescope = parseFileScope(serialisedFileScope);
86+
const fileScope = parseFileScope(serialisedFileScope);
8687
const css = transformCss({
8788
localClassNames: Array.from(localClassNames),
8889
cssObjs: fileScopeCss,
8990
}).join('\n');
9091

9192
const base64Source = Buffer.from(css, 'utf-8').toString('base64');
9293
const fileName = `${
93-
filescope.packageName
94-
? `${filescope.packageName}/${filescope.filePath}`
95-
: filescope.filePath
94+
fileScope.packageName
95+
? `${fileScope.packageName}/${fileScope.filePath}`
96+
: fileScope.filePath
9697
}.vanilla.css`;
9798

9899
const virtualCssFilePath = serializeVirtualCssPath
99-
? serializeVirtualCssPath({ fileName, base64Source })
100+
? serializeVirtualCssPath({ fileName, base64Source, fileScope })
100101
: `import '${fileName}?source=${base64Source}';`;
101102

102103
cssImports.push(virtualCssFilePath);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "@vanilla-extract/snowpack-plugin",
3+
"version": "0.0.1",
4+
"description": "Zero-runtime Stylesheets-in-TypeScript",
5+
"main": "dist/vanilla-extract-snowpack-plugin.cjs.js",
6+
"module": "dist/vanilla-extract-snowpack-plugin.esm.js",
7+
"files": [
8+
"/dist"
9+
],
10+
"repository": {
11+
"type": "git",
12+
"url": "https://github.com/seek-oss/vanilla-extract.git",
13+
"directory": "packages/snowpack-plugin"
14+
},
15+
"author": "SEEK",
16+
"license": "MIT",
17+
"dependencies": {
18+
"@vanilla-extract/integration": "^0.1.0"
19+
},
20+
"devDependencies": {
21+
"snowpack": "^3.5.1"
22+
}
23+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import path from 'path';
2+
import { SnowpackBuildMap, SnowpackConfig, SnowpackPlugin } from 'snowpack';
3+
import {
4+
processVanillaFile,
5+
compile,
6+
getSourceFromVirtualCssFile,
7+
} from '@vanilla-extract/integration';
8+
9+
export default function vanillaExtractPlugin(
10+
snowpackConfig: SnowpackConfig,
11+
): SnowpackPlugin {
12+
const importedByMap = new Map();
13+
14+
function addImportsToMap(filePath: string, dependency: string) {
15+
const importedBy = importedByMap.get(dependency);
16+
if (importedBy) {
17+
importedBy.add(filePath);
18+
} else {
19+
importedByMap.set(dependency, new Set([filePath]));
20+
}
21+
}
22+
23+
return {
24+
name: '@vanilla-extract/snowpack-plugin',
25+
resolve: {
26+
input: ['.css.ts'],
27+
output: ['.js', '.css'],
28+
},
29+
onChange({ filePath }) {
30+
if (importedByMap.has(filePath)) {
31+
const importedBy = importedByMap.get(filePath);
32+
importedByMap.delete(filePath);
33+
for (const dependentFilePath of importedBy) {
34+
this.markChanged?.(dependentFilePath);
35+
}
36+
}
37+
},
38+
async load(args) {
39+
const { filePath, isSSR } = args;
40+
const cwd = snowpackConfig.root || process.cwd();
41+
42+
const { source, watchFiles } = await compile({
43+
filePath,
44+
cwd,
45+
});
46+
47+
watchFiles.forEach((dependency) => {
48+
addImportsToMap(filePath, dependency);
49+
});
50+
51+
let css;
52+
const js = processVanillaFile({
53+
source,
54+
filePath,
55+
outputCss: !isSSR,
56+
serializeVirtualCssPath({ base64Source, fileScope }) {
57+
const cssUrl = `${path.join(cwd, fileScope.filePath)}.css`;
58+
59+
if (cssUrl === `${filePath}.css`) {
60+
css = getSourceFromVirtualCssFile(`?source=${base64Source}`).source;
61+
// snowpack injects the .css import for us
62+
return '';
63+
}
64+
65+
const rel = path.relative(path.dirname(filePath), cssUrl);
66+
const relWithLeadingDot =
67+
rel.startsWith('./') || rel.startsWith('../') ? rel : `./${rel}`;
68+
69+
return `import "${relWithLeadingDot}";`;
70+
},
71+
});
72+
73+
const buildMap: SnowpackBuildMap = {
74+
'.js': {
75+
code: js,
76+
},
77+
};
78+
if (!isSSR && css) {
79+
buildMap['.css'] = { code: css };
80+
}
81+
return buildMap;
82+
},
83+
};
84+
}

test-helpers/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"path-browserify": "^1.0.1",
2323
"portfinder": "^1.0.28",
2424
"serve-handler": "^6.1.3",
25+
"snowpack": "^3.5.1",
2526
"style-loader": "^2.0.0",
2627
"vite": "^2.2.3",
2728
"webpack": "^5.36.1",

0 commit comments

Comments
 (0)