vite-plugin-qingkuai 1.0.9 → 1.0.10

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/index.cjs CHANGED
@@ -3,11 +3,13 @@
3
3
  var node_path = require('node:path');
4
4
  var node_fs = require('node:fs');
5
5
  var node_crypto = require('node:crypto');
6
- var sourcemapCodec = require('@jridgewell/sourcemap-codec');
7
6
  var compiler = require('qingkuai/compiler');
7
+ var linesAndColumns = require('lines-and-columns');
8
+ var sourcemapCodec = require('@jridgewell/sourcemap-codec');
8
9
  var postcss = require('postcss');
9
10
  var selectorParser = require('postcss-selector-parser');
10
11
  var vite = require('vite');
12
+ var sourceMapJs = require('source-map-js');
11
13
 
12
14
  function findFilesByName(dir, targetFileName, ignoreList) {
13
15
  const result = [];
@@ -26,23 +28,8 @@ function findFilesByName(dir, targetFileName, ignoreList) {
26
28
  return result;
27
29
  }
28
30
 
29
- function offsetSourceMap(mappings, sourceIndex, preLine, preColumn) {
30
- return sourcemapCodec.decode(mappings).map((line) => {
31
- return line.map((segment) => {
32
- if (segment.length === 1 || segment[1] !== sourceIndex) {
33
- return segment;
34
- }
35
- if (segment[2] === preLine) {
36
- segment[3] += preColumn;
37
- } else {
38
- segment[2] += preLine;
39
- }
40
- return segment;
41
- });
42
- });
43
- }
44
-
45
31
  async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
32
+ let error;
46
33
  const processor = postcss([
47
34
  {
48
35
  postcssPlugin: "postcss-attach-scope-qingkuai",
@@ -52,8 +39,34 @@ async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
52
39
  }
53
40
  rule.selector = selectorParser((selectors) => {
54
41
  selectors.each((selector) => {
42
+ const scopePseudoSelectors = selector.nodes.filter(
43
+ (node) => node.type === "pseudo" && node.value === ":scope"
44
+ );
45
+ if (scopePseudoSelectors.length) {
46
+ if (scopePseudoSelectors.length > 1) {
47
+ error = {
48
+ loc: scopePseudoSelectors[1].source?.start,
49
+ message: "Duplicate scope pseudo class selectors."
50
+ };
51
+ } else {
52
+ const fistScopePseudo = scopePseudoSelectors[0];
53
+ if (!fistScopePseudo.nodes[0]?.toString()) {
54
+ error = {
55
+ loc: fistScopePseudo?.source?.start,
56
+ message: "Must pass paramter for the :scope pseudo class selector."
57
+ };
58
+ }
59
+ if (fistScopePseudo.nodes.length > 1) {
60
+ error = {
61
+ loc: fistScopePseudo?.source?.start,
62
+ message: "The :scope pseudo class selector can accept at most one parameter."
63
+ };
64
+ }
65
+ fistScopePseudo.nodes[0] && (selector = fistScopePseudo.nodes[0]);
66
+ }
67
+ }
55
68
  const index = selector.nodes.findLastIndex(({ type }) => {
56
- return type === "class" || type === "tag" || type === "id" || type === "universal";
69
+ return type === "id" || type === "tag" || type === "class" || type === "universal" || type === "attribute";
57
70
  });
58
71
  if (index !== -1) {
59
72
  const lastNode = selector.nodes[index];
@@ -65,6 +78,7 @@ async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
65
78
  raws: {}
66
79
  })
67
80
  );
81
+ scopePseudoSelectors[0]?.replaceWith(...scopePseudoSelectors[0].nodes);
68
82
  }
69
83
  });
70
84
  }).processSync(rule.selector);
@@ -78,7 +92,26 @@ async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
78
92
  annotation: false
79
93
  }
80
94
  });
81
- return { code: ret.css, mappings: ret.map.toJSON().mappings };
95
+ return { error, code: ret.css, mappings: ret.map.toJSON().mappings };
96
+ }
97
+
98
+ function offsetSourceMap(mappings, sourceIndex, preLine, preColumn) {
99
+ return sourcemapCodec.decode(mappings).map((line) => {
100
+ return line.map((segment) => {
101
+ if (segment.length === 1 || segment[1] !== sourceIndex) {
102
+ return segment;
103
+ }
104
+ if (segment[2] === preLine) {
105
+ segment[3] += preColumn;
106
+ } else {
107
+ segment[2] += preLine;
108
+ }
109
+ return segment;
110
+ });
111
+ });
112
+ }
113
+ async function getOriginalPosition(map, line, column) {
114
+ return new sourceMapJs.SourceMapConsumer(map).originalPositionFor({ line, column });
82
115
  }
83
116
 
84
117
  function qingkuaiPlugin() {
@@ -119,6 +152,7 @@ function qingkuaiPlugin() {
119
152
  const qingkuaiConfig = getQingkuaiConfiguration(id);
120
153
  return node_path.join(node_path.dirname(importer), id + (qingkuaiConfig.resolveImportExtension ? ".qk" : ""));
121
154
  }
155
+ return id;
122
156
  },
123
157
  async load(id) {
124
158
  if (styleIdRE.test(id)) {
@@ -163,6 +197,30 @@ function qingkuaiPlugin() {
163
197
  style.loc.start.column - 1
164
198
  )
165
199
  );
200
+ if (attachScopeResult.error) {
201
+ if (!attachScopeResult.error.loc) {
202
+ this.error(attachScopeResult.error.message);
203
+ } else {
204
+ const preprocessedPosition = await getOriginalPosition(
205
+ assertedPreprocessMap,
206
+ attachScopeResult.error.loc.line,
207
+ attachScopeResult.error.loc.column
208
+ );
209
+ const preprocessedIndex = new linesAndColumns.LinesAndColumns(style.code).indexForLocation({
210
+ line: preprocessedPosition.line - 1,
211
+ column: preprocessedPosition.column
212
+ }) || 0;
213
+ const position = compileRes.inputDescriptor.positions[style.loc.start.index + preprocessedIndex];
214
+ this.error({
215
+ message: attachScopeResult.error.message,
216
+ loc: {
217
+ file: fileId,
218
+ line: position.line,
219
+ column: position.column
220
+ }
221
+ });
222
+ }
223
+ }
166
224
  return {
167
225
  code: attachScopeResult.code,
168
226
  map: {
@@ -192,64 +250,68 @@ function qingkuaiPlugin() {
192
250
  }
193
251
  return;
194
252
  }
195
- const compileRes = compiler.compile(src, {
196
- sourcemap,
197
- debug: isDev,
198
- hashId: compileResultCache.get(id)?.hashId || void 0,
199
- reserveTemplateComment: getReserveHtmlComments(qingkuaiConfig),
200
- componentName: compiler.util.kebab2Camel(node_path.basename(id, node_path.extname(id)), true)
201
- });
202
- compileRes.messages.forEach(({ type, value: warning }) => {
203
- if (type === "warning") {
204
- this.warn(warning.message);
253
+ try {
254
+ const compileRes = compiler.compile(src, {
255
+ sourcemap,
256
+ debug: isDev,
257
+ hashId: compileResultCache.get(id)?.hashId || void 0,
258
+ reserveTemplateComment: getReserveHtmlComments(qingkuaiConfig),
259
+ componentName: compiler.util.kebab2Camel(node_path.basename(id, node_path.extname(id)), true)
260
+ });
261
+ compileRes.messages.forEach(({ type, value: warning }) => {
262
+ if (type === "warning") {
263
+ this.warn(warning.message);
264
+ }
265
+ });
266
+ compileResultCache.set(id, compileRes);
267
+ const compiledCodeArr = [compileRes.code];
268
+ compileRes.inputDescriptor.styles.forEach((_, index) => {
269
+ compiledCodeArr.push(`import "virtual:[${index}]${id}.css?${Date.now()}"`);
270
+ });
271
+ const baseMap = {
272
+ version: 3,
273
+ sources: [id],
274
+ sourcesContent: [src]
275
+ };
276
+ const compiledCode = compiledCodeArr.join("\n");
277
+ if (!compileRes.inputDescriptor.script.isTS) {
278
+ if (!sourcemap) {
279
+ return compiledCode;
280
+ }
281
+ return {
282
+ code: compiledCode,
283
+ map: Object.assign(baseMap, {
284
+ mappings: compileRes.mappings
285
+ })
286
+ };
205
287
  }
206
- });
207
- compileResultCache.set(id, compileRes);
208
- const compiledCodeArr = [compileRes.code];
209
- compileRes.inputDescriptor.styles.forEach((_, index) => {
210
- compiledCodeArr.push(`import "virtual:[${index}]${id}.css?${Date.now()}"`);
211
- });
212
- const baseMap = {
213
- version: 3,
214
- sources: [id],
215
- sourcesContent: [src]
216
- };
217
- const compiledCode = compiledCodeArr.join("\n");
218
- if (!compileRes.inputDescriptor.script.isTS) {
288
+ const esBuildCompileRes = await vite.transformWithEsbuild(
289
+ compiledCode,
290
+ id,
291
+ {
292
+ sourcemap,
293
+ loader: "ts",
294
+ target: "esnext"
295
+ },
296
+ sourcemap ? {
297
+ version: 3,
298
+ sources: [id],
299
+ sourcesContent: [src],
300
+ mappings: compileRes.mappings
301
+ } : void 0
302
+ );
219
303
  if (!sourcemap) {
220
- return compiledCode;
304
+ return esBuildCompileRes.code;
221
305
  }
222
306
  return {
223
- code: compiledCode,
307
+ code: esBuildCompileRes.code,
224
308
  map: Object.assign(baseMap, {
225
- mappings: compileRes.mappings
309
+ mappings: esBuildCompileRes.map.mappings
226
310
  })
227
311
  };
312
+ } catch (err) {
313
+ err.pos = err.loc.start.index, this.error(err);
228
314
  }
229
- const esBuildCompileRes = await vite.transformWithEsbuild(
230
- compiledCode,
231
- id,
232
- {
233
- sourcemap,
234
- loader: "ts",
235
- target: "esnext"
236
- },
237
- sourcemap ? {
238
- version: 3,
239
- sources: [id],
240
- sourcesContent: [src],
241
- mappings: compileRes.mappings
242
- } : void 0
243
- );
244
- if (!sourcemap) {
245
- return esBuildCompileRes.code;
246
- }
247
- return {
248
- code: esBuildCompileRes.code,
249
- map: Object.assign(baseMap, {
250
- mappings: esBuildCompileRes.map.mappings
251
- })
252
- };
253
315
  }
254
316
  };
255
317
  function getQingkuaiConfiguration(id) {
package/dist/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import { join, basename, extname, dirname } from 'node:path';
2
2
  import { readdirSync, existsSync, readFileSync } from 'node:fs';
3
3
  import { randomBytes } from 'node:crypto';
4
- import { decode, encode } from '@jridgewell/sourcemap-codec';
5
4
  import { compile, util } from 'qingkuai/compiler';
5
+ import { LinesAndColumns } from 'lines-and-columns';
6
+ import { decode, encode } from '@jridgewell/sourcemap-codec';
6
7
  import postcss from 'postcss';
7
8
  import selectorParser from 'postcss-selector-parser';
8
9
  import { transformWithEsbuild, preprocessCSS } from 'vite';
10
+ import { SourceMapConsumer } from 'source-map-js';
9
11
 
10
12
  function findFilesByName(dir, targetFileName, ignoreList) {
11
13
  const result = [];
@@ -24,23 +26,8 @@ function findFilesByName(dir, targetFileName, ignoreList) {
24
26
  return result;
25
27
  }
26
28
 
27
- function offsetSourceMap(mappings, sourceIndex, preLine, preColumn) {
28
- return decode(mappings).map((line) => {
29
- return line.map((segment) => {
30
- if (segment.length === 1 || segment[1] !== sourceIndex) {
31
- return segment;
32
- }
33
- if (segment[2] === preLine) {
34
- segment[3] += preColumn;
35
- } else {
36
- segment[2] += preLine;
37
- }
38
- return segment;
39
- });
40
- });
41
- }
42
-
43
29
  async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
30
+ let error;
44
31
  const processor = postcss([
45
32
  {
46
33
  postcssPlugin: "postcss-attach-scope-qingkuai",
@@ -50,8 +37,34 @@ async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
50
37
  }
51
38
  rule.selector = selectorParser((selectors) => {
52
39
  selectors.each((selector) => {
40
+ const scopePseudoSelectors = selector.nodes.filter(
41
+ (node) => node.type === "pseudo" && node.value === ":scope"
42
+ );
43
+ if (scopePseudoSelectors.length) {
44
+ if (scopePseudoSelectors.length > 1) {
45
+ error = {
46
+ loc: scopePseudoSelectors[1].source?.start,
47
+ message: "Duplicate scope pseudo class selectors."
48
+ };
49
+ } else {
50
+ const fistScopePseudo = scopePseudoSelectors[0];
51
+ if (!fistScopePseudo.nodes[0]?.toString()) {
52
+ error = {
53
+ loc: fistScopePseudo?.source?.start,
54
+ message: "Must pass paramter for the :scope pseudo class selector."
55
+ };
56
+ }
57
+ if (fistScopePseudo.nodes.length > 1) {
58
+ error = {
59
+ loc: fistScopePseudo?.source?.start,
60
+ message: "The :scope pseudo class selector can accept at most one parameter."
61
+ };
62
+ }
63
+ fistScopePseudo.nodes[0] && (selector = fistScopePseudo.nodes[0]);
64
+ }
65
+ }
53
66
  const index = selector.nodes.findLastIndex(({ type }) => {
54
- return type === "class" || type === "tag" || type === "id" || type === "universal";
67
+ return type === "id" || type === "tag" || type === "class" || type === "universal" || type === "attribute";
55
68
  });
56
69
  if (index !== -1) {
57
70
  const lastNode = selector.nodes[index];
@@ -63,6 +76,7 @@ async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
63
76
  raws: {}
64
77
  })
65
78
  );
79
+ scopePseudoSelectors[0]?.replaceWith(...scopePseudoSelectors[0].nodes);
66
80
  }
67
81
  });
68
82
  }).processSync(rule.selector);
@@ -76,7 +90,26 @@ async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
76
90
  annotation: false
77
91
  }
78
92
  });
79
- return { code: ret.css, mappings: ret.map.toJSON().mappings };
93
+ return { error, code: ret.css, mappings: ret.map.toJSON().mappings };
94
+ }
95
+
96
+ function offsetSourceMap(mappings, sourceIndex, preLine, preColumn) {
97
+ return decode(mappings).map((line) => {
98
+ return line.map((segment) => {
99
+ if (segment.length === 1 || segment[1] !== sourceIndex) {
100
+ return segment;
101
+ }
102
+ if (segment[2] === preLine) {
103
+ segment[3] += preColumn;
104
+ } else {
105
+ segment[2] += preLine;
106
+ }
107
+ return segment;
108
+ });
109
+ });
110
+ }
111
+ async function getOriginalPosition(map, line, column) {
112
+ return new SourceMapConsumer(map).originalPositionFor({ line, column });
80
113
  }
81
114
 
82
115
  function qingkuaiPlugin() {
@@ -117,6 +150,7 @@ function qingkuaiPlugin() {
117
150
  const qingkuaiConfig = getQingkuaiConfiguration(id);
118
151
  return join(dirname(importer), id + (qingkuaiConfig.resolveImportExtension ? ".qk" : ""));
119
152
  }
153
+ return id;
120
154
  },
121
155
  async load(id) {
122
156
  if (styleIdRE.test(id)) {
@@ -161,6 +195,30 @@ function qingkuaiPlugin() {
161
195
  style.loc.start.column - 1
162
196
  )
163
197
  );
198
+ if (attachScopeResult.error) {
199
+ if (!attachScopeResult.error.loc) {
200
+ this.error(attachScopeResult.error.message);
201
+ } else {
202
+ const preprocessedPosition = await getOriginalPosition(
203
+ assertedPreprocessMap,
204
+ attachScopeResult.error.loc.line,
205
+ attachScopeResult.error.loc.column
206
+ );
207
+ const preprocessedIndex = new LinesAndColumns(style.code).indexForLocation({
208
+ line: preprocessedPosition.line - 1,
209
+ column: preprocessedPosition.column
210
+ }) || 0;
211
+ const position = compileRes.inputDescriptor.positions[style.loc.start.index + preprocessedIndex];
212
+ this.error({
213
+ message: attachScopeResult.error.message,
214
+ loc: {
215
+ file: fileId,
216
+ line: position.line,
217
+ column: position.column
218
+ }
219
+ });
220
+ }
221
+ }
164
222
  return {
165
223
  code: attachScopeResult.code,
166
224
  map: {
@@ -190,64 +248,68 @@ function qingkuaiPlugin() {
190
248
  }
191
249
  return;
192
250
  }
193
- const compileRes = compile(src, {
194
- sourcemap,
195
- debug: isDev,
196
- hashId: compileResultCache.get(id)?.hashId || void 0,
197
- reserveTemplateComment: getReserveHtmlComments(qingkuaiConfig),
198
- componentName: util.kebab2Camel(basename(id, extname(id)), true)
199
- });
200
- compileRes.messages.forEach(({ type, value: warning }) => {
201
- if (type === "warning") {
202
- this.warn(warning.message);
251
+ try {
252
+ const compileRes = compile(src, {
253
+ sourcemap,
254
+ debug: isDev,
255
+ hashId: compileResultCache.get(id)?.hashId || void 0,
256
+ reserveTemplateComment: getReserveHtmlComments(qingkuaiConfig),
257
+ componentName: util.kebab2Camel(basename(id, extname(id)), true)
258
+ });
259
+ compileRes.messages.forEach(({ type, value: warning }) => {
260
+ if (type === "warning") {
261
+ this.warn(warning.message);
262
+ }
263
+ });
264
+ compileResultCache.set(id, compileRes);
265
+ const compiledCodeArr = [compileRes.code];
266
+ compileRes.inputDescriptor.styles.forEach((_, index) => {
267
+ compiledCodeArr.push(`import "virtual:[${index}]${id}.css?${Date.now()}"`);
268
+ });
269
+ const baseMap = {
270
+ version: 3,
271
+ sources: [id],
272
+ sourcesContent: [src]
273
+ };
274
+ const compiledCode = compiledCodeArr.join("\n");
275
+ if (!compileRes.inputDescriptor.script.isTS) {
276
+ if (!sourcemap) {
277
+ return compiledCode;
278
+ }
279
+ return {
280
+ code: compiledCode,
281
+ map: Object.assign(baseMap, {
282
+ mappings: compileRes.mappings
283
+ })
284
+ };
203
285
  }
204
- });
205
- compileResultCache.set(id, compileRes);
206
- const compiledCodeArr = [compileRes.code];
207
- compileRes.inputDescriptor.styles.forEach((_, index) => {
208
- compiledCodeArr.push(`import "virtual:[${index}]${id}.css?${Date.now()}"`);
209
- });
210
- const baseMap = {
211
- version: 3,
212
- sources: [id],
213
- sourcesContent: [src]
214
- };
215
- const compiledCode = compiledCodeArr.join("\n");
216
- if (!compileRes.inputDescriptor.script.isTS) {
286
+ const esBuildCompileRes = await transformWithEsbuild(
287
+ compiledCode,
288
+ id,
289
+ {
290
+ sourcemap,
291
+ loader: "ts",
292
+ target: "esnext"
293
+ },
294
+ sourcemap ? {
295
+ version: 3,
296
+ sources: [id],
297
+ sourcesContent: [src],
298
+ mappings: compileRes.mappings
299
+ } : void 0
300
+ );
217
301
  if (!sourcemap) {
218
- return compiledCode;
302
+ return esBuildCompileRes.code;
219
303
  }
220
304
  return {
221
- code: compiledCode,
305
+ code: esBuildCompileRes.code,
222
306
  map: Object.assign(baseMap, {
223
- mappings: compileRes.mappings
307
+ mappings: esBuildCompileRes.map.mappings
224
308
  })
225
309
  };
310
+ } catch (err) {
311
+ err.pos = err.loc.start.index, this.error(err);
226
312
  }
227
- const esBuildCompileRes = await transformWithEsbuild(
228
- compiledCode,
229
- id,
230
- {
231
- sourcemap,
232
- loader: "ts",
233
- target: "esnext"
234
- },
235
- sourcemap ? {
236
- version: 3,
237
- sources: [id],
238
- sourcesContent: [src],
239
- mappings: compileRes.mappings
240
- } : void 0
241
- );
242
- if (!sourcemap) {
243
- return esBuildCompileRes.code;
244
- }
245
- return {
246
- code: esBuildCompileRes.code,
247
- map: Object.assign(baseMap, {
248
- mappings: esBuildCompileRes.map.mappings
249
- })
250
- };
251
313
  }
252
314
  };
253
315
  function getQingkuaiConfiguration(id) {
@@ -1,5 +1,6 @@
1
- import type { SourceMap } from "./types";
1
+ import type { PostcssPluginError, SourceMap } from "./types";
2
2
  export declare function attachScopeForStyleSelectors(code: string, hash: string, sourceFile: string, map: SourceMap | undefined): Promise<{
3
+ error: PostcssPluginError | undefined;
3
4
  code: string;
4
5
  mappings: string;
5
6
  }>;
@@ -1,2 +1,3 @@
1
1
  import type { SourceMapMappings } from "@jridgewell/sourcemap-codec";
2
2
  export declare function offsetSourceMap(mappings: string, sourceIndex: number, preLine: number, preColumn: number): SourceMapMappings;
3
+ export declare function getOriginalPosition(map: any, line: number, column: number): Promise<import("source-map-js").MappedPosition>;
@@ -16,3 +16,10 @@ export type QingkuaiConfiguration = Partial<{
16
16
  convenientDerivedDeclaration: boolean;
17
17
  reserveHtmlComments: "all" | "never" | "development" | "production";
18
18
  }>;
19
+ export interface PostcssPluginError {
20
+ message: string;
21
+ loc?: {
22
+ line: number;
23
+ column: number;
24
+ };
25
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "vite-plugin-qingkuai",
3
3
  "author": "mlgq",
4
4
  "license": "MIT",
5
- "version": "1.0.9",
5
+ "version": "1.0.10",
6
6
  "type": "module",
7
7
  "keywords": [
8
8
  "vite",
@@ -25,7 +25,7 @@
25
25
  "@types/fs-extra": "^11.0.4",
26
26
  "@types/node": "^22.13.14",
27
27
  "fs-extra": "^11.3.0",
28
- "qingkuai": "^1.0.41",
28
+ "qingkuai": "^1.0.42",
29
29
  "rimraf": "^6.0.1",
30
30
  "rollup": "^4.38.0",
31
31
  "rollup-plugin-dts": "^6.2.1",
@@ -33,12 +33,14 @@
33
33
  "vite": "^6.2.4"
34
34
  },
35
35
  "peerDependencies": {
36
- "qingkuai": "^1.0.41",
36
+ "qingkuai": "^1.0.42",
37
37
  "vite": "^6.2.4"
38
38
  },
39
39
  "dependencies": {
40
40
  "@jridgewell/sourcemap-codec": "^1.5.0",
41
+ "lines-and-columns": "^2.0.4",
41
42
  "postcss": "^8.5.3",
42
- "postcss-selector-parser": "^7.1.0"
43
+ "postcss-selector-parser": "^7.1.0",
44
+ "source-map-js": "^1.2.1"
43
45
  }
44
46
  }