vite-plugin-qingkuai 1.0.28 → 1.0.30

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/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ * text=auto eol=lf
package/dist/index.cjs CHANGED
@@ -11,6 +11,7 @@ var postcss = require('postcss');
11
11
  var selectorParser = require('postcss-selector-parser');
12
12
  var compiler = require('qingkuai/compiler');
13
13
  var sourceMapJs = require('source-map-js');
14
+ var config = require('qingkuai-language-service/config');
14
15
 
15
16
  function _interopNamespaceDefault(e) {
16
17
  var n = Object.create(null);
@@ -31,6 +32,13 @@ function _interopNamespaceDefault(e) {
31
32
 
32
33
  var vite__namespace = /*#__PURE__*/_interopNamespaceDefault(vite);
33
34
 
35
+ function isNumber(v) {
36
+ return typeof v === "number";
37
+ }
38
+ function isUndefined(v) {
39
+ return void 0 === v;
40
+ }
41
+
34
42
  async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
35
43
  let error;
36
44
  const processedRules = /* @__PURE__ */ new WeakSet();
@@ -104,29 +112,6 @@ const globalStyle = "\n" + compiler.util.formatSourceCode(
104
112
  ).replace(/^/gm, " ") + "\n";
105
113
  const VIRTUAL_STYLE_ID_RE = /^virtual:\[\d+\].*?\.qk\.(css|s[ac]ss|less|stylus|postcss)\?\d{13}$/;
106
114
 
107
- function isNumber(v) {
108
- return typeof v === "number";
109
- }
110
- function isUndefined(v) {
111
- return void 0 === v;
112
- }
113
- function findFilesByName(dir, targetFileName, ignoreList) {
114
- const result = [];
115
- const entries = nodeFs.readdirSync(dir, { withFileTypes: true });
116
- for (const entry of entries) {
117
- if (ignoreList.has(entry.name)) {
118
- continue;
119
- }
120
- const fullPath = nodePath.join(dir, entry.name);
121
- if (entry.name === targetFileName) {
122
- result.push(fullPath);
123
- } else if (entry.isDirectory()) {
124
- result.push(...findFilesByName(fullPath, targetFileName, ignoreList));
125
- }
126
- }
127
- return result;
128
- }
129
-
130
115
  function offsetSourceMap(sourceIndices, mappings, preLine, preColumn) {
131
116
  const indices = new Set(sourceIndices);
132
117
  return sourcemapCodec.decode(mappings).map((line) => {
@@ -152,8 +137,29 @@ function qingkuai(options = {}) {
152
137
  let sourcemap;
153
138
  let cssSourcemap;
154
139
  let viteConfig;
140
+ const reportedConfigMessages = /* @__PURE__ */ new Set();
155
141
  const compileResultCache = /* @__PURE__ */ new Map();
156
- const qingkuaiConfigurations = /* @__PURE__ */ new Map();
142
+ const configResolver = config.createConfigResolver(
143
+ {
144
+ read: (filePath) => {
145
+ return nodeFs.readFileSync(filePath, "utf-8");
146
+ },
147
+ exist: (filePath) => {
148
+ return nodeFs.existsSync(filePath);
149
+ }
150
+ },
151
+ {
152
+ dir: (filePath) => {
153
+ return nodePath.resolve(nodePath.dirname(filePath));
154
+ },
155
+ resolve: (...segments) => {
156
+ return nodePath.resolve(...segments);
157
+ },
158
+ ext: nodePath.extname,
159
+ base: nodePath.basename,
160
+ relative: nodePath.relative
161
+ }
162
+ );
157
163
  if (isUndefined(options.maxScheduleDepth)) {
158
164
  options.maxScheduleDepth = 300;
159
165
  }
@@ -180,7 +186,6 @@ function qingkuai(options = {}) {
180
186
  cssSourcemap = true;
181
187
  sourcemap = config.build.sourcemap !== false;
182
188
  }
183
- loadAllQingkuaiConfigurations(config.root);
184
189
  },
185
190
  transformIndexHtml(html) {
186
191
  return {
@@ -199,7 +204,7 @@ function qingkuai(options = {}) {
199
204
  return id;
200
205
  }
201
206
  if (importer?.endsWith(".qk") && !nodePath.extname(id)) {
202
- const qingkuaiConfig = getQingkuaiConfiguration(id);
207
+ const qingkuaiConfig = getQingkuaiConfig(importer);
203
208
  return nodePath.join(
204
209
  nodePath.dirname(importer),
205
210
  id + (qingkuaiConfig.resolveImportExtension ? ".qk" : "")
@@ -463,75 +468,65 @@ Caused by: "${fileId}".`;
463
468
  }
464
469
  }
465
470
  };
466
- function getQingkuaiConfiguration(id) {
467
- let config = {
468
- interpretiveComments: true,
469
- resolveImportExtension: true,
470
- preserveHtmlComments: "development"
471
- };
472
- while (true) {
473
- const dir = nodePath.dirname(id);
474
- if (dir === id) {
475
- break;
476
- }
477
- const got = qingkuaiConfigurations.get(id = dir);
478
- if (got) {
479
- config = got;
480
- break;
471
+ function getQingkuaiConfig(filePath) {
472
+ return configResolver.resolve(filePath, (configPath, message) => {
473
+ reportConfigMessage(viteConfig.logger, configPath, message);
474
+ });
475
+ }
476
+ function reportConfigMessage(logger, filePath, message) {
477
+ const key = `${filePath}\0${message.value}`;
478
+ if (reportedConfigMessages.has(key)) {
479
+ return;
480
+ }
481
+ reportedConfigMessages.add(key);
482
+ const reason = message.kind === config.ConfigParsingMessageKind.Error ? "Failed to parse configuration file" : "Configuration file";
483
+ logger.warn(`[qingkuai] ${reason} ${filePath}: ${message.value}`);
484
+ }
485
+ function forgetConfigMessages(configPath) {
486
+ const prefix = `${configPath}\0`;
487
+ for (const key of reportedConfigMessages) {
488
+ if (key.startsWith(prefix)) {
489
+ reportedConfigMessages.delete(key);
481
490
  }
482
491
  }
483
- return config;
484
492
  }
485
493
  function createQingkuaiConfigurationWatcher(server) {
486
494
  const watcher = server.watcher;
487
- const isQingkuaiConfig = (filePath) => {
488
- return nodePath.basename(filePath) === ".qingkuairc" && !filePath.includes(`${nodePath.sep}node_modules${nodePath.sep}`);
489
- };
490
- watcher.on("unlink", (filePath) => {
491
- if (isQingkuaiConfig(filePath)) {
492
- qingkuaiConfigurations.delete(nodePath.dirname(filePath));
493
- }
494
- });
495
- watcher.on("change", (filePath) => {
496
- if (isQingkuaiConfig(filePath)) {
497
- recordQingkuaiConfiguration(filePath);
498
- }
499
- });
500
- watcher.on("add", (filePath) => {
501
- if (isQingkuaiConfig(filePath)) {
502
- recordQingkuaiConfiguration(filePath);
495
+ const handleFileChange = (filePath) => {
496
+ for (const configPath of configResolver.removeCacheByPath(filePath)) {
497
+ forgetConfigMessages(configPath);
498
+ configResolver.resolve(configPath, (path, message) => {
499
+ reportConfigMessage(server.config.logger, path, message);
500
+ });
503
501
  }
504
- });
505
- }
506
- function loadAllQingkuaiConfigurations(workspaceDir) {
507
- findFilesByName(workspaceDir, ".qingkuairc", /* @__PURE__ */ new Set(["node_modules"])).forEach((fileName) => {
508
- recordQingkuaiConfiguration(fileName);
509
- });
510
- }
511
- function recordQingkuaiConfiguration(fileName) {
512
- try {
513
- qingkuaiConfigurations.set(nodePath.dirname(fileName), JSON.parse(nodeFs.readFileSync(fileName, "utf-8")));
514
- } catch {
515
- }
502
+ };
503
+ watcher.on("change", handleFileChange);
504
+ watcher.on("add", handleFileChange);
505
+ watcher.on("unlink", handleFileChange);
516
506
  }
517
507
  function getCompileOptions(id) {
518
- const qingkuaiConfig = getQingkuaiConfiguration(id);
508
+ const qingkuaiConfig = getQingkuaiConfig(id);
519
509
  const ret = {
520
510
  interpretiveComments: isUndefined(qingkuaiConfig.interpretiveComments) ? isDev : !!qingkuaiConfig.interpretiveComments,
521
511
  allowConstReactive: qingkuaiConfig.allowConstReactive !== false,
522
512
  requireReactivityMark: qingkuaiConfig.requireReactivityMark === true,
523
- reactivityMode: qingkuaiConfig.reactivityMode === "shallow" ? "shallow" : "reactive"
513
+ reactivityMode: qingkuaiConfig.reactivityMode === "shallow" ? compiler.ReactivityMode.Shallow : compiler.ReactivityMode.Reactive
524
514
  };
525
515
  switch (qingkuaiConfig.whitespace) {
526
- case "trim":
527
- case "collapse":
528
- case "preserve":
529
- case "trim-collapse": {
530
- ret.whitespace = qingkuaiConfig.whitespace;
516
+ case "trim": {
517
+ ret.whitespace = compiler.WhitespaceMode.Trim;
518
+ break;
519
+ }
520
+ case "collapse": {
521
+ ret.whitespace = compiler.WhitespaceMode.Collapse;
522
+ break;
523
+ }
524
+ case "preserve": {
525
+ ret.whitespace = compiler.WhitespaceMode.Preserve;
531
526
  break;
532
527
  }
533
528
  default: {
534
- ret.whitespace = "trim-collapse";
529
+ ret.whitespace = compiler.WhitespaceMode.TrimCollapse;
535
530
  break;
536
531
  }
537
532
  }
package/dist/index.js CHANGED
@@ -7,8 +7,16 @@ import { LinesAndColumns } from 'lines-and-columns';
7
7
  import { decode, encode } from '@jridgewell/sourcemap-codec';
8
8
  import postcss from 'postcss';
9
9
  import selectorParser from 'postcss-selector-parser';
10
- import { util, compile, isCompileError } from 'qingkuai/compiler';
10
+ import { util, compile, isCompileError, ReactivityMode, WhitespaceMode } from 'qingkuai/compiler';
11
11
  import { SourceMapConsumer } from 'source-map-js';
12
+ import { createConfigResolver, ConfigParsingMessageKind } from 'qingkuai-language-service/config';
13
+
14
+ function isNumber(v) {
15
+ return typeof v === "number";
16
+ }
17
+ function isUndefined(v) {
18
+ return void 0 === v;
19
+ }
12
20
 
13
21
  async function attachScopeForStyleSelectors(code, hash, sourceFile, map) {
14
22
  let error;
@@ -83,29 +91,6 @@ const globalStyle = "\n" + util.formatSourceCode(
83
91
  ).replace(/^/gm, " ") + "\n";
84
92
  const VIRTUAL_STYLE_ID_RE = /^virtual:\[\d+\].*?\.qk\.(css|s[ac]ss|less|stylus|postcss)\?\d{13}$/;
85
93
 
86
- function isNumber(v) {
87
- return typeof v === "number";
88
- }
89
- function isUndefined(v) {
90
- return void 0 === v;
91
- }
92
- function findFilesByName(dir, targetFileName, ignoreList) {
93
- const result = [];
94
- const entries = nodeFs.readdirSync(dir, { withFileTypes: true });
95
- for (const entry of entries) {
96
- if (ignoreList.has(entry.name)) {
97
- continue;
98
- }
99
- const fullPath = nodePath.join(dir, entry.name);
100
- if (entry.name === targetFileName) {
101
- result.push(fullPath);
102
- } else if (entry.isDirectory()) {
103
- result.push(...findFilesByName(fullPath, targetFileName, ignoreList));
104
- }
105
- }
106
- return result;
107
- }
108
-
109
94
  function offsetSourceMap(sourceIndices, mappings, preLine, preColumn) {
110
95
  const indices = new Set(sourceIndices);
111
96
  return decode(mappings).map((line) => {
@@ -131,8 +116,29 @@ function qingkuai(options = {}) {
131
116
  let sourcemap;
132
117
  let cssSourcemap;
133
118
  let viteConfig;
119
+ const reportedConfigMessages = /* @__PURE__ */ new Set();
134
120
  const compileResultCache = /* @__PURE__ */ new Map();
135
- const qingkuaiConfigurations = /* @__PURE__ */ new Map();
121
+ const configResolver = createConfigResolver(
122
+ {
123
+ read: (filePath) => {
124
+ return nodeFs.readFileSync(filePath, "utf-8");
125
+ },
126
+ exist: (filePath) => {
127
+ return nodeFs.existsSync(filePath);
128
+ }
129
+ },
130
+ {
131
+ dir: (filePath) => {
132
+ return nodePath.resolve(nodePath.dirname(filePath));
133
+ },
134
+ resolve: (...segments) => {
135
+ return nodePath.resolve(...segments);
136
+ },
137
+ ext: nodePath.extname,
138
+ base: nodePath.basename,
139
+ relative: nodePath.relative
140
+ }
141
+ );
136
142
  if (isUndefined(options.maxScheduleDepth)) {
137
143
  options.maxScheduleDepth = 300;
138
144
  }
@@ -159,7 +165,6 @@ function qingkuai(options = {}) {
159
165
  cssSourcemap = true;
160
166
  sourcemap = config.build.sourcemap !== false;
161
167
  }
162
- loadAllQingkuaiConfigurations(config.root);
163
168
  },
164
169
  transformIndexHtml(html) {
165
170
  return {
@@ -178,7 +183,7 @@ function qingkuai(options = {}) {
178
183
  return id;
179
184
  }
180
185
  if (importer?.endsWith(".qk") && !nodePath.extname(id)) {
181
- const qingkuaiConfig = getQingkuaiConfiguration(id);
186
+ const qingkuaiConfig = getQingkuaiConfig(importer);
182
187
  return nodePath.join(
183
188
  nodePath.dirname(importer),
184
189
  id + (qingkuaiConfig.resolveImportExtension ? ".qk" : "")
@@ -442,75 +447,65 @@ Caused by: "${fileId}".`;
442
447
  }
443
448
  }
444
449
  };
445
- function getQingkuaiConfiguration(id) {
446
- let config = {
447
- interpretiveComments: true,
448
- resolveImportExtension: true,
449
- preserveHtmlComments: "development"
450
- };
451
- while (true) {
452
- const dir = nodePath.dirname(id);
453
- if (dir === id) {
454
- break;
455
- }
456
- const got = qingkuaiConfigurations.get(id = dir);
457
- if (got) {
458
- config = got;
459
- break;
450
+ function getQingkuaiConfig(filePath) {
451
+ return configResolver.resolve(filePath, (configPath, message) => {
452
+ reportConfigMessage(viteConfig.logger, configPath, message);
453
+ });
454
+ }
455
+ function reportConfigMessage(logger, filePath, message) {
456
+ const key = `${filePath}\0${message.value}`;
457
+ if (reportedConfigMessages.has(key)) {
458
+ return;
459
+ }
460
+ reportedConfigMessages.add(key);
461
+ const reason = message.kind === ConfigParsingMessageKind.Error ? "Failed to parse configuration file" : "Configuration file";
462
+ logger.warn(`[qingkuai] ${reason} ${filePath}: ${message.value}`);
463
+ }
464
+ function forgetConfigMessages(configPath) {
465
+ const prefix = `${configPath}\0`;
466
+ for (const key of reportedConfigMessages) {
467
+ if (key.startsWith(prefix)) {
468
+ reportedConfigMessages.delete(key);
460
469
  }
461
470
  }
462
- return config;
463
471
  }
464
472
  function createQingkuaiConfigurationWatcher(server) {
465
473
  const watcher = server.watcher;
466
- const isQingkuaiConfig = (filePath) => {
467
- return nodePath.basename(filePath) === ".qingkuairc" && !filePath.includes(`${nodePath.sep}node_modules${nodePath.sep}`);
468
- };
469
- watcher.on("unlink", (filePath) => {
470
- if (isQingkuaiConfig(filePath)) {
471
- qingkuaiConfigurations.delete(nodePath.dirname(filePath));
472
- }
473
- });
474
- watcher.on("change", (filePath) => {
475
- if (isQingkuaiConfig(filePath)) {
476
- recordQingkuaiConfiguration(filePath);
477
- }
478
- });
479
- watcher.on("add", (filePath) => {
480
- if (isQingkuaiConfig(filePath)) {
481
- recordQingkuaiConfiguration(filePath);
474
+ const handleFileChange = (filePath) => {
475
+ for (const configPath of configResolver.removeCacheByPath(filePath)) {
476
+ forgetConfigMessages(configPath);
477
+ configResolver.resolve(configPath, (path, message) => {
478
+ reportConfigMessage(server.config.logger, path, message);
479
+ });
482
480
  }
483
- });
484
- }
485
- function loadAllQingkuaiConfigurations(workspaceDir) {
486
- findFilesByName(workspaceDir, ".qingkuairc", /* @__PURE__ */ new Set(["node_modules"])).forEach((fileName) => {
487
- recordQingkuaiConfiguration(fileName);
488
- });
489
- }
490
- function recordQingkuaiConfiguration(fileName) {
491
- try {
492
- qingkuaiConfigurations.set(nodePath.dirname(fileName), JSON.parse(nodeFs.readFileSync(fileName, "utf-8")));
493
- } catch {
494
- }
481
+ };
482
+ watcher.on("change", handleFileChange);
483
+ watcher.on("add", handleFileChange);
484
+ watcher.on("unlink", handleFileChange);
495
485
  }
496
486
  function getCompileOptions(id) {
497
- const qingkuaiConfig = getQingkuaiConfiguration(id);
487
+ const qingkuaiConfig = getQingkuaiConfig(id);
498
488
  const ret = {
499
489
  interpretiveComments: isUndefined(qingkuaiConfig.interpretiveComments) ? isDev : !!qingkuaiConfig.interpretiveComments,
500
490
  allowConstReactive: qingkuaiConfig.allowConstReactive !== false,
501
491
  requireReactivityMark: qingkuaiConfig.requireReactivityMark === true,
502
- reactivityMode: qingkuaiConfig.reactivityMode === "shallow" ? "shallow" : "reactive"
492
+ reactivityMode: qingkuaiConfig.reactivityMode === "shallow" ? ReactivityMode.Shallow : ReactivityMode.Reactive
503
493
  };
504
494
  switch (qingkuaiConfig.whitespace) {
505
- case "trim":
506
- case "collapse":
507
- case "preserve":
508
- case "trim-collapse": {
509
- ret.whitespace = qingkuaiConfig.whitespace;
495
+ case "trim": {
496
+ ret.whitespace = WhitespaceMode.Trim;
497
+ break;
498
+ }
499
+ case "collapse": {
500
+ ret.whitespace = WhitespaceMode.Collapse;
501
+ break;
502
+ }
503
+ case "preserve": {
504
+ ret.whitespace = WhitespaceMode.Preserve;
510
505
  break;
511
506
  }
512
507
  default: {
513
- ret.whitespace = "trim-collapse";
508
+ ret.whitespace = WhitespaceMode.TrimCollapse;
514
509
  break;
515
510
  }
516
511
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "mlgq",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
- "version": "1.0.28",
6
+ "version": "1.0.30",
7
7
  "packageManager": "pnpm@9.9.0",
8
8
  "exports": {
9
9
  ".": {
@@ -22,8 +22,10 @@
22
22
  },
23
23
  "scripts": {
24
24
  "dev": "rollup -c -w",
25
+ "test": "vitest --run",
25
26
  "release": "node scripts/release.js",
26
- "build": "rimraf dist && tsc && rollup -c && rimraf dist/temp-types",
27
+ "typecheck": "tsc -p tsconfig.json",
28
+ "build": "rimraf dist && tsc -p tsconfig.build.json && rollup -c && rimraf dist/temp-types",
27
29
  "postpublish": "curl -X PUT 'https://registry-direct.npmmirror.com/-/package/vite-plugin-qingkuai/syncs'"
28
30
  },
29
31
  "devDependencies": {
@@ -32,15 +34,17 @@
32
34
  "fs-extra": "^11.3.0",
33
35
  "husky": "^9.1.7",
34
36
  "lint-staged": "^17.3.0",
35
- "qingkuai": "^1.0.101",
37
+ "qingkuai": "^1.0.104",
36
38
  "rimraf": "^6.0.1",
37
39
  "rollup": "^4.38.0",
38
40
  "rollup-plugin-dts": "^6.2.1",
39
41
  "rollup-plugin-esbuild": "^6.2.1",
40
- "vite": "8.0.0"
42
+ "typescript": "^6.0.3",
43
+ "vite": "8.3.5",
44
+ "vitest": "4.1.10"
41
45
  },
42
46
  "peerDependencies": {
43
- "qingkuai": ">=1.0.50",
47
+ "qingkuai": ">=1.0.104",
44
48
  "vite": ">=6.2.4 <9"
45
49
  },
46
50
  "dependencies": {
@@ -48,6 +52,7 @@
48
52
  "lines-and-columns": "^2.0.4",
49
53
  "postcss": "^8.5.3",
50
54
  "postcss-selector-parser": "^7.1.0",
55
+ "qingkuai-language-service": "^1.0.23",
51
56
  "source-map-js": "^1.2.1"
52
57
  },
53
58
  "keywords": [