@knighted/css 1.0.0-alpha.4 → 1.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/loader.cjs +95 -17
- package/dist/cjs/loader.d.cts +5 -1
- package/dist/loader.d.ts +5 -1
- package/dist/loader.js +93 -17
- package/package.json +1 -1
package/dist/cjs/loader.cjs
CHANGED
|
@@ -1,25 +1,103 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pitch = void 0;
|
|
3
4
|
const css_js_1 = require("./css.cjs");
|
|
4
5
|
const DEFAULT_EXPORT_NAME = 'knightedCss';
|
|
6
|
+
const COMBINED_QUERY_FLAG = 'combined';
|
|
5
7
|
const loader = async function loader(source) {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
cwd: cssOptions.cwd ?? this.rootContext ?? process.cwd(),
|
|
11
|
-
};
|
|
12
|
-
const { css, files } = await (0, css_js_1.cssWithMeta)(this.resourcePath, normalizedOptions);
|
|
13
|
-
const uniqueFiles = new Set([this.resourcePath, ...files]);
|
|
14
|
-
for (const file of uniqueFiles) {
|
|
15
|
-
this.addDependency(file);
|
|
16
|
-
}
|
|
17
|
-
const input = typeof source === 'string' ? source : source.toString('utf8');
|
|
18
|
-
const injection = `\n\nexport const ${DEFAULT_EXPORT_NAME} = ${JSON.stringify(css)};\n`;
|
|
8
|
+
const cssOptions = resolveCssOptions(this);
|
|
9
|
+
const css = await extractCss(this, cssOptions);
|
|
10
|
+
const injection = buildInjection(css);
|
|
11
|
+
const input = toSourceString(source);
|
|
19
12
|
const isStyleModule = this.resourcePath.endsWith('.css.ts');
|
|
20
|
-
|
|
21
|
-
? `${injection}export default {};\n`
|
|
22
|
-
: `${input}${injection}`;
|
|
23
|
-
return output;
|
|
13
|
+
return isStyleModule ? `${injection}export default {};\n` : `${input}${injection}`;
|
|
24
14
|
};
|
|
15
|
+
const pitch = function pitch() {
|
|
16
|
+
if (!hasCombinedQuery(this.resourceQuery)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const request = buildProxyRequest(this);
|
|
20
|
+
const cssOptions = resolveCssOptions(this);
|
|
21
|
+
return extractCss(this, cssOptions).then(css => createCombinedModule(request, css));
|
|
22
|
+
};
|
|
23
|
+
exports.pitch = pitch;
|
|
24
|
+
loader.pitch = exports.pitch;
|
|
25
25
|
exports.default = loader;
|
|
26
|
+
function resolveCssOptions(ctx) {
|
|
27
|
+
const rawOptions = (typeof ctx.getOptions === 'function' ? ctx.getOptions() : {});
|
|
28
|
+
return {
|
|
29
|
+
...rawOptions,
|
|
30
|
+
cwd: rawOptions.cwd ?? ctx.rootContext ?? process.cwd(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async function extractCss(ctx, options) {
|
|
34
|
+
const { css, files } = await (0, css_js_1.cssWithMeta)(ctx.resourcePath, options);
|
|
35
|
+
const uniqueFiles = new Set([ctx.resourcePath, ...files]);
|
|
36
|
+
for (const file of uniqueFiles) {
|
|
37
|
+
ctx.addDependency(file);
|
|
38
|
+
}
|
|
39
|
+
return css;
|
|
40
|
+
}
|
|
41
|
+
function toSourceString(source) {
|
|
42
|
+
return typeof source === 'string' ? source : source.toString('utf8');
|
|
43
|
+
}
|
|
44
|
+
function buildInjection(css) {
|
|
45
|
+
return `\n\nexport const ${DEFAULT_EXPORT_NAME} = ${JSON.stringify(css)};\n`;
|
|
46
|
+
}
|
|
47
|
+
function hasCombinedQuery(query) {
|
|
48
|
+
if (!query)
|
|
49
|
+
return false;
|
|
50
|
+
const trimmed = query.startsWith('?') ? query.slice(1) : query;
|
|
51
|
+
if (!trimmed)
|
|
52
|
+
return false;
|
|
53
|
+
return trimmed
|
|
54
|
+
.split('&')
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
.some(part => isQueryFlag(part, COMBINED_QUERY_FLAG));
|
|
57
|
+
}
|
|
58
|
+
function buildProxyRequest(ctx) {
|
|
59
|
+
const sanitizedQuery = buildSanitizedQuery(ctx.resourceQuery);
|
|
60
|
+
const request = `${ctx.resourcePath}${sanitizedQuery}`;
|
|
61
|
+
const context = ctx.context ?? ctx.rootContext ?? process.cwd();
|
|
62
|
+
if (ctx.utils && typeof ctx.utils.contextify === 'function') {
|
|
63
|
+
return ctx.utils.contextify(context, request);
|
|
64
|
+
}
|
|
65
|
+
return request;
|
|
66
|
+
}
|
|
67
|
+
function buildSanitizedQuery(query) {
|
|
68
|
+
if (!query)
|
|
69
|
+
return '';
|
|
70
|
+
const entries = splitQuery(query).filter(part => {
|
|
71
|
+
return !isQueryFlag(part, COMBINED_QUERY_FLAG) && !isQueryFlag(part, 'knighted-css');
|
|
72
|
+
});
|
|
73
|
+
return entries.length > 0 ? `?${entries.join('&')}` : '';
|
|
74
|
+
}
|
|
75
|
+
function splitQuery(query) {
|
|
76
|
+
const trimmed = query.startsWith('?') ? query.slice(1) : query;
|
|
77
|
+
if (!trimmed)
|
|
78
|
+
return [];
|
|
79
|
+
return trimmed.split('&').filter(Boolean);
|
|
80
|
+
}
|
|
81
|
+
function isQueryFlag(entry, flag) {
|
|
82
|
+
const [rawKey] = entry.split('=');
|
|
83
|
+
try {
|
|
84
|
+
return decodeURIComponent(rawKey) === flag;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return rawKey === flag;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function createCombinedModule(request, css) {
|
|
91
|
+
const requestLiteral = JSON.stringify(request);
|
|
92
|
+
const defaultExport = `const __knightedDefault =
|
|
93
|
+
typeof __knightedModule.default !== 'undefined'
|
|
94
|
+
? __knightedModule.default
|
|
95
|
+
: __knightedModule;`;
|
|
96
|
+
return [
|
|
97
|
+
`import * as __knightedModule from ${requestLiteral};`,
|
|
98
|
+
`export * from ${requestLiteral};`,
|
|
99
|
+
defaultExport,
|
|
100
|
+
'export default __knightedDefault;',
|
|
101
|
+
buildInjection(css),
|
|
102
|
+
].join('\n');
|
|
103
|
+
}
|
package/dist/cjs/loader.d.cts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import type { LoaderDefinitionFunction } from 'webpack';
|
|
1
|
+
import type { LoaderDefinitionFunction, PitchLoaderDefinitionFunction } from 'webpack';
|
|
2
2
|
import { type CssOptions } from './css.cjs';
|
|
3
|
+
export type KnightedCssCombinedModule<TModule> = TModule & {
|
|
4
|
+
knightedCss: string;
|
|
5
|
+
};
|
|
3
6
|
export interface KnightedCssLoaderOptions extends CssOptions {
|
|
4
7
|
}
|
|
5
8
|
declare const loader: LoaderDefinitionFunction<KnightedCssLoaderOptions>;
|
|
9
|
+
export declare const pitch: PitchLoaderDefinitionFunction<KnightedCssLoaderOptions>;
|
|
6
10
|
export default loader;
|
package/dist/loader.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import type { LoaderDefinitionFunction } from 'webpack';
|
|
1
|
+
import type { LoaderDefinitionFunction, PitchLoaderDefinitionFunction } from 'webpack';
|
|
2
2
|
import { type CssOptions } from './css.js';
|
|
3
|
+
export type KnightedCssCombinedModule<TModule> = TModule & {
|
|
4
|
+
knightedCss: string;
|
|
5
|
+
};
|
|
3
6
|
export interface KnightedCssLoaderOptions extends CssOptions {
|
|
4
7
|
}
|
|
5
8
|
declare const loader: LoaderDefinitionFunction<KnightedCssLoaderOptions>;
|
|
9
|
+
export declare const pitch: PitchLoaderDefinitionFunction<KnightedCssLoaderOptions>;
|
|
6
10
|
export default loader;
|
package/dist/loader.js
CHANGED
|
@@ -1,23 +1,99 @@
|
|
|
1
1
|
import { cssWithMeta } from './css.js';
|
|
2
2
|
const DEFAULT_EXPORT_NAME = 'knightedCss';
|
|
3
|
+
const COMBINED_QUERY_FLAG = 'combined';
|
|
3
4
|
const loader = async function loader(source) {
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
cwd: cssOptions.cwd ?? this.rootContext ?? process.cwd(),
|
|
9
|
-
};
|
|
10
|
-
const { css, files } = await cssWithMeta(this.resourcePath, normalizedOptions);
|
|
11
|
-
const uniqueFiles = new Set([this.resourcePath, ...files]);
|
|
12
|
-
for (const file of uniqueFiles) {
|
|
13
|
-
this.addDependency(file);
|
|
14
|
-
}
|
|
15
|
-
const input = typeof source === 'string' ? source : source.toString('utf8');
|
|
16
|
-
const injection = `\n\nexport const ${DEFAULT_EXPORT_NAME} = ${JSON.stringify(css)};\n`;
|
|
5
|
+
const cssOptions = resolveCssOptions(this);
|
|
6
|
+
const css = await extractCss(this, cssOptions);
|
|
7
|
+
const injection = buildInjection(css);
|
|
8
|
+
const input = toSourceString(source);
|
|
17
9
|
const isStyleModule = this.resourcePath.endsWith('.css.ts');
|
|
18
|
-
|
|
19
|
-
? `${injection}export default {};\n`
|
|
20
|
-
: `${input}${injection}`;
|
|
21
|
-
return output;
|
|
10
|
+
return isStyleModule ? `${injection}export default {};\n` : `${input}${injection}`;
|
|
22
11
|
};
|
|
12
|
+
export const pitch = function pitch() {
|
|
13
|
+
if (!hasCombinedQuery(this.resourceQuery)) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const request = buildProxyRequest(this);
|
|
17
|
+
const cssOptions = resolveCssOptions(this);
|
|
18
|
+
return extractCss(this, cssOptions).then(css => createCombinedModule(request, css));
|
|
19
|
+
};
|
|
20
|
+
loader.pitch = pitch;
|
|
23
21
|
export default loader;
|
|
22
|
+
function resolveCssOptions(ctx) {
|
|
23
|
+
const rawOptions = (typeof ctx.getOptions === 'function' ? ctx.getOptions() : {});
|
|
24
|
+
return {
|
|
25
|
+
...rawOptions,
|
|
26
|
+
cwd: rawOptions.cwd ?? ctx.rootContext ?? process.cwd(),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async function extractCss(ctx, options) {
|
|
30
|
+
const { css, files } = await cssWithMeta(ctx.resourcePath, options);
|
|
31
|
+
const uniqueFiles = new Set([ctx.resourcePath, ...files]);
|
|
32
|
+
for (const file of uniqueFiles) {
|
|
33
|
+
ctx.addDependency(file);
|
|
34
|
+
}
|
|
35
|
+
return css;
|
|
36
|
+
}
|
|
37
|
+
function toSourceString(source) {
|
|
38
|
+
return typeof source === 'string' ? source : source.toString('utf8');
|
|
39
|
+
}
|
|
40
|
+
function buildInjection(css) {
|
|
41
|
+
return `\n\nexport const ${DEFAULT_EXPORT_NAME} = ${JSON.stringify(css)};\n`;
|
|
42
|
+
}
|
|
43
|
+
function hasCombinedQuery(query) {
|
|
44
|
+
if (!query)
|
|
45
|
+
return false;
|
|
46
|
+
const trimmed = query.startsWith('?') ? query.slice(1) : query;
|
|
47
|
+
if (!trimmed)
|
|
48
|
+
return false;
|
|
49
|
+
return trimmed
|
|
50
|
+
.split('&')
|
|
51
|
+
.filter(Boolean)
|
|
52
|
+
.some(part => isQueryFlag(part, COMBINED_QUERY_FLAG));
|
|
53
|
+
}
|
|
54
|
+
function buildProxyRequest(ctx) {
|
|
55
|
+
const sanitizedQuery = buildSanitizedQuery(ctx.resourceQuery);
|
|
56
|
+
const request = `${ctx.resourcePath}${sanitizedQuery}`;
|
|
57
|
+
const context = ctx.context ?? ctx.rootContext ?? process.cwd();
|
|
58
|
+
if (ctx.utils && typeof ctx.utils.contextify === 'function') {
|
|
59
|
+
return ctx.utils.contextify(context, request);
|
|
60
|
+
}
|
|
61
|
+
return request;
|
|
62
|
+
}
|
|
63
|
+
function buildSanitizedQuery(query) {
|
|
64
|
+
if (!query)
|
|
65
|
+
return '';
|
|
66
|
+
const entries = splitQuery(query).filter(part => {
|
|
67
|
+
return !isQueryFlag(part, COMBINED_QUERY_FLAG) && !isQueryFlag(part, 'knighted-css');
|
|
68
|
+
});
|
|
69
|
+
return entries.length > 0 ? `?${entries.join('&')}` : '';
|
|
70
|
+
}
|
|
71
|
+
function splitQuery(query) {
|
|
72
|
+
const trimmed = query.startsWith('?') ? query.slice(1) : query;
|
|
73
|
+
if (!trimmed)
|
|
74
|
+
return [];
|
|
75
|
+
return trimmed.split('&').filter(Boolean);
|
|
76
|
+
}
|
|
77
|
+
function isQueryFlag(entry, flag) {
|
|
78
|
+
const [rawKey] = entry.split('=');
|
|
79
|
+
try {
|
|
80
|
+
return decodeURIComponent(rawKey) === flag;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return rawKey === flag;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function createCombinedModule(request, css) {
|
|
87
|
+
const requestLiteral = JSON.stringify(request);
|
|
88
|
+
const defaultExport = `const __knightedDefault =
|
|
89
|
+
typeof __knightedModule.default !== 'undefined'
|
|
90
|
+
? __knightedModule.default
|
|
91
|
+
: __knightedModule;`;
|
|
92
|
+
return [
|
|
93
|
+
`import * as __knightedModule from ${requestLiteral};`,
|
|
94
|
+
`export * from ${requestLiteral};`,
|
|
95
|
+
defaultExport,
|
|
96
|
+
'export default __knightedDefault;',
|
|
97
|
+
buildInjection(css),
|
|
98
|
+
].join('\n');
|
|
99
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knighted/css",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-rc.0",
|
|
4
4
|
"description": "A build-time utility that traverses JavaScript/TypeScript module dependency graphs to extract, compile, and optimize all imported CSS into a single, in-memory string.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/css.js",
|