@knighted/css 1.0.0-alpha.1 → 1.0.0-alpha.2

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/README.md CHANGED
@@ -100,7 +100,7 @@ export async function render(url: string) {
100
100
 
101
101
  ### Bundler loader (`?knighted-css` query)
102
102
 
103
- When using Webpack/Rspack, add the provided loader so importing a module with a specific query also returns the compiled stylesheet:
103
+ When using Webpack/Rspack, add the provided loader so importing a module with a specific query also returns the compiled stylesheet. Recommended DX: import your component as usual, and import the CSS separately via the query import.
104
104
 
105
105
  ```js
106
106
  // webpack.config.js
@@ -114,7 +114,6 @@ module.exports = {
114
114
  {
115
115
  loader: '@knighted/css/loader',
116
116
  options: {
117
- exportName: 'reactStyles', // optional (default: "knightedCss")
118
117
  lightningcss: { minify: true }, // all css() options supported
119
118
  },
120
119
  },
@@ -128,7 +127,8 @@ module.exports = {
128
127
  ```ts
129
128
  // lit wrapper
130
129
  import { LitElement, html, unsafeCSS } from 'lit'
131
- import { Button, reactStyles } from './button.tsx?knighted-css'
130
+ import { Button } from './button.tsx'
131
+ import { knightedCss as reactStyles } from './button.tsx?knighted-css'
132
132
 
133
133
  export class ButtonWrapper extends LitElement {
134
134
  static styles = [unsafeCSS(reactStyles)]
@@ -137,12 +137,40 @@ export class ButtonWrapper extends LitElement {
137
137
  }
138
138
  }
139
139
 
140
- // per-import override:
141
- // import { Button, cardCss } from './button.tsx?knighted-css&exportName=cardCss'
142
- // (exportName in the query wins over the loader option)
140
+ // Prefer import aliasing when you need a different local name:
141
+ // import { knightedCss as cardCss } from './button.tsx?knighted-css'
143
142
  ```
144
143
 
145
- The loader appends `export const reactStyles = "/* compiled css */"` to the module, so you can wire it directly into Lit’s `static styles` or any other runtime.
144
+ The loader appends `export const knightedCss = "/* compiled css */"` to the module when imported with `?knighted-css`. Keep your main module import separate to preserve its typing; use the query import only for the CSS string.
145
+
146
+ ### Custom resolver (enhanced-resolve example)
147
+
148
+ If your project uses aliases or nonstandard resolution, plug in a custom resolver. Here’s how to use [`enhanced-resolve`](https://github.com/webpack/enhanced-resolve):
149
+
150
+ ```ts
151
+ import { ResolverFactory } from 'enhanced-resolve'
152
+ import { css } from '@knighted/css'
153
+
154
+ const resolver = ResolverFactory.createResolver({
155
+ extensions: ['.ts', '.tsx', '.js'],
156
+ mainFiles: ['index'],
157
+ })
158
+
159
+ async function resolveWithEnhanced(id: string, cwd: string): Promise<string | undefined> {
160
+ return new Promise((resolve, reject) => {
161
+ resolver.resolve({}, cwd, id, {}, (err, result) => {
162
+ if (err) return reject(err)
163
+ resolve(result ?? undefined)
164
+ })
165
+ })
166
+ }
167
+
168
+ const styles = await css('./src/routes/page.tsx', {
169
+ resolver: (specifier, { cwd }) => resolveWithEnhanced(specifier, cwd),
170
+ })
171
+ ```
172
+
173
+ This keeps `@knighted/css` resolution in sync with your bundler’s alias/extension rules.
146
174
 
147
175
  ## Scripts
148
176
 
@@ -1,4 +1,4 @@
1
- import type { DependencyTreeOptions } from 'dependency-tree';
1
+ import type { Options as DependencyTreeOpts } from 'dependency-tree';
2
2
  import { type TransformOptions as LightningTransformOptions } from 'lightningcss';
3
3
  export declare const DEFAULT_EXTENSIONS: string[];
4
4
  type LightningCssConfig = boolean | Partial<Omit<LightningTransformOptions<never>, 'code'>>;
@@ -11,7 +11,7 @@ export interface CssOptions {
11
11
  cwd?: string;
12
12
  filter?: (filePath: string) => boolean;
13
13
  lightningcss?: LightningCssConfig;
14
- dependencyTree?: Partial<Omit<DependencyTreeOptions, 'filename' | 'directory'>>;
14
+ dependencyTree?: Partial<Omit<DependencyTreeOpts, 'filename' | 'directory'>>;
15
15
  resolver?: CssResolver;
16
16
  peerResolver?: PeerLoader;
17
17
  }
@@ -4,14 +4,7 @@ const css_js_1 = require("./css.cjs");
4
4
  const DEFAULT_EXPORT_NAME = 'knightedCss';
5
5
  const loader = async function loader(source) {
6
6
  const rawOptions = (typeof this.getOptions === 'function' ? this.getOptions() : {});
7
- const queryParams = typeof this.resourceQuery === 'string' && this.resourceQuery.startsWith('?')
8
- ? new URLSearchParams(this.resourceQuery.slice(1))
9
- : undefined;
10
- const queryExportName = queryParams?.get('exportName')?.trim();
11
- const isValidIdentifier = typeof queryExportName === 'string' &&
12
- /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(queryExportName);
13
- const { exportName = DEFAULT_EXPORT_NAME, ...cssOptions } = rawOptions;
14
- const resolvedExportName = isValidIdentifier ? queryExportName : exportName;
7
+ const cssOptions = rawOptions;
15
8
  const normalizedOptions = {
16
9
  ...cssOptions,
17
10
  cwd: cssOptions.cwd ?? this.rootContext ?? process.cwd(),
@@ -22,8 +15,11 @@ const loader = async function loader(source) {
22
15
  this.addDependency(file);
23
16
  }
24
17
  const input = typeof source === 'string' ? source : source.toString('utf8');
25
- const injection = `\n\nexport const ${resolvedExportName} = ${JSON.stringify(css)};\n`;
26
- const output = `${input}${injection}`;
18
+ const injection = `\n\nexport const ${DEFAULT_EXPORT_NAME} = ${JSON.stringify(css)};\n`;
19
+ const isStyleModule = this.resourcePath.endsWith('.css.ts');
20
+ const output = isStyleModule
21
+ ? `${injection}export default {};\n`
22
+ : `${input}${injection}`;
27
23
  return output;
28
24
  };
29
25
  exports.default = loader;
@@ -1,11 +1,6 @@
1
1
  import type { LoaderDefinitionFunction } from 'webpack';
2
2
  import { type CssOptions } from './css.cjs';
3
3
  export interface KnightedCssLoaderOptions extends CssOptions {
4
- /**
5
- * Named export that will contain the compiled CSS string.
6
- * Defaults to "knightedCss".
7
- */
8
- exportName?: string;
9
4
  }
10
5
  declare const loader: LoaderDefinitionFunction<KnightedCssLoaderOptions>;
11
6
  export default loader;
package/dist/css.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { DependencyTreeOptions } from 'dependency-tree';
1
+ import type { Options as DependencyTreeOpts } from 'dependency-tree';
2
2
  import { type TransformOptions as LightningTransformOptions } from 'lightningcss';
3
3
  export declare const DEFAULT_EXTENSIONS: string[];
4
4
  type LightningCssConfig = boolean | Partial<Omit<LightningTransformOptions<never>, 'code'>>;
@@ -11,7 +11,7 @@ export interface CssOptions {
11
11
  cwd?: string;
12
12
  filter?: (filePath: string) => boolean;
13
13
  lightningcss?: LightningCssConfig;
14
- dependencyTree?: Partial<Omit<DependencyTreeOptions, 'filename' | 'directory'>>;
14
+ dependencyTree?: Partial<Omit<DependencyTreeOpts, 'filename' | 'directory'>>;
15
15
  resolver?: CssResolver;
16
16
  peerResolver?: PeerLoader;
17
17
  }
@@ -0,0 +1,4 @@
1
+ /// <reference path="./loader-queries.d.ts" />
2
+
3
+ export * from '../css.js'
4
+ export { default } from '../css.js'
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Ambient declaration for loader query imports like "./file.js?knighted-css".
3
+ * The loader appends a named export `knightedCss` containing the compiled CSS.
4
+ */
5
+ declare module '*?knighted-css*' {
6
+ export const knightedCss: string
7
+ }
package/dist/loader.d.ts CHANGED
@@ -1,11 +1,4 @@
1
- import type { LoaderDefinitionFunction } from 'webpack';
2
- import { type CssOptions } from './css.js';
3
- export interface KnightedCssLoaderOptions extends CssOptions {
4
- /**
5
- * Named export that will contain the compiled CSS string.
6
- * Defaults to "knightedCss".
7
- */
8
- exportName?: string;
9
- }
10
- declare const loader: LoaderDefinitionFunction<KnightedCssLoaderOptions>;
11
- export default loader;
1
+ /// <reference path="./loader-queries.d.ts" />
2
+
3
+ export * from '../loader.js'
4
+ export { default } from '../loader.js'
package/dist/loader.js CHANGED
@@ -2,14 +2,7 @@ import { cssWithMeta } from './css.js';
2
2
  const DEFAULT_EXPORT_NAME = 'knightedCss';
3
3
  const loader = async function loader(source) {
4
4
  const rawOptions = (typeof this.getOptions === 'function' ? this.getOptions() : {});
5
- const queryParams = typeof this.resourceQuery === 'string' && this.resourceQuery.startsWith('?')
6
- ? new URLSearchParams(this.resourceQuery.slice(1))
7
- : undefined;
8
- const queryExportName = queryParams?.get('exportName')?.trim();
9
- const isValidIdentifier = typeof queryExportName === 'string' &&
10
- /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(queryExportName);
11
- const { exportName = DEFAULT_EXPORT_NAME, ...cssOptions } = rawOptions;
12
- const resolvedExportName = isValidIdentifier ? queryExportName : exportName;
5
+ const cssOptions = rawOptions;
13
6
  const normalizedOptions = {
14
7
  ...cssOptions,
15
8
  cwd: cssOptions.cwd ?? this.rootContext ?? process.cwd(),
@@ -20,8 +13,11 @@ const loader = async function loader(source) {
20
13
  this.addDependency(file);
21
14
  }
22
15
  const input = typeof source === 'string' ? source : source.toString('utf8');
23
- const injection = `\n\nexport const ${resolvedExportName} = ${JSON.stringify(css)};\n`;
24
- const output = `${input}${injection}`;
16
+ const injection = `\n\nexport const ${DEFAULT_EXPORT_NAME} = ${JSON.stringify(css)};\n`;
17
+ const isStyleModule = this.resourcePath.endsWith('.css.ts');
18
+ const output = isStyleModule
19
+ ? `${injection}export default {};\n`
20
+ : `${input}${injection}`;
25
21
  return output;
26
22
  };
27
23
  export default loader;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@knighted/css",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.2",
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",
7
- "types": "./dist/css.d.ts",
7
+ "types": "./dist/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
- "types": "./dist/css.d.ts",
10
+ "types": "./dist/index.d.ts",
11
11
  "import": "./dist/css.js",
12
12
  "require": "./dist/cjs/css.cjs"
13
13
  },
@@ -42,8 +42,16 @@
42
42
  ],
43
43
  "scripts": {
44
44
  "build": "duel",
45
+ "postbuild": "cp src/types/*.d.ts dist/",
45
46
  "check-types": "tsc --noEmit",
46
47
  "test": "c8 --reporter=text --reporter=text-summary --reporter=lcov --include \"src/**/*.ts\" tsx --test test/**/*.test.ts",
48
+ "build:fixture": "npx rspack --config test/fixtures/loader-rspack/rspack.config.js",
49
+ "preview:fixture": "npm run build:fixture && npx http-server test/fixtures/loader-rspack -p 4173",
50
+ "prebuild:fixture:playwright": "npm run build",
51
+ "build:fixture:playwright": "npx rspack --config test/fixtures/playwright/rspack.config.js",
52
+ "serve:fixture:playwright": "npx http-server test/fixtures/playwright/dist -p 4174",
53
+ "preview:fixture:playwright": "npm run build:fixture:playwright && npx http-server test/fixtures/playwright -p 4174",
54
+ "test:e2e": "npx playwright test",
47
55
  "prettier": "prettier --write .",
48
56
  "prettier:check": "prettier --check .",
49
57
  "lint": "oxlint src test",
@@ -51,7 +59,7 @@
51
59
  "prepare": "husky"
52
60
  },
53
61
  "dependencies": {
54
- "dependency-tree": "^9.0.0",
62
+ "dependency-tree": "^11.2.0",
55
63
  "lightningcss": "^1.30.2"
56
64
  },
57
65
  "peerDependencies": {
@@ -72,6 +80,8 @@
72
80
  },
73
81
  "devDependencies": {
74
82
  "@knighted/duel": "^2.1.6",
83
+ "@playwright/test": "^1.48.2",
84
+ "@rspack/cli": "^1.0.0",
75
85
  "@rspack/core": "^1.0.0",
76
86
  "@types/less": "^3.0.8",
77
87
  "@types/webpack": "^5.28.5",
@@ -79,6 +89,7 @@
79
89
  "@vanilla-extract/integration": "^8.0.6",
80
90
  "@vanilla-extract/recipes": "^0.5.7",
81
91
  "c8": "^10.1.2",
92
+ "http-server": "^14.1.1",
82
93
  "husky": "^9.1.7",
83
94
  "less": "^4.2.0",
84
95
  "lint-staged": "^16.2.7",