vite 5.1.0-beta.1 → 5.1.0-beta.3

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.
@@ -17,7 +17,7 @@ import { createServer as createServer$2, get as get$1 } from 'node:https';
17
17
  import require$$0$6 from 'util';
18
18
  import require$$4$1 from 'net';
19
19
  import require$$0$9 from 'url';
20
- import require$$1$1 from 'http';
20
+ import require$$1 from 'http';
21
21
  import require$$0$7 from 'stream';
22
22
  import require$$2 from 'os';
23
23
  import require$$2$1 from 'child_process';
@@ -30,6 +30,7 @@ import require$$0$a from 'crypto';
30
30
  import require$$0$8, { createRequire as createRequire$2 } from 'module';
31
31
  import assert$1 from 'node:assert';
32
32
  import v8 from 'node:v8';
33
+ import { Worker as Worker$1 } from 'node:worker_threads';
33
34
  import { Buffer as Buffer$1 } from 'node:buffer';
34
35
  import { VERSION } from 'rollup';
35
36
  import { parseAst, parseAstAsync } from 'rollup/parseAst';
@@ -38,10 +39,9 @@ import readline from 'node:readline';
38
39
  import { EventEmitter as EventEmitter$4 } from 'node:events';
39
40
  import require$$0$b from 'zlib';
40
41
  import require$$0$c from 'buffer';
41
- import require$$1$2 from 'https';
42
+ import require$$1$1 from 'https';
42
43
  import require$$4$2 from 'tls';
43
44
  import zlib$1, { gzip } from 'node:zlib';
44
- import require$$1 from 'worker_threads';
45
45
 
46
46
  import { fileURLToPath as __cjs_fileURLToPath } from 'node:url';
47
47
  import { dirname as __cjs_dirname } from 'node:path';
@@ -11837,7 +11837,7 @@ function loadPackageData(pkgPath) {
11837
11837
  });
11838
11838
  }
11839
11839
  else {
11840
- hasSideEffects = () => true;
11840
+ hasSideEffects = () => null;
11841
11841
  }
11842
11842
  const pkg = {
11843
11843
  dir: pkgDir,
@@ -12047,7 +12047,7 @@ function isOptimizable(id, optimizeDeps) {
12047
12047
  const bareImportRE = /^(?![a-zA-Z]:)[\w@](?!.*:\/\/)/;
12048
12048
  const deepImportRE = /^([^@][^/]*)\/|^(@[^/]+\/[^/]+)\//;
12049
12049
  // TODO: use import()
12050
- const _require$2 = createRequire$1(import.meta.url);
12050
+ const _require$1 = createRequire$1(import.meta.url);
12051
12051
  // set in bin/vite.js
12052
12052
  const filter = process.env.VITE_DEBUG_FILTER;
12053
12053
  const DEBUG = process.env.DEBUG;
@@ -12770,7 +12770,7 @@ const requireResolveFromRootWithFallback = (root, id) => {
12770
12770
  }
12771
12771
  // actually resolve
12772
12772
  // Search in the root directory first, and fallback to the default require paths.
12773
- return _require$2.resolve(id, { paths: [root, _dirname] });
12773
+ return _require$1.resolve(id, { paths: [root, _dirname] });
12774
12774
  };
12775
12775
  function emptyCssComments(raw) {
12776
12776
  return raw.replace(multilineCommentsRE, blankReplacer);
@@ -14863,101 +14863,235 @@ async function reloadOnTsconfigChange(changedFile) {
14863
14863
  }
14864
14864
  }
14865
14865
 
14866
- var dist$1 = {};
14867
-
14868
- var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
14869
- return (mod && mod.__esModule) ? mod : { "default": mod };
14870
- };
14871
- Object.defineProperty(dist$1, "__esModule", { value: true });
14872
- var Worker_1 = dist$1.Worker = void 0;
14873
- const os_1 = __importDefault(require$$2);
14874
- const worker_threads_1 = require$$1;
14875
- class Worker {
14876
- constructor(fn, options = {}) {
14877
- this.code = genWorkerCode(fn);
14878
- this.max = options.max || Math.max(1, os_1.default.cpus().length - 1);
14879
- this.pool = [];
14880
- this.idlePool = [];
14881
- this.queue = [];
14882
- }
14883
- async run(...args) {
14884
- const worker = await this._getAvailableWorker();
14885
- return new Promise((resolve, reject) => {
14886
- worker.currentResolve = resolve;
14887
- worker.currentReject = reject;
14888
- worker.postMessage(args);
14889
- });
14890
- }
14891
- stop() {
14892
- this.pool.forEach((w) => w.unref());
14893
- this.queue.forEach(([_, reject]) => reject(new Error('Main worker pool stopped before a worker was available.')));
14894
- this.pool = [];
14895
- this.idlePool = [];
14896
- this.queue = [];
14897
- }
14898
- async _getAvailableWorker() {
14899
- // has idle one?
14900
- if (this.idlePool.length) {
14901
- return this.idlePool.shift();
14902
- }
14903
- // can spawn more?
14904
- if (this.pool.length < this.max) {
14905
- const worker = new worker_threads_1.Worker(this.code, { eval: true });
14906
- worker.on('message', (res) => {
14907
- worker.currentResolve && worker.currentResolve(res);
14908
- worker.currentResolve = null;
14909
- this._assignDoneWorker(worker);
14910
- });
14911
- worker.on('error', (err) => {
14912
- worker.currentReject && worker.currentReject(err);
14913
- worker.currentReject = null;
14914
- });
14915
- worker.on('exit', (code) => {
14916
- const i = this.pool.indexOf(worker);
14917
- if (i > -1)
14918
- this.pool.splice(i, 1);
14919
- if (code !== 0 && worker.currentReject) {
14920
- worker.currentReject(new Error(`Wroker stopped with non-0 exit code ${code}`));
14921
- worker.currentReject = null;
14922
- }
14866
+ // src/realWorker.ts
14867
+ var Worker = class {
14868
+ /** @internal */
14869
+ _code;
14870
+ /** @internal */
14871
+ _parentFunctions;
14872
+ /** @internal */
14873
+ _max;
14874
+ /** @internal */
14875
+ _pool;
14876
+ /** @internal */
14877
+ _idlePool;
14878
+ /** @internal */
14879
+ _queue;
14880
+ constructor(fn, options = {}) {
14881
+ this._code = genWorkerCode(fn, options.parentFunctions ?? {});
14882
+ this._parentFunctions = options.parentFunctions ?? {};
14883
+ const defaultMax = Math.max(
14884
+ 1,
14885
+ // os.availableParallelism is available from Node.js 18.14.0
14886
+ (os$4.availableParallelism?.() ?? os$4.cpus().length) - 1
14887
+ );
14888
+ this._max = options.max || defaultMax;
14889
+ this._pool = [];
14890
+ this._idlePool = [];
14891
+ this._queue = [];
14892
+ }
14893
+ async run(...args) {
14894
+ const worker = await this._getAvailableWorker();
14895
+ return new Promise((resolve, reject) => {
14896
+ worker.currentResolve = resolve;
14897
+ worker.currentReject = reject;
14898
+ worker.postMessage({ type: "run", args });
14899
+ });
14900
+ }
14901
+ stop() {
14902
+ this._pool.forEach((w) => w.unref());
14903
+ this._queue.forEach(
14904
+ ([, reject]) => reject(
14905
+ new Error("Main worker pool stopped before a worker was available.")
14906
+ )
14907
+ );
14908
+ this._pool = [];
14909
+ this._idlePool = [];
14910
+ this._queue = [];
14911
+ }
14912
+ /** @internal */
14913
+ async _getAvailableWorker() {
14914
+ if (this._idlePool.length) {
14915
+ return this._idlePool.shift();
14916
+ }
14917
+ if (this._pool.length < this._max) {
14918
+ const worker = new Worker$1(this._code, { eval: true });
14919
+ worker.on("message", async (args) => {
14920
+ if (args.type === "run") {
14921
+ if ("result" in args) {
14922
+ worker.currentResolve && worker.currentResolve(args.result);
14923
+ worker.currentResolve = null;
14924
+ } else {
14925
+ if (args.error instanceof ReferenceError) {
14926
+ args.error.message += ". Maybe you forgot to pass the function to parentFunction?";
14927
+ }
14928
+ worker.currentReject && worker.currentReject(args.error);
14929
+ worker.currentReject = null;
14930
+ }
14931
+ this._assignDoneWorker(worker);
14932
+ } else if (args.type === "parentFunction") {
14933
+ try {
14934
+ const result = await this._parentFunctions[args.name](...args.args);
14935
+ worker.postMessage({ type: "parentFunction", id: args.id, result });
14936
+ } catch (e) {
14937
+ worker.postMessage({
14938
+ type: "parentFunction",
14939
+ id: args.id,
14940
+ error: e
14923
14941
  });
14924
- this.pool.push(worker);
14925
- return worker;
14926
- }
14927
- // no one is available, we have to wait
14928
- let resolve;
14929
- let reject;
14930
- const onWorkerAvailablePromise = new Promise((r, rj) => {
14931
- resolve = r;
14932
- reject = rj;
14933
- });
14934
- this.queue.push([resolve, reject]);
14935
- return onWorkerAvailablePromise;
14936
- }
14937
- _assignDoneWorker(worker) {
14938
- // someone's waiting already?
14939
- if (this.queue.length) {
14940
- const [resolve] = this.queue.shift();
14941
- resolve(worker);
14942
- return;
14942
+ }
14943
14943
  }
14944
- // take a rest.
14945
- this.idlePool.push(worker);
14944
+ });
14945
+ worker.on("error", (err) => {
14946
+ worker.currentReject && worker.currentReject(err);
14947
+ worker.currentReject = null;
14948
+ });
14949
+ worker.on("exit", (code) => {
14950
+ const i = this._pool.indexOf(worker);
14951
+ if (i > -1)
14952
+ this._pool.splice(i, 1);
14953
+ if (code !== 0 && worker.currentReject) {
14954
+ worker.currentReject(
14955
+ new Error(`Worker stopped with non-0 exit code ${code}`)
14956
+ );
14957
+ worker.currentReject = null;
14958
+ }
14959
+ });
14960
+ this._pool.push(worker);
14961
+ return worker;
14946
14962
  }
14947
- }
14948
- Worker_1 = dist$1.Worker = Worker;
14949
- function genWorkerCode(fn) {
14950
- return `
14951
- const doWork = ${fn.toString()}
14952
-
14963
+ let resolve;
14964
+ let reject;
14965
+ const onWorkerAvailablePromise = new Promise((r, rj) => {
14966
+ resolve = r;
14967
+ reject = rj;
14968
+ });
14969
+ this._queue.push([resolve, reject]);
14970
+ return onWorkerAvailablePromise;
14971
+ }
14972
+ /** @internal */
14973
+ _assignDoneWorker(worker) {
14974
+ if (this._queue.length) {
14975
+ const [resolve] = this._queue.shift();
14976
+ resolve(worker);
14977
+ return;
14978
+ }
14979
+ this._idlePool.push(worker);
14980
+ }
14981
+ };
14982
+ function genWorkerCode(fn, parentFunctions) {
14983
+ const createParentFunctionCaller = (parentPort) => {
14984
+ let id = 0;
14985
+ const resolvers = /* @__PURE__ */ new Map();
14986
+ const call = (key) => async (...args) => {
14987
+ id++;
14988
+ let resolve, reject;
14989
+ const promise = new Promise((res, rej) => {
14990
+ resolve = res;
14991
+ reject = rej;
14992
+ });
14993
+ resolvers.set(id, { resolve, reject });
14994
+ parentPort.postMessage({ type: "parentFunction", id, name: key, args });
14995
+ return await promise;
14996
+ };
14997
+ const receive = (id2, args) => {
14998
+ if (resolvers.has(id2)) {
14999
+ const { resolve, reject } = resolvers.get(id2);
15000
+ resolvers.delete(id2);
15001
+ if ("result" in args) {
15002
+ resolve(args.result);
15003
+ } else {
15004
+ reject(args.error);
15005
+ }
15006
+ }
15007
+ };
15008
+ return { call, receive };
15009
+ };
15010
+ return `
14953
15011
  const { parentPort } = require('worker_threads')
15012
+ const parentFunctionCaller = (${createParentFunctionCaller.toString()})(parentPort)
15013
+
15014
+ const doWork = (() => {
15015
+ ${Object.keys(parentFunctions).map(
15016
+ (key) => `const ${key} = parentFunctionCaller.call(${JSON.stringify(key)});`
15017
+ ).join("\n")}
15018
+ return (${fn.toString()})()
15019
+ })()
14954
15020
 
14955
15021
  parentPort.on('message', async (args) => {
14956
- const res = await doWork(...args)
14957
- parentPort.postMessage(res)
15022
+ if (args.type === 'run') {
15023
+ try {
15024
+ const res = await doWork(...args.args)
15025
+ parentPort.postMessage({ type: 'run', result: res })
15026
+ } catch (e) {
15027
+ parentPort.postMessage({ type: 'run', error: e })
15028
+ }
15029
+ } else if (args.type === 'parentFunction') {
15030
+ parentFunctionCaller.receive(args.id, args)
15031
+ }
14958
15032
  })
14959
15033
  `;
14960
15034
  }
15035
+ var FakeWorker = class {
15036
+ /** @internal */
15037
+ _fn;
15038
+ constructor(fn, options = {}) {
15039
+ const argsAndCode = genFakeWorkerArgsAndCode(
15040
+ fn,
15041
+ options.parentFunctions ?? {}
15042
+ );
15043
+ const require2 = createRequire$1(import.meta.url);
15044
+ this._fn = new Function(...argsAndCode)(require2, options.parentFunctions);
15045
+ }
15046
+ async run(...args) {
15047
+ try {
15048
+ return await this._fn(...args);
15049
+ } catch (err) {
15050
+ if (err instanceof ReferenceError) {
15051
+ err.message += ". Maybe you forgot to pass the function to parentFunction?";
15052
+ }
15053
+ throw err;
15054
+ }
15055
+ }
15056
+ stop() {
15057
+ }
15058
+ };
15059
+ function genFakeWorkerArgsAndCode(fn, parentFunctions) {
15060
+ return [
15061
+ "require",
15062
+ "parentFunctions",
15063
+ `
15064
+ ${Object.keys(parentFunctions).map((key) => `const ${key} = parentFunctions[${JSON.stringify(key)}];`).join("\n")}
15065
+ return (${fn.toString()})()
15066
+ `
15067
+ ];
15068
+ }
15069
+
15070
+ // src/workerWithFallback.ts
15071
+ var WorkerWithFallback = class {
15072
+ /** @internal */
15073
+ _disableReal;
15074
+ /** @internal */
15075
+ _realWorker;
15076
+ /** @internal */
15077
+ _fakeWorker;
15078
+ /** @internal */
15079
+ _shouldUseFake;
15080
+ constructor(fn, options) {
15081
+ this._disableReal = options.max !== void 0 && options.max <= 0;
15082
+ this._realWorker = new Worker(fn, options);
15083
+ this._fakeWorker = new FakeWorker(fn, options);
15084
+ this._shouldUseFake = options.shouldUseFake;
15085
+ }
15086
+ async run(...args) {
15087
+ const useFake = this._disableReal || this._shouldUseFake(...args);
15088
+ return this[useFake ? "_fakeWorker" : "_realWorker"].run(...args);
15089
+ }
15090
+ stop() {
15091
+ this._realWorker.stop();
15092
+ this._fakeWorker.stop();
15093
+ }
15094
+ };
14961
15095
 
14962
15096
  let terserPath;
14963
15097
  const loadTerserPath = (root) => {
@@ -14980,7 +15114,7 @@ const loadTerserPath = (root) => {
14980
15114
  };
14981
15115
  function terserPlugin(config) {
14982
15116
  const { maxWorkers, ...terserOptions } = config.build.terserOptions;
14983
- const makeWorker = () => new Worker_1(async (terserPath, code, options) => {
15117
+ const makeWorker = () => new Worker(() => async (terserPath, code, options) => {
14984
15118
  // test fails when using `import`. maybe related: https://github.com/nodejs/node/issues/43205
14985
15119
  // eslint-disable-next-line no-restricted-globals -- this function runs inside cjs
14986
15120
  const terser = require(terserPath);
@@ -30813,28 +30947,33 @@ async function applyHtmlTransforms(html, hooks, ctx) {
30813
30947
  html = res.html || html;
30814
30948
  tags = res.tags;
30815
30949
  }
30816
- const headTags = [];
30817
- const headPrependTags = [];
30818
- const bodyTags = [];
30819
- const bodyPrependTags = [];
30950
+ let headTags;
30951
+ let headPrependTags;
30952
+ let bodyTags;
30953
+ let bodyPrependTags;
30820
30954
  for (const tag of tags) {
30821
- if (tag.injectTo === 'body') {
30822
- bodyTags.push(tag);
30823
- }
30824
- else if (tag.injectTo === 'body-prepend') {
30825
- bodyPrependTags.push(tag);
30826
- }
30827
- else if (tag.injectTo === 'head') {
30828
- headTags.push(tag);
30829
- }
30830
- else {
30831
- headPrependTags.push(tag);
30955
+ switch (tag.injectTo) {
30956
+ case 'body':
30957
+ (bodyTags ??= []).push(tag);
30958
+ break;
30959
+ case 'body-prepend':
30960
+ (bodyPrependTags ??= []).push(tag);
30961
+ break;
30962
+ case 'head':
30963
+ (headTags ??= []).push(tag);
30964
+ break;
30965
+ default:
30966
+ (headPrependTags ??= []).push(tag);
30832
30967
  }
30833
30968
  }
30834
- html = injectToHead(html, headPrependTags, true);
30835
- html = injectToHead(html, headTags);
30836
- html = injectToBody(html, bodyPrependTags, true);
30837
- html = injectToBody(html, bodyTags);
30969
+ if (headPrependTags)
30970
+ html = injectToHead(html, headPrependTags, true);
30971
+ if (headTags)
30972
+ html = injectToHead(html, headTags);
30973
+ if (bodyPrependTags)
30974
+ html = injectToBody(html, bodyPrependTags, true);
30975
+ if (bodyTags)
30976
+ html = injectToBody(html, bodyTags);
30838
30977
  }
30839
30978
  }
30840
30979
  return html;
@@ -31006,6 +31145,7 @@ function cssPlugin(config) {
31006
31145
  tryIndex: false,
31007
31146
  extensions: [],
31008
31147
  });
31148
+ let preprocessorWorkerController;
31009
31149
  // warm up cache for resolved postcss config
31010
31150
  if (config.css?.transformer !== 'lightningcss') {
31011
31151
  resolvePostcssConfig(config);
@@ -31017,6 +31157,11 @@ function cssPlugin(config) {
31017
31157
  moduleCache = new Map();
31018
31158
  cssModulesCache.set(config, moduleCache);
31019
31159
  removedPureCssFilesCache.set(config, new Map());
31160
+ preprocessorWorkerController = createPreprocessorWorkerController(normalizeMaxWorkers(config.css.preprocessorMaxWorkers));
31161
+ preprocessorWorkerControllerCache.set(config, preprocessorWorkerController);
31162
+ },
31163
+ buildEnd() {
31164
+ preprocessorWorkerController?.close();
31020
31165
  },
31021
31166
  async load(id) {
31022
31167
  if (!isCSSRequest(id))
@@ -31066,7 +31211,7 @@ function cssPlugin(config) {
31066
31211
  }
31067
31212
  return url;
31068
31213
  };
31069
- const { code: css, modules, deps, map, } = await compileCSS(id, raw, config, urlReplacer);
31214
+ const { code: css, modules, deps, map, } = await compileCSS(id, raw, config, preprocessorWorkerController, urlReplacer);
31070
31215
  if (modules) {
31071
31216
  moduleCache.set(id, modules);
31072
31217
  }
@@ -31592,10 +31737,10 @@ function createCSSResolvers(config) {
31592
31737
  function getCssResolversKeys(resolvers) {
31593
31738
  return Object.keys(resolvers);
31594
31739
  }
31595
- async function compileCSSPreprocessors(id, lang, code, config) {
31740
+ async function compileCSSPreprocessors(id, lang, code, config, workerController) {
31596
31741
  const { preprocessorOptions, devSourcemap } = config.css ?? {};
31597
31742
  const atImportResolvers = getAtImportResolvers(config);
31598
- const preProcessor = preProcessors[lang];
31743
+ const preProcessor = workerController[lang];
31599
31744
  let opts = (preprocessorOptions && preprocessorOptions[lang]) || {};
31600
31745
  // support @import from node dependencies by default
31601
31746
  switch (lang) {
@@ -31644,7 +31789,7 @@ function getAtImportResolvers(config) {
31644
31789
  }
31645
31790
  return atImportResolvers;
31646
31791
  }
31647
- async function compileCSS(id, code, config, urlReplacer) {
31792
+ async function compileCSS(id, code, config, workerController, urlReplacer) {
31648
31793
  if (config.css?.transformer === 'lightningcss') {
31649
31794
  return compileLightningCSS(id, code, config, urlReplacer);
31650
31795
  }
@@ -31669,7 +31814,7 @@ async function compileCSS(id, code, config, urlReplacer) {
31669
31814
  // 2. pre-processors: sass etc.
31670
31815
  let preprocessorMap;
31671
31816
  if (isPreProcessor(lang)) {
31672
- const preprocessorResult = await compileCSSPreprocessors(id, lang, code, config);
31817
+ const preprocessorResult = await compileCSSPreprocessors(id, lang, code, config, workerController);
31673
31818
  code = preprocessorResult.code;
31674
31819
  preprocessorMap = preprocessorResult.map;
31675
31820
  preprocessorResult.deps?.forEach((dep) => deps.add(dep));
@@ -31701,7 +31846,7 @@ async function compileCSS(id, code, config, urlReplacer) {
31701
31846
  const code = await fs$l.promises.readFile(id, 'utf-8');
31702
31847
  const lang = id.match(CSS_LANGS_RE)?.[1];
31703
31848
  if (isPreProcessor(lang)) {
31704
- const result = await compileCSSPreprocessors(id, lang, code, config);
31849
+ const result = await compileCSSPreprocessors(id, lang, code, config, workerController);
31705
31850
  result.deps?.forEach((dep) => deps.add(dep));
31706
31851
  // TODO: support source map
31707
31852
  return result.code;
@@ -31754,9 +31899,7 @@ async function compileCSS(id, code, config, urlReplacer) {
31754
31899
  // postcss is an unbundled dep and should be lazy imported
31755
31900
  postcssResult = await postcss.default(postcssPlugins).process(code, {
31756
31901
  ...postcssOptions,
31757
- parser: lang === 'sss'
31758
- ? loadPreprocessor("sugarss" /* PostCssDialectLang.sss */, config.root)
31759
- : postcssOptions.parser,
31902
+ parser: lang === 'sss' ? loadSss(config.root) : postcssOptions.parser,
31760
31903
  to: source,
31761
31904
  from: source,
31762
31905
  ...(devSourcemap
@@ -31851,14 +31994,24 @@ function createCachedImport(imp) {
31851
31994
  return cached;
31852
31995
  };
31853
31996
  }
31854
- const importPostcssImport = createCachedImport(() => import('./dep-vM06sRGH.js').then(function (n) { return n.i; }));
31855
- const importPostcssModules = createCachedImport(() => import('./dep-pPggWEp0.js').then(function (n) { return n.i; }));
31997
+ const importPostcssImport = createCachedImport(() => import('./dep-A6C2SOTv.js').then(function (n) { return n.i; }));
31998
+ const importPostcssModules = createCachedImport(() => import('./dep-tbVWvdXL.js').then(function (n) { return n.i; }));
31856
31999
  const importPostcss = createCachedImport(() => import('postcss'));
32000
+ const preprocessorWorkerControllerCache = new WeakMap();
32001
+ let alwaysFakeWorkerWorkerControllerCache;
31857
32002
  /**
31858
32003
  * @experimental
31859
32004
  */
31860
32005
  async function preprocessCSS(code, filename, config) {
31861
- return await compileCSS(filename, code, config);
32006
+ let workerController = preprocessorWorkerControllerCache.get(config);
32007
+ if (!workerController) {
32008
+ // if workerController doesn't exist, create a workerController that always uses fake workers
32009
+ // because fake workers doesn't require calling `.close` unlike real workers
32010
+ alwaysFakeWorkerWorkerControllerCache ||=
32011
+ createPreprocessorWorkerController(0);
32012
+ workerController = alwaysFakeWorkerWorkerControllerCache;
32013
+ }
32014
+ return await compileCSS(filename, code, config, workerController);
31862
32015
  }
31863
32016
  async function formatPostcssSourceMap(rawMap, file) {
31864
32017
  const inputFileDir = path$o.dirname(file);
@@ -32160,16 +32313,15 @@ async function hoistAtRules(css) {
32160
32313
  }
32161
32314
  return s.toString();
32162
32315
  }
32163
- const loadedPreprocessors = {};
32164
- // TODO: use dynamic import
32165
- const _require$1 = createRequire$1(import.meta.url);
32166
- function loadPreprocessor(lang, root) {
32167
- if (lang in loadedPreprocessors) {
32168
- return loadedPreprocessors[lang];
32316
+ const loadedPreprocessorPath = {};
32317
+ function loadPreprocessorPath(lang, root) {
32318
+ const cached = loadedPreprocessorPath[lang];
32319
+ if (cached) {
32320
+ return cached;
32169
32321
  }
32170
32322
  try {
32171
32323
  const resolved = requireResolveFromRootWithFallback(root, lang);
32172
- return (loadedPreprocessors[lang] = _require$1(resolved));
32324
+ return (loadedPreprocessorPath[lang] = resolved);
32173
32325
  }
32174
32326
  catch (e) {
32175
32327
  if (e.code === 'MODULE_NOT_FOUND') {
@@ -32183,6 +32335,14 @@ function loadPreprocessor(lang, root) {
32183
32335
  }
32184
32336
  }
32185
32337
  }
32338
+ let cachedSss;
32339
+ function loadSss(root) {
32340
+ if (cachedSss)
32341
+ return cachedSss;
32342
+ const sssPath = loadPreprocessorPath("sugarss" /* PostCssDialectLang.sss */, root);
32343
+ cachedSss = createRequire$1(import.meta.url)(sssPath);
32344
+ return cachedSss;
32345
+ }
32186
32346
  // in unix, scss might append `location.href` in environments that shim `location`
32187
32347
  // see https://github.com/sass/dart-sass/issues/710
32188
32348
  function cleanScssBugUrl(url) {
@@ -32214,78 +32374,124 @@ function fixScssBugImportValue(data) {
32214
32374
  return data;
32215
32375
  }
32216
32376
  // .scss/.sass processor
32217
- const scss = async (source, root, options, resolvers) => {
32218
- const render = loadPreprocessor("sass" /* PreprocessLang.sass */, root).render;
32219
- // NOTE: `sass` always runs it's own importer first, and only falls back to
32220
- // the `importer` option when it can't resolve a path
32221
- const internalImporter = (url, importer, done) => {
32377
+ const makeScssWorker = (resolvers, alias, maxWorkers) => {
32378
+ const internalImporter = async (url, importer, filename) => {
32222
32379
  importer = cleanScssBugUrl(importer);
32223
- resolvers.sass(url, importer).then((resolved) => {
32224
- if (resolved) {
32225
- rebaseUrls(resolved, options.filename, options.alias, '$', resolvers.sass)
32226
- .then((data) => done?.(fixScssBugImportValue(data)))
32227
- .catch((data) => done?.(data));
32228
- }
32229
- else {
32230
- done?.(null);
32380
+ const resolved = await resolvers.sass(url, importer);
32381
+ if (resolved) {
32382
+ try {
32383
+ const data = await rebaseUrls(resolved, filename, alias, '$', resolvers.sass);
32384
+ return fixScssBugImportValue(data);
32231
32385
  }
32232
- });
32233
- };
32234
- const importer = [internalImporter];
32235
- if (options.importer) {
32236
- Array.isArray(options.importer)
32237
- ? importer.unshift(...options.importer)
32238
- : importer.unshift(options.importer);
32239
- }
32240
- const { content: data, map: additionalMap } = await getSource(source, options.filename, options.additionalData, options.enableSourcemap);
32241
- const finalOptions = {
32242
- ...options,
32243
- data,
32244
- file: options.filename,
32245
- outFile: options.filename,
32246
- importer,
32247
- ...(options.enableSourcemap
32248
- ? {
32249
- sourceMap: true,
32250
- omitSourceMapUrl: true,
32251
- sourceMapRoot: path$o.dirname(options.filename),
32386
+ catch (data) {
32387
+ return data;
32252
32388
  }
32253
- : {}),
32389
+ }
32390
+ else {
32391
+ return null;
32392
+ }
32254
32393
  };
32255
- try {
32256
- const result = await new Promise((resolve, reject) => {
32257
- render(finalOptions, (err, res) => {
32394
+ const worker = new WorkerWithFallback(() => async (sassPath, data,
32395
+ // additionalData can a function that is not cloneable but it won't be used
32396
+ options) => {
32397
+ // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker
32398
+ const sass = require(sassPath);
32399
+ // eslint-disable-next-line no-restricted-globals
32400
+ const path = require('node:path');
32401
+ // NOTE: `sass` always runs it's own importer first, and only falls back to
32402
+ // the `importer` option when it can't resolve a path
32403
+ const _internalImporter = (url, importer, done) => {
32404
+ internalImporter(url, importer, options.filename).then((data) => done?.(data));
32405
+ };
32406
+ const importer = [_internalImporter];
32407
+ if (options.importer) {
32408
+ Array.isArray(options.importer)
32409
+ ? importer.unshift(...options.importer)
32410
+ : importer.unshift(options.importer);
32411
+ }
32412
+ const finalOptions = {
32413
+ ...options,
32414
+ data,
32415
+ file: options.filename,
32416
+ outFile: options.filename,
32417
+ importer,
32418
+ ...(options.enableSourcemap
32419
+ ? {
32420
+ sourceMap: true,
32421
+ omitSourceMapUrl: true,
32422
+ sourceMapRoot: path.dirname(options.filename),
32423
+ }
32424
+ : {}),
32425
+ };
32426
+ return new Promise((resolve, reject) => {
32427
+ sass.render(finalOptions, (err, res) => {
32258
32428
  if (err) {
32259
32429
  reject(err);
32260
32430
  }
32261
32431
  else {
32262
- resolve(res);
32432
+ resolve({
32433
+ css: res.css.toString(),
32434
+ map: res.map?.toString(),
32435
+ stats: res.stats,
32436
+ });
32263
32437
  }
32264
32438
  });
32265
32439
  });
32266
- const deps = result.stats.includedFiles.map((f) => cleanScssBugUrl(f));
32267
- const map = result.map
32268
- ? JSON.parse(result.map.toString())
32269
- : undefined;
32270
- return {
32271
- code: result.css.toString(),
32272
- map,
32273
- additionalMap,
32274
- deps,
32275
- };
32276
- }
32277
- catch (e) {
32278
- // normalize SASS error
32279
- e.message = `[sass] ${e.message}`;
32280
- e.id = e.file;
32281
- e.frame = e.formatted;
32282
- return { code: '', error: e, deps: [] };
32283
- }
32440
+ }, {
32441
+ parentFunctions: { internalImporter },
32442
+ shouldUseFake(_sassPath, _data, options) {
32443
+ // functions and importer is a function and is not serializable
32444
+ // in that case, fallback to running in main thread
32445
+ return !!((options.functions && Object.keys(options.functions).length > 0) ||
32446
+ (options.importer &&
32447
+ (!Array.isArray(options.importer) || options.importer.length > 0)));
32448
+ },
32449
+ max: maxWorkers,
32450
+ });
32451
+ return worker;
32452
+ };
32453
+ const scssProcessor = (maxWorkers) => {
32454
+ const workerMap = new Map();
32455
+ return {
32456
+ close() {
32457
+ for (const worker of workerMap.values()) {
32458
+ worker.stop();
32459
+ }
32460
+ },
32461
+ async process(source, root, options, resolvers) {
32462
+ const sassPath = loadPreprocessorPath("sass" /* PreprocessLang.sass */, root);
32463
+ if (!workerMap.has(options.alias)) {
32464
+ workerMap.set(options.alias, makeScssWorker(resolvers, options.alias, maxWorkers));
32465
+ }
32466
+ const worker = workerMap.get(options.alias);
32467
+ const { content: data, map: additionalMap } = await getSource(source, options.filename, options.additionalData, options.enableSourcemap);
32468
+ const optionsWithoutAdditionalData = {
32469
+ ...options,
32470
+ additionalData: undefined,
32471
+ };
32472
+ try {
32473
+ const result = await worker.run(sassPath, data, optionsWithoutAdditionalData);
32474
+ const deps = result.stats.includedFiles.map((f) => cleanScssBugUrl(f));
32475
+ const map = result.map
32476
+ ? JSON.parse(result.map.toString())
32477
+ : undefined;
32478
+ return {
32479
+ code: result.css.toString(),
32480
+ map,
32481
+ additionalMap,
32482
+ deps,
32483
+ };
32484
+ }
32485
+ catch (e) {
32486
+ // normalize SASS error
32487
+ e.message = `[sass] ${e.message}`;
32488
+ e.id = e.file;
32489
+ e.frame = e.formatted;
32490
+ return { code: '', error: e, deps: [] };
32491
+ }
32492
+ },
32493
+ };
32284
32494
  };
32285
- const sass = (source, root, options, aliasResolver) => scss(source, root, {
32286
- ...options,
32287
- indentedSyntax: true,
32288
- }, aliasResolver);
32289
32495
  /**
32290
32496
  * relative url() inside \@imported sass and less files must be rebased to use
32291
32497
  * root file as base.
@@ -32342,137 +32548,220 @@ async function rebaseUrls(file, rootFile, alias, variablePrefix, resolver) {
32342
32548
  };
32343
32549
  }
32344
32550
  // .less
32345
- const less = async (source, root, options, resolvers) => {
32346
- const nodeLess = loadPreprocessor("less" /* PreprocessLang.less */, root);
32347
- const viteResolverPlugin = createViteLessPlugin(nodeLess, options.filename, options.alias, resolvers);
32348
- const { content, map: additionalMap } = await getSource(source, options.filename, options.additionalData, options.enableSourcemap);
32349
- let result;
32350
- try {
32351
- result = await nodeLess.render(content, {
32352
- ...options,
32353
- plugins: [viteResolverPlugin, ...(options.plugins || [])],
32354
- ...(options.enableSourcemap
32355
- ? {
32356
- sourceMap: {
32357
- outputSourceFiles: true,
32358
- sourceMapFileInline: false,
32359
- },
32360
- }
32361
- : {}),
32362
- });
32363
- }
32364
- catch (e) {
32365
- const error = e;
32366
- // normalize error info
32367
- const normalizedError = new Error(`[less] ${error.message || error.type}`);
32368
- normalizedError.loc = {
32369
- file: error.filename || options.filename,
32370
- line: error.line,
32371
- column: error.column,
32372
- };
32373
- return { code: '', error: normalizedError, deps: [] };
32374
- }
32375
- const map = result.map && JSON.parse(result.map);
32376
- if (map) {
32377
- delete map.sourcesContent;
32378
- }
32379
- return {
32380
- code: result.css.toString(),
32381
- map,
32382
- additionalMap,
32383
- deps: result.imports,
32551
+ const makeLessWorker = (resolvers, alias, maxWorkers) => {
32552
+ const viteLessResolve = async (filename, dir, rootFile) => {
32553
+ const resolved = await resolvers.less(filename, path$o.join(dir, '*'));
32554
+ if (!resolved)
32555
+ return undefined;
32556
+ const result = await rebaseUrls(resolved, rootFile, alias, '@', resolvers.less);
32557
+ if (result) {
32558
+ return {
32559
+ resolved,
32560
+ contents: 'contents' in result ? result.contents : undefined,
32561
+ };
32562
+ }
32563
+ return result;
32384
32564
  };
32385
- };
32386
- /**
32387
- * Less manager, lazy initialized
32388
- */
32389
- let ViteLessManager;
32390
- function createViteLessPlugin(less, rootFile, alias, resolvers) {
32391
- if (!ViteLessManager) {
32392
- ViteLessManager = class ViteManager extends less.FileManager {
32393
- resolvers;
32394
- rootFile;
32395
- alias;
32396
- constructor(rootFile, resolvers, alias) {
32397
- super();
32398
- this.rootFile = rootFile;
32399
- this.resolvers = resolvers;
32400
- this.alias = alias;
32401
- }
32402
- supports(filename) {
32403
- return !isExternalUrl(filename);
32404
- }
32405
- supportsSync() {
32406
- return false;
32407
- }
32408
- async loadFile(filename, dir, opts, env) {
32409
- const resolved = await this.resolvers.less(filename, path$o.join(dir, '*'));
32410
- if (resolved) {
32411
- const result = await rebaseUrls(resolved, this.rootFile, this.alias, '@', this.resolvers.less);
32412
- let contents;
32413
- if (result && 'contents' in result) {
32414
- contents = result.contents;
32565
+ const worker = new WorkerWithFallback(() => {
32566
+ // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker
32567
+ const fsp = require('node:fs/promises');
32568
+ // eslint-disable-next-line no-restricted-globals
32569
+ const path = require('node:path');
32570
+ let ViteLessManager;
32571
+ const createViteLessPlugin = (less, rootFile) => {
32572
+ const { FileManager } = less;
32573
+ ViteLessManager ??= class ViteManager extends FileManager {
32574
+ rootFile;
32575
+ constructor(rootFile) {
32576
+ super();
32577
+ this.rootFile = rootFile;
32578
+ }
32579
+ supports(filename) {
32580
+ return !/^(?:https?:)?\/\//.test(filename);
32581
+ }
32582
+ supportsSync() {
32583
+ return false;
32584
+ }
32585
+ async loadFile(filename, dir, opts, env) {
32586
+ const result = await viteLessResolve(filename, dir, this.rootFile);
32587
+ if (result) {
32588
+ return {
32589
+ filename: path.resolve(result.resolved),
32590
+ contents: result.contents ??
32591
+ (await fsp.readFile(result.resolved, 'utf-8')),
32592
+ };
32415
32593
  }
32416
32594
  else {
32417
- contents = await fsp.readFile(resolved, 'utf-8');
32595
+ return super.loadFile(filename, dir, opts, env);
32418
32596
  }
32419
- return {
32420
- filename: path$o.resolve(resolved),
32421
- contents,
32422
- };
32423
32597
  }
32424
- else {
32425
- return super.loadFile(filename, dir, opts, env);
32426
- }
32427
- }
32598
+ };
32599
+ return {
32600
+ install(_, pluginManager) {
32601
+ pluginManager.addFileManager(new ViteLessManager(rootFile));
32602
+ },
32603
+ minVersion: [3, 0, 0],
32604
+ };
32428
32605
  };
32429
- }
32606
+ return async (lessPath, content,
32607
+ // additionalData can a function that is not cloneable but it won't be used
32608
+ options) => {
32609
+ // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker
32610
+ const nodeLess = require(lessPath);
32611
+ const viteResolverPlugin = createViteLessPlugin(nodeLess, options.filename);
32612
+ const result = await nodeLess.render(content, {
32613
+ ...options,
32614
+ plugins: [viteResolverPlugin, ...(options.plugins || [])],
32615
+ ...(options.enableSourcemap
32616
+ ? {
32617
+ sourceMap: {
32618
+ outputSourceFiles: true,
32619
+ sourceMapFileInline: false,
32620
+ },
32621
+ }
32622
+ : {}),
32623
+ });
32624
+ return result;
32625
+ };
32626
+ }, {
32627
+ parentFunctions: { viteLessResolve },
32628
+ shouldUseFake(_lessPath, _content, options) {
32629
+ // plugins are a function and is not serializable
32630
+ // in that case, fallback to running in main thread
32631
+ return options.plugins?.length > 0;
32632
+ },
32633
+ max: maxWorkers,
32634
+ });
32635
+ return worker;
32636
+ };
32637
+ const lessProcessor = (maxWorkers) => {
32638
+ const workerMap = new Map();
32430
32639
  return {
32431
- install(_, pluginManager) {
32432
- pluginManager.addFileManager(new ViteLessManager(rootFile, resolvers, alias));
32640
+ close() {
32641
+ for (const worker of workerMap.values()) {
32642
+ worker.stop();
32643
+ }
32644
+ },
32645
+ async process(source, root, options, resolvers) {
32646
+ const lessPath = loadPreprocessorPath("less" /* PreprocessLang.less */, root);
32647
+ if (!workerMap.has(options.alias)) {
32648
+ workerMap.set(options.alias, makeLessWorker(resolvers, options.alias, maxWorkers));
32649
+ }
32650
+ const worker = workerMap.get(options.alias);
32651
+ const { content, map: additionalMap } = await getSource(source, options.filename, options.additionalData, options.enableSourcemap);
32652
+ let result;
32653
+ const optionsWithoutAdditionalData = {
32654
+ ...options,
32655
+ additionalData: undefined,
32656
+ };
32657
+ try {
32658
+ result = await worker.run(lessPath, content, optionsWithoutAdditionalData);
32659
+ }
32660
+ catch (e) {
32661
+ const error = e;
32662
+ // normalize error info
32663
+ const normalizedError = new Error(`[less] ${error.message || error.type}`);
32664
+ normalizedError.loc = {
32665
+ file: error.filename || options.filename,
32666
+ line: error.line,
32667
+ column: error.column,
32668
+ };
32669
+ return { code: '', error: normalizedError, deps: [] };
32670
+ }
32671
+ const map = result.map && JSON.parse(result.map);
32672
+ if (map) {
32673
+ delete map.sourcesContent;
32674
+ }
32675
+ return {
32676
+ code: result.css.toString(),
32677
+ map,
32678
+ additionalMap,
32679
+ deps: result.imports,
32680
+ };
32433
32681
  },
32434
- minVersion: [3, 0, 0],
32435
32682
  };
32436
- }
32683
+ };
32437
32684
  // .styl
32438
- const styl = async (source, root, options) => {
32439
- const nodeStylus = loadPreprocessor("stylus" /* PreprocessLang.stylus */, root);
32440
- // Get source with preprocessor options.additionalData. Make sure a new line separator
32441
- // is added to avoid any render error, as added stylus content may not have semi-colon separators
32442
- const { content, map: additionalMap } = await getSource(source, options.filename, options.additionalData, options.enableSourcemap, '\n');
32443
- // Get preprocessor options.imports dependencies as stylus
32444
- // does not return them with its builtin `.deps()` method
32445
- const importsDeps = (options.imports ?? []).map((dep) => path$o.resolve(dep));
32446
- try {
32447
- const ref = nodeStylus(content, options);
32448
- if (options.define) {
32449
- for (const key in options.define) {
32450
- ref.define(key, options.define[key]);
32685
+ const makeStylWorker = (maxWorkers) => {
32686
+ const worker = new WorkerWithFallback(() => {
32687
+ return async (stylusPath, content, root,
32688
+ // additionalData can a function that is not cloneable but it won't be used
32689
+ options) => {
32690
+ // eslint-disable-next-line no-restricted-globals -- this function runs inside a cjs worker
32691
+ const nodeStylus = require(stylusPath);
32692
+ const ref = nodeStylus(content, options);
32693
+ if (options.define) {
32694
+ for (const key in options.define) {
32695
+ ref.define(key, options.define[key]);
32696
+ }
32451
32697
  }
32452
- }
32453
- if (options.enableSourcemap) {
32454
- ref.set('sourcemap', {
32455
- comment: false,
32456
- inline: false,
32457
- basePath: root,
32458
- });
32459
- }
32460
- const result = ref.render();
32461
- // Concat imports deps with computed deps
32462
- const deps = [...ref.deps(), ...importsDeps];
32463
- // @ts-expect-error sourcemap exists
32464
- const map = ref.sourcemap;
32465
- return {
32466
- code: result,
32467
- map: formatStylusSourceMap(map, root),
32468
- additionalMap,
32469
- deps,
32698
+ if (options.enableSourcemap) {
32699
+ ref.set('sourcemap', {
32700
+ comment: false,
32701
+ inline: false,
32702
+ basePath: root,
32703
+ });
32704
+ }
32705
+ return {
32706
+ code: ref.render(),
32707
+ // @ts-expect-error sourcemap exists
32708
+ map: ref.sourcemap,
32709
+ deps: ref.deps(),
32710
+ };
32470
32711
  };
32471
- }
32472
- catch (e) {
32473
- e.message = `[stylus] ${e.message}`;
32474
- return { code: '', error: e, deps: [] };
32475
- }
32712
+ }, {
32713
+ shouldUseFake(_stylusPath, _content, _root, options) {
32714
+ // define can include functions and those are not serializable
32715
+ // in that case, fallback to running in main thread
32716
+ return !!(options.define &&
32717
+ Object.values(options.define).some((d) => typeof d === 'function'));
32718
+ },
32719
+ max: maxWorkers,
32720
+ });
32721
+ return worker;
32722
+ };
32723
+ const stylProcessor = (maxWorkers) => {
32724
+ const workerMap = new Map();
32725
+ return {
32726
+ close() {
32727
+ for (const worker of workerMap.values()) {
32728
+ worker.stop();
32729
+ }
32730
+ },
32731
+ async process(source, root, options, resolvers) {
32732
+ const stylusPath = loadPreprocessorPath("stylus" /* PreprocessLang.stylus */, root);
32733
+ if (!workerMap.has(options.alias)) {
32734
+ workerMap.set(options.alias, makeStylWorker(maxWorkers));
32735
+ }
32736
+ const worker = workerMap.get(options.alias);
32737
+ // Get source with preprocessor options.additionalData. Make sure a new line separator
32738
+ // is added to avoid any render error, as added stylus content may not have semi-colon separators
32739
+ const { content, map: additionalMap } = await getSource(source, options.filename, options.additionalData, options.enableSourcemap, '\n');
32740
+ // Get preprocessor options.imports dependencies as stylus
32741
+ // does not return them with its builtin `.deps()` method
32742
+ const importsDeps = (options.imports ?? []).map((dep) => path$o.resolve(dep));
32743
+ const optionsWithoutAdditionalData = {
32744
+ ...options,
32745
+ additionalData: undefined,
32746
+ };
32747
+ try {
32748
+ const { code, map, deps } = await worker.run(stylusPath, content, root, optionsWithoutAdditionalData);
32749
+ return {
32750
+ code,
32751
+ map: formatStylusSourceMap(map, root),
32752
+ additionalMap,
32753
+ // Concat imports deps with computed deps
32754
+ deps: [...deps, ...importsDeps],
32755
+ };
32756
+ }
32757
+ catch (e) {
32758
+ const wrapped = new Error(`[stylus] ${e.message}`);
32759
+ wrapped.name = e.name;
32760
+ wrapped.stack = e.stack;
32761
+ return { code: '', error: wrapped, deps: [] };
32762
+ }
32763
+ },
32764
+ };
32476
32765
  };
32477
32766
  function formatStylusSourceMap(mapBefore, root) {
32478
32767
  if (!mapBefore)
@@ -32509,15 +32798,43 @@ async function getSource(source, filename, additionalData, enableSourcemap, sep
32509
32798
  map,
32510
32799
  };
32511
32800
  }
32512
- const preProcessors = Object.freeze({
32513
- ["less" /* PreprocessLang.less */]: less,
32514
- ["sass" /* PreprocessLang.sass */]: sass,
32515
- ["scss" /* PreprocessLang.scss */]: scss,
32516
- ["styl" /* PreprocessLang.styl */]: styl,
32517
- ["stylus" /* PreprocessLang.stylus */]: styl,
32518
- });
32801
+ const createPreprocessorWorkerController = (maxWorkers) => {
32802
+ const scss = scssProcessor(maxWorkers);
32803
+ const less = lessProcessor(maxWorkers);
32804
+ const styl = stylProcessor(maxWorkers);
32805
+ const sassProcess = (source, root, options, resolvers) => {
32806
+ return scss.process(source, root, { ...options, indentedSyntax: true }, resolvers);
32807
+ };
32808
+ const close = () => {
32809
+ less.close();
32810
+ scss.close();
32811
+ styl.close();
32812
+ };
32813
+ return {
32814
+ ["less" /* PreprocessLang.less */]: less.process,
32815
+ ["scss" /* PreprocessLang.scss */]: scss.process,
32816
+ ["sass" /* PreprocessLang.sass */]: sassProcess,
32817
+ ["styl" /* PreprocessLang.styl */]: styl.process,
32818
+ ["stylus" /* PreprocessLang.stylus */]: styl.process,
32819
+ close,
32820
+ };
32821
+ };
32822
+ const normalizeMaxWorkers = (maxWorker) => {
32823
+ if (maxWorker === undefined)
32824
+ return 0;
32825
+ if (maxWorker === true)
32826
+ return undefined;
32827
+ return maxWorker;
32828
+ };
32829
+ const preprocessorSet = new Set([
32830
+ "less" /* PreprocessLang.less */,
32831
+ "sass" /* PreprocessLang.sass */,
32832
+ "scss" /* PreprocessLang.scss */,
32833
+ "styl" /* PreprocessLang.styl */,
32834
+ "stylus" /* PreprocessLang.stylus */,
32835
+ ]);
32519
32836
  function isPreProcessor(lang) {
32520
- return lang && lang in preProcessors;
32837
+ return lang && preprocessorSet.has(lang);
32521
32838
  }
32522
32839
  const importLightningCSS = createCachedImport(() => import('lightningcss'));
32523
32840
  async function compileLightningCSS(id, src, config, urlReplacer) {
@@ -42028,7 +42345,7 @@ var utilsMergeExports = utilsMerge.exports;
42028
42345
  var debug$d = srcExports('connect:dispatcher');
42029
42346
  var EventEmitter$3 = require$$0$5.EventEmitter;
42030
42347
  var finalhandler = finalhandler_1;
42031
- var http$4 = require$$1$1;
42348
+ var http$4 = require$$1;
42032
42349
  var merge = utilsMergeExports;
42033
42350
  var parseUrl = parseurlExports;
42034
42351
 
@@ -46918,7 +47235,7 @@ const debug$c = createDebugger('vite:resolve-details', {
46918
47235
  });
46919
47236
  function resolvePlugin(resolveOptions) {
46920
47237
  const { root, isProduction, asSrc, ssrConfig, preferRelative = false, } = resolveOptions;
46921
- const { target: ssrTarget, noExternal: ssrNoExternal } = ssrConfig ?? {};
47238
+ const { target: ssrTarget, noExternal: ssrNoExternal, external: ssrExternal, } = ssrConfig ?? {};
46922
47239
  // In unix systems, absolute paths inside root first needs to be checked as an
46923
47240
  // absolute URL (/root/root/path-to-file) resulting in failed checks before falling
46924
47241
  // back to checking the path as absolute. If /root/root isn't a valid path, we can
@@ -47092,7 +47409,10 @@ function resolvePlugin(resolveOptions) {
47092
47409
  // externalize if building for SSR, otherwise redirect to empty module
47093
47410
  if (isBuiltin(id)) {
47094
47411
  if (ssr) {
47095
- if (ssrNoExternal === true) {
47412
+ if (ssrNoExternal === true &&
47413
+ // if both noExternal and external are true, noExternal will take the higher priority and bundle it.
47414
+ // only if the id is explicitly listed in external, we will externalize it and skip this error.
47415
+ (ssrExternal === true || !ssrExternal?.includes(id))) {
47096
47416
  let message = `Cannot bundle Node.js built-in "${id}"`;
47097
47417
  if (importer) {
47098
47418
  message += ` imported from "${path$o.relative(process.cwd(), importer)}"`;
@@ -47100,7 +47420,9 @@ function resolvePlugin(resolveOptions) {
47100
47420
  message += `. Consider disabling ssr.noExternal or remove the built-in dependency.`;
47101
47421
  this.error(message);
47102
47422
  }
47103
- return options.idOnly ? id : { id, external: true };
47423
+ return options.idOnly
47424
+ ? id
47425
+ : { id, external: true, moduleSideEffects: false };
47104
47426
  }
47105
47427
  else {
47106
47428
  if (!asSrc) {
@@ -49680,26 +50002,27 @@ function createPluginHookUtils(plugins) {
49680
50002
  };
49681
50003
  }
49682
50004
  function getSortedPluginsByHook(hookName, plugins) {
49683
- const pre = [];
49684
- const normal = [];
49685
- const post = [];
50005
+ const sortedPlugins = [];
50006
+ // Use indexes to track and insert the ordered plugins directly in the
50007
+ // resulting array to avoid creating 3 extra temporary arrays per hook
50008
+ let pre = 0, normal = 0, post = 0;
49686
50009
  for (const plugin of plugins) {
49687
50010
  const hook = plugin[hookName];
49688
50011
  if (hook) {
49689
50012
  if (typeof hook === 'object') {
49690
50013
  if (hook.order === 'pre') {
49691
- pre.push(plugin);
50014
+ sortedPlugins.splice(pre++, 0, plugin);
49692
50015
  continue;
49693
50016
  }
49694
50017
  if (hook.order === 'post') {
49695
- post.push(plugin);
50018
+ sortedPlugins.splice(pre + normal + post++, 0, plugin);
49696
50019
  continue;
49697
50020
  }
49698
50021
  }
49699
- normal.push(plugin);
50022
+ sortedPlugins.splice(pre + normal++, 0, plugin);
49700
50023
  }
49701
50024
  }
49702
- return [...pre, ...normal, ...post];
50025
+ return sortedPlugins;
49703
50026
  }
49704
50027
  function getHookHandler(hook) {
49705
50028
  return (typeof hook === 'object' ? hook.handler : hook);
@@ -53076,6 +53399,7 @@ async function loadAndTransform(id, url, server, options, timestamp, mod, resolv
53076
53399
  const sourcemapPath = `${mod.file}.map`;
53077
53400
  applySourcemapIgnoreList(normalizedMap, sourcemapPath, config.server.sourcemapIgnoreList, logger);
53078
53401
  if (path$o.isAbsolute(mod.file)) {
53402
+ let modDirname;
53079
53403
  for (let sourcesIndex = 0; sourcesIndex < normalizedMap.sources.length; ++sourcesIndex) {
53080
53404
  const sourcePath = normalizedMap.sources[sourcesIndex];
53081
53405
  if (sourcePath) {
@@ -53083,7 +53407,8 @@ async function loadAndTransform(id, url, server, options, timestamp, mod, resolv
53083
53407
  // to resolve and display them in a meaningful way (rather than
53084
53408
  // with absolute paths).
53085
53409
  if (path$o.isAbsolute(sourcePath)) {
53086
- normalizedMap.sources[sourcesIndex] = path$o.relative(path$o.dirname(mod.file), sourcePath);
53410
+ modDirname ??= path$o.dirname(mod.file);
53411
+ normalizedMap.sources[sourcesIndex] = path$o.relative(modDirname, sourcePath);
53087
53412
  }
53088
53413
  }
53089
53414
  }
@@ -53100,12 +53425,8 @@ async function loadAndTransform(id, url, server, options, timestamp, mod, resolv
53100
53425
  });
53101
53426
  // Only cache the result if the module wasn't invalidated while it was
53102
53427
  // being processed, so it is re-processed next time if it is stale
53103
- if (timestamp > mod.lastInvalidationTimestamp) {
53104
- if (ssr)
53105
- mod.ssrTransformResult = result;
53106
- else
53107
- mod.transformResult = result;
53108
- }
53428
+ if (timestamp > mod.lastInvalidationTimestamp)
53429
+ moduleGraph.updateModuleTransformResult(mod, result, ssr);
53109
53430
  return result;
53110
53431
  }
53111
53432
  function createConvertSourceMapReadMap(originalFileName) {
@@ -53182,12 +53503,8 @@ async function handleModuleSoftInvalidation(mod, ssr, timestamp, server) {
53182
53503
  }
53183
53504
  // Only cache the result if the module wasn't invalidated while it was
53184
53505
  // being processed, so it is re-processed next time if it is stale
53185
- if (timestamp > mod.lastInvalidationTimestamp) {
53186
- if (ssr)
53187
- mod.ssrTransformResult = result;
53188
- else
53189
- mod.transformResult = result;
53190
- }
53506
+ if (timestamp > mod.lastInvalidationTimestamp)
53507
+ server.moduleGraph.updateModuleTransformResult(mod, result, ssr);
53191
53508
  return result;
53192
53509
  }
53193
53510
 
@@ -58155,8 +58472,8 @@ var extension$1 = { format: format$1, parse: parse$2 };
58155
58472
  /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex|Readable$" }] */
58156
58473
 
58157
58474
  const EventEmitter$1 = require$$0$5;
58158
- const https$2 = require$$1$2;
58159
- const http$3 = require$$1$1;
58475
+ const https$2 = require$$1$1;
58476
+ const http$3 = require$$1;
58160
58477
  const net = require$$4$1;
58161
58478
  const tls = require$$4$2;
58162
58479
  const { randomBytes, createHash: createHash$1 } = require$$0$a;
@@ -59550,7 +59867,7 @@ var subprotocol$1 = { parse };
59550
59867
  /* eslint no-unused-vars: ["error", { "varsIgnorePattern": "^Duplex$" }] */
59551
59868
 
59552
59869
  const EventEmitter = require$$0$5;
59553
- const http$2 = require$$1$1;
59870
+ const http$2 = require$$1;
59554
59871
  const { createHash } = require$$0$a;
59555
59872
 
59556
59873
  const extension = extension$1;
@@ -61155,8 +61472,8 @@ var debug_1 = function () {
61155
61472
 
61156
61473
  var url = require$$0$9;
61157
61474
  var URL$1 = url.URL;
61158
- var http$1 = require$$1$1;
61159
- var https$1 = require$$1$2;
61475
+ var http$1 = require$$1;
61476
+ var https$1 = require$$1$1;
61160
61477
  var Writable = require$$0$7.Writable;
61161
61478
  var assert = require$$5;
61162
61479
  var debug$5 = debug_1;
@@ -61749,8 +62066,8 @@ followRedirects$1.exports.wrap = wrap;
61749
62066
 
61750
62067
  var followRedirectsExports = followRedirects$1.exports;
61751
62068
 
61752
- var httpNative = require$$1$1,
61753
- httpsNative = require$$1$2,
62069
+ var httpNative = require$$1,
62070
+ httpsNative = require$$1$1,
61754
62071
  web_o = webOutgoing,
61755
62072
  common$1 = common$3,
61756
62073
  followRedirects = followRedirectsExports;
@@ -61944,8 +62261,8 @@ var webIncoming = {
61944
62261
 
61945
62262
  };
61946
62263
 
61947
- var http = require$$1$1,
61948
- https = require$$1$2,
62264
+ var http = require$$1,
62265
+ https = require$$1$1,
61949
62266
  common = common$3;
61950
62267
 
61951
62268
  /*!
@@ -62112,8 +62429,8 @@ var wsIncoming = {
62112
62429
  extend = require$$0$6._extend,
62113
62430
  parse_url = require$$0$9.parse,
62114
62431
  EE3 = eventemitter3Exports,
62115
- http = require$$1$1,
62116
- https = require$$1$2,
62432
+ http = require$$1,
62433
+ https = require$$1$1,
62117
62434
  web = webIncoming,
62118
62435
  ws = wsIncoming;
62119
62436
 
@@ -62616,6 +62933,32 @@ function send(req, res, content, type, options) {
62616
62933
 
62617
62934
  const debugCache = createDebugger('vite:cache');
62618
62935
  const knownIgnoreList = new Set(['/', '/favicon.ico']);
62936
+ /**
62937
+ * A middleware that short-circuits the middleware chain to serve cached transformed modules
62938
+ */
62939
+ function cachedTransformMiddleware(server) {
62940
+ // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
62941
+ return function viteCachedTransformMiddleware(req, res, next) {
62942
+ // check if we can return 304 early
62943
+ const ifNoneMatch = req.headers['if-none-match'];
62944
+ if (ifNoneMatch) {
62945
+ const moduleByEtag = server.moduleGraph.getModuleByEtag(ifNoneMatch);
62946
+ if (moduleByEtag?.transformResult?.etag === ifNoneMatch) {
62947
+ // For direct CSS requests, if the same CSS file is imported in a module,
62948
+ // the browser sends the request for the direct CSS request with the etag
62949
+ // from the imported CSS module. We ignore the etag in this case.
62950
+ const mixedEtag = !req.headers.accept?.includes('text/css') &&
62951
+ isDirectRequest(moduleByEtag.url);
62952
+ if (!mixedEtag) {
62953
+ debugCache?.(`[304] ${prettifyUrl(req.url, server.config.root)}`);
62954
+ res.statusCode = 304;
62955
+ return res.end();
62956
+ }
62957
+ }
62958
+ }
62959
+ next();
62960
+ };
62961
+ }
62619
62962
  function transformMiddleware(server) {
62620
62963
  // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...`
62621
62964
  // check if public dir is inside root dir
@@ -62702,15 +63045,6 @@ function transformMiddleware(server) {
62702
63045
  req.headers.accept?.includes('text/css')) {
62703
63046
  url = injectQuery(url, 'direct');
62704
63047
  }
62705
- // check if we can return 304 early
62706
- const ifNoneMatch = req.headers['if-none-match'];
62707
- if (ifNoneMatch &&
62708
- (await server.moduleGraph.getModuleByUrl(url, false))?.transformResult
62709
- ?.etag === ifNoneMatch) {
62710
- debugCache?.(`[304] ${prettifyUrl(url, server.config.root)}`);
62711
- res.statusCode = 304;
62712
- return res.end();
62713
- }
62714
63048
  // resolve, load and transform using the plugin container
62715
63049
  const result = await transformRequest(url, server, {
62716
63050
  html: req.headers.accept?.includes('text/html'),
@@ -63173,6 +63507,7 @@ class ModuleGraph {
63173
63507
  resolveId;
63174
63508
  urlToModuleMap = new Map();
63175
63509
  idToModuleMap = new Map();
63510
+ etagToModuleMap = new Map();
63176
63511
  // a single file may corresponds to multiple modules with different queries
63177
63512
  fileToModulesMap = new Map();
63178
63513
  safeModulesPath = new Set();
@@ -63247,6 +63582,9 @@ class ModuleGraph {
63247
63582
  }
63248
63583
  // Don't invalidate mod.info and mod.meta, as they are part of the processing pipeline
63249
63584
  // Invalidating the transform result is enough to ensure this module is re-processed next time it is requested
63585
+ const etag = mod.transformResult?.etag;
63586
+ if (etag)
63587
+ this.etagToModuleMap.delete(etag);
63250
63588
  mod.transformResult = null;
63251
63589
  mod.ssrTransformResult = null;
63252
63590
  mod.ssrModule = null;
@@ -63425,6 +63763,22 @@ class ModuleGraph {
63425
63763
  }
63426
63764
  return this._resolveUrl(url, ssr);
63427
63765
  }
63766
+ updateModuleTransformResult(mod, result, ssr) {
63767
+ if (ssr) {
63768
+ mod.ssrTransformResult = result;
63769
+ }
63770
+ else {
63771
+ const prevEtag = mod.transformResult?.etag;
63772
+ if (prevEtag)
63773
+ this.etagToModuleMap.delete(prevEtag);
63774
+ mod.transformResult = result;
63775
+ if (result?.etag)
63776
+ this.etagToModuleMap.set(result.etag, mod);
63777
+ }
63778
+ }
63779
+ getModuleByEtag(etag) {
63780
+ return this.etagToModuleMap.get(etag);
63781
+ }
63428
63782
  /**
63429
63783
  * @internal
63430
63784
  */
@@ -63791,7 +64145,10 @@ async function _createServer(inlineConfig = {}, options) {
63791
64145
  _importGlobMap: new Map(),
63792
64146
  _forceOptimizeOnRestart: false,
63793
64147
  _pendingRequests: new Map(),
63794
- _fsDenyGlob: picomatch$4(config.server.fs.deny, { matchBase: true }),
64148
+ _fsDenyGlob: picomatch$4(config.server.fs.deny, {
64149
+ matchBase: true,
64150
+ nocase: true,
64151
+ }),
63795
64152
  _shortcutsOptions: undefined,
63796
64153
  };
63797
64154
  // maintain consistency with the server instance after restarting.
@@ -63838,7 +64195,17 @@ async function _createServer(inlineConfig = {}, options) {
63838
64195
  await container.watchChange(file, { event: isUnlink ? 'delete' : 'create' });
63839
64196
  if (publicDir && publicFiles) {
63840
64197
  if (file.startsWith(publicDir)) {
63841
- publicFiles[isUnlink ? 'delete' : 'add'](file.slice(publicDir.length));
64198
+ const path = file.slice(publicDir.length);
64199
+ publicFiles[isUnlink ? 'delete' : 'add'](path);
64200
+ if (!isUnlink) {
64201
+ const moduleWithSamePath = await moduleGraph.getModuleByUrl(path);
64202
+ const etag = moduleWithSamePath?.transformResult?.etag;
64203
+ if (etag) {
64204
+ // The public file should win on the next request over a module with the
64205
+ // same path. Prevent the transform etag fast path from serving the module
64206
+ moduleGraph.etagToModuleMap.delete(etag);
64207
+ }
64208
+ }
63842
64209
  }
63843
64210
  }
63844
64211
  await handleFileAddUnlink(file, server, isUnlink);
@@ -63889,6 +64256,7 @@ async function _createServer(inlineConfig = {}, options) {
63889
64256
  if (cors !== false) {
63890
64257
  middlewares.use(corsMiddleware(typeof cors === 'boolean' ? {} : cors));
63891
64258
  }
64259
+ middlewares.use(cachedTransformMiddleware(server));
63892
64260
  // proxy
63893
64261
  const { proxy } = serverConfig;
63894
64262
  if (proxy) {