@crxjs/vite-plugin 2.6.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +170 -32
- package/package.json +7 -9
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { simple } from 'acorn-walk';
|
|
2
|
-
import { createHash } from 'crypto';
|
|
2
|
+
import { createHash, randomBytes } from 'crypto';
|
|
3
3
|
import debug$5 from 'debug';
|
|
4
4
|
import { join, normalize, dirname, basename, isAbsolute, relative, resolve, parse as parse$1 } from 'pathe';
|
|
5
|
-
import { Subject, filter, ReplaySubject, switchMap, of, startWith, map, BehaviorSubject, mergeMap, firstValueFrom, takeUntil, first, toArray, retry, concatWith, Subscription, buffer } from 'rxjs';
|
|
5
|
+
import { Subject, filter, ReplaySubject, switchMap, of, startWith, tap, debounceTime, map, share, BehaviorSubject, mergeMap, firstValueFrom, takeUntil, first, toArray, retry, concatWith, Subscription, buffer } from 'rxjs';
|
|
6
6
|
import fsx from 'fs-extra';
|
|
7
7
|
import { performance } from 'perf_hooks';
|
|
8
8
|
import { rollup } from 'rollup';
|
|
@@ -58,7 +58,7 @@ function isCrxPlugin(p) {
|
|
|
58
58
|
return !!p && typeof p === "object" && !(p instanceof Promise) && !Array.isArray(p) && p.name.startsWith("crx:");
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
var workerHmrClient = "const ownOrigin = `chrome-extension://${chrome.runtime.id}`;\nself.addEventListener(\"fetch\", (fetchEvent) => {\n const url = new URL(fetchEvent.request.url);\n if (url.origin === ownOrigin) {\n fetchEvent.respondWith(sendToServer(fetchEvent.request));\n }\n});\nasync function sendToServer(req) {\n const url = new URL(req.url);\n const requestHeaders = new Headers(req.headers);\n url.protocol = __SERVER_PROTO__ + \":\";\n url.host = \"localhost\";\n url.port = __SERVER_PORT__;\n url.searchParams.set(\"t\", Date.now().toString());\n const response = await fetch(url.href.replace(/=$|=(?=&)/g, \"\"), {\n headers: requestHeaders\n });\n const responseHeaders = new Headers(response.headers);\n responseHeaders.set(\n \"Content-Type\",\n responseHeaders.get(\"Content-Type\") ?? \"text/javascript\"\n );\n responseHeaders.set(\n \"Cache-Control\",\n responseHeaders.get(\"Cache-Control\") ?? \"\"\n );\n return new Response(response.body, {\n headers: responseHeaders\n });\n}\nconst ports = /* @__PURE__ */ new Set();\
|
|
61
|
+
var workerHmrClient = "const crxClientPortName = `@crx/client:${__CRX_HMR_TOKEN__}`;\nconst ownOrigin = `chrome-extension://${chrome.runtime.id}`;\nself.addEventListener(\"fetch\", (fetchEvent) => {\n const url = new URL(fetchEvent.request.url);\n if (url.origin === ownOrigin) {\n fetchEvent.respondWith(sendToServer(fetchEvent.request));\n }\n});\nasync function sendToServer(req) {\n const url = new URL(req.url);\n const requestHeaders = new Headers(req.headers);\n url.protocol = __SERVER_PROTO__ + \":\";\n url.host = \"localhost\";\n url.port = __SERVER_PORT__;\n url.searchParams.set(\"t\", Date.now().toString());\n const response = await fetch(url.href.replace(/=$|=(?=&)/g, \"\"), {\n headers: requestHeaders\n });\n const responseHeaders = new Headers(response.headers);\n responseHeaders.set(\n \"Content-Type\",\n responseHeaders.get(\"Content-Type\") ?? \"text/javascript\"\n );\n responseHeaders.set(\n \"Cache-Control\",\n responseHeaders.get(\"Cache-Control\") ?? \"\"\n );\n return new Response(response.body, {\n headers: responseHeaders\n });\n}\nconst ports = /* @__PURE__ */ new Set();\nfunction isExternalSenderAllowed(port) {\n return !port.sender?.id || port.sender.id === chrome.runtime.id;\n}\nfunction handlePort(port, { external = false } = {}) {\n if (port.name === crxClientPortName && (!external || isExternalSenderAllowed(port))) {\n ports.add(port);\n port.onDisconnect.addListener((port2) => {\n if (chrome.runtime.lastError) {\n console.error(chrome.runtime.lastError);\n }\n ports.delete(port2);\n });\n port.onMessage.addListener((message) => {\n });\n port.postMessage({ data: JSON.stringify({ type: \"connected\" }) });\n }\n}\nchrome.runtime.onConnect.addListener(handlePort);\nchrome.runtime.onConnectExternal.addListener(\n (port) => handlePort(port, { external: true })\n);\nfunction notifyContentScripts(payload) {\n const data = JSON.stringify(payload);\n for (const port of ports)\n port.postMessage({ data });\n}\nconsole.log(\"[vite] connecting...\");\nconst socketProtocol = __HMR_PROTOCOL__ || (location.protocol === \"https:\" ? \"wss\" : \"ws\");\nconst socketToken = __HMR_TOKEN__;\nconst socketHost = `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`;\nconst socket = new WebSocket(\n `${socketProtocol}://${socketHost}?token=${socketToken}`,\n \"vite-hmr\"\n);\nconst base = __BASE__ || \"/\";\nsocket.addEventListener(\"message\", async ({ data }) => {\n handleSocketMessage(JSON.parse(data));\n});\nfunction isCrxHmrPayload(x) {\n return x.type === \"custom\" && x.event.startsWith(\"crx:\");\n}\nfunction handleSocketMessage(payload) {\n if (isCrxHmrPayload(payload)) {\n handleCrxHmrPayload(payload);\n } else if (payload.type === \"connected\") {\n console.log(`[vite] connected.`);\n const interval = setInterval(() => socket.send(\"ping\"), __HMR_TIMEOUT__);\n socket.addEventListener(\"close\", () => clearInterval(interval));\n }\n}\nfunction handleCrxHmrPayload(payload) {\n if (!__LIVE_RELOAD__) {\n if (payload.event === \"crx:runtime-reload\") {\n console.log(\"[crx] runtime reload suppressed (liveReload disabled)\");\n }\n return;\n }\n notifyContentScripts(payload);\n switch (payload.event) {\n case \"crx:runtime-reload\":\n console.log(\"[crx] runtime reload\");\n chrome.runtime.reload();\n break;\n }\n}\nasync function waitForSuccessfulPing(ms = 1e3) {\n while (true) {\n try {\n await fetch(`${base}__vite_ping`);\n break;\n } catch (e) {\n await new Promise((resolve) => setTimeout(resolve, ms));\n }\n }\n}\nsocket.addEventListener(\"close\", async ({ wasClean }) => {\n if (wasClean)\n return;\n console.log(`[vite] server connection lost. polling for restart...`);\n await waitForSuccessfulPing();\n if (__LIVE_RELOAD__) {\n handleCrxHmrPayload({\n type: \"custom\",\n event: \"crx:runtime-reload\"\n });\n } else {\n console.log(\n \"[crx] server reconnected, skipping reload (liveReload disabled)\"\n );\n }\n});\n";
|
|
62
62
|
|
|
63
63
|
const _debug = (id) => debug$5("crx").extend(id);
|
|
64
64
|
const hash = (data, length = 5) => createHash("sha1").update(data).digest("base64").replace(/[^A-Za-z0-9]/g, "").slice(0, length);
|
|
@@ -274,6 +274,18 @@ async function fileReady(script) {
|
|
|
274
274
|
await Promise.all(deps.map(fileReady));
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
const crxHmrTokens = /* @__PURE__ */ new WeakMap();
|
|
278
|
+
function getCrxHmrToken(config) {
|
|
279
|
+
if (config.webSocketToken)
|
|
280
|
+
return config.webSocketToken;
|
|
281
|
+
let token = crxHmrTokens.get(config);
|
|
282
|
+
if (!token) {
|
|
283
|
+
token = randomBytes(16).toString("hex");
|
|
284
|
+
crxHmrTokens.set(config, token);
|
|
285
|
+
}
|
|
286
|
+
return token;
|
|
287
|
+
}
|
|
288
|
+
|
|
277
289
|
const viteClientId = "/@vite/client";
|
|
278
290
|
const customElementsId = "/@webcomponents/custom-elements";
|
|
279
291
|
const contentHmrPortId = "/@crx/client-port";
|
|
@@ -312,7 +324,12 @@ const pluginBackground = () => {
|
|
|
312
324
|
if (id === workerClientId) {
|
|
313
325
|
const base = `${config.server.https ? "https" : "http"}://localhost:${config.server.port}/`;
|
|
314
326
|
return defineClientValues(
|
|
315
|
-
workerHmrClient.replace("__BASE__", JSON.stringify(base)).replace("__LIVE_RELOAD__", JSON.stringify(liveReload))
|
|
327
|
+
workerHmrClient.replace("__BASE__", JSON.stringify(base)).replace("__LIVE_RELOAD__", JSON.stringify(liveReload)).replace(
|
|
328
|
+
"__CRX_HMR_TOKEN__",
|
|
329
|
+
JSON.stringify(
|
|
330
|
+
getCrxHmrToken(config)
|
|
331
|
+
)
|
|
332
|
+
),
|
|
316
333
|
config
|
|
317
334
|
);
|
|
318
335
|
}
|
|
@@ -430,11 +447,11 @@ function pluginExtensionCors() {
|
|
|
430
447
|
};
|
|
431
448
|
}
|
|
432
449
|
|
|
433
|
-
var contentHmrPort = "
|
|
450
|
+
var contentHmrPort = "const crxClientPortName = `@crx/client:${__CRX_HMR_TOKEN__}`;\nfunction hasOwnExtensionRuntime(runtime2, extensionId2) {\n try {\n return new URL(runtime2.getURL(\"\")).host === extensionId2;\n } catch {\n return false;\n }\n}\nconst runtime = typeof chrome === \"undefined\" ? void 0 : chrome.runtime;\nconst extensionId = new URL(import.meta.url).host;\nconst connectsToOwnRuntime = runtime ? hasOwnExtensionRuntime(runtime, extensionId) : false;\nfunction isCrxHMRPayload(x) {\n return x.type === \"custom\" && x.event.startsWith(\"crx:\");\n}\nclass HMRPort {\n port;\n callbacks = /* @__PURE__ */ new Map();\n constructor() {\n setInterval(() => {\n try {\n this.port?.postMessage({ data: \"ping\" });\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Extension context invalidated.\")) {\n location.reload();\n } else\n throw error;\n }\n }, __CRX_HMR_TIMEOUT__);\n setInterval(this.initPort, 5 * 60 * 1e3);\n this.initPort();\n }\n initPort = () => {\n if (!runtime)\n throw new Error(\"[crx] chrome.runtime is not available\");\n const connectInfo = { name: crxClientPortName };\n this.port?.disconnect();\n this.port = connectsToOwnRuntime ? runtime.connect(connectInfo) : runtime.connect(extensionId, connectInfo);\n this.port.onDisconnect.addListener(this.handleDisconnect.bind(this));\n this.port.onMessage.addListener(this.handleMessage.bind(this));\n this.port.postMessage({ type: \"connected\" });\n };\n handleDisconnect = () => {\n if (this.callbacks.has(\"close\"))\n for (const cb of this.callbacks.get(\"close\")) {\n cb({ wasClean: true });\n }\n };\n handleMessage = (message) => {\n const forward = (data) => {\n if (this.callbacks.has(\"message\"))\n for (const cb of this.callbacks.get(\"message\")) {\n cb({ data });\n }\n };\n const payload = JSON.parse(message.data);\n if (isCrxHMRPayload(payload)) {\n if (payload.event === \"crx:runtime-reload\") {\n if (__CRX_LIVE_RELOAD__) {\n console.log(\"[crx] runtime reload\");\n setTimeout(() => location.reload(), 500);\n } else {\n console.log(\"[crx] runtime reload suppressed (liveReload disabled)\");\n }\n } else {\n forward(JSON.stringify(payload.data));\n }\n } else {\n forward(message.data);\n }\n };\n addEventListener = (event, callback) => {\n const cbs = this.callbacks.get(event) ?? /* @__PURE__ */ new Set();\n cbs.add(callback);\n this.callbacks.set(event, cbs);\n };\n send = (data) => {\n if (this.port)\n this.port.postMessage({ data });\n else\n throw new Error(\"HMRPort is not initialized\");\n };\n}\n\nexport { HMRPort };\n";
|
|
434
451
|
|
|
435
452
|
var contentDevLoader = "(function () {\n 'use strict';\n\n const injectTime = performance.now();\n (async () => {\n if (__PREAMBLE__)\n await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__PREAMBLE__)\n );\n await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__CLIENT__)\n );\n const { onExecute } = await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__SCRIPT__)\n );\n onExecute?.({ perf: { injectTime, loadTime: performance.now() - injectTime } });\n })().catch(console.error);\n\n})();\n";
|
|
436
453
|
|
|
437
|
-
var contentDevMainLoader = "(function () {\n 'use strict';\n\n const injectTime = performance.now();\n (async () => {\n console.warn(
|
|
454
|
+
var contentDevMainLoader = "(function () {\n 'use strict';\n\n const injectTime = performance.now();\n (async () => {\n try {\n if (__PREAMBLE__)\n await import(\n /* @vite-ignore */\n __PREAMBLE__\n );\n await import(\n /* @vite-ignore */\n __CLIENT__\n );\n } catch (error) {\n console.warn(\"[crx] MAIN world HMR client failed to load\", error);\n }\n const { onExecute } = await import(\n /* @vite-ignore */\n __SCRIPT__\n );\n onExecute?.({\n perf: { injectTime, loadTime: performance.now() - injectTime }\n });\n })().catch(console.error);\n\n})();\n";
|
|
438
455
|
|
|
439
456
|
var contentProLoader = "(function () {\n 'use strict';\n\n const injectTime = performance.now();\n (async () => {\n const { onExecute } = await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__SCRIPT__)\n );\n onExecute?.({ perf: { injectTime, loadTime: performance.now() - injectTime } });\n })().catch(console.error);\n\n})();\n";
|
|
440
457
|
|
|
@@ -474,11 +491,15 @@ function createProLoader({ fileName }) {
|
|
|
474
491
|
return contentProLoader.replace(/__SCRIPT__/g, JSON.stringify(fileName));
|
|
475
492
|
}
|
|
476
493
|
function createDevMainLoader({
|
|
494
|
+
preamble,
|
|
495
|
+
client,
|
|
477
496
|
fileName
|
|
478
497
|
}) {
|
|
479
|
-
return contentDevMainLoader.replace(/__SCRIPT__/g, JSON.stringify(fileName)).replace(/__TIMESTAMP__/g, JSON.stringify(Date.now()));
|
|
498
|
+
return contentDevMainLoader.replace(/__PREAMBLE__/g, JSON.stringify(preamble)).replace(/__CLIENT__/g, JSON.stringify(client)).replace(/__SCRIPT__/g, JSON.stringify(fileName)).replace(/__TIMESTAMP__/g, JSON.stringify(Date.now()));
|
|
480
499
|
}
|
|
481
|
-
function createProMainLoader({
|
|
500
|
+
function createProMainLoader({
|
|
501
|
+
fileName
|
|
502
|
+
}) {
|
|
482
503
|
return contentProMainLoader.replace(/__SCRIPT__/g, JSON.stringify(fileName));
|
|
483
504
|
}
|
|
484
505
|
|
|
@@ -515,12 +536,39 @@ fileWriterEvent$.pipe(
|
|
|
515
536
|
filter((e) => e.type === "build_start"),
|
|
516
537
|
switchMap((e) => of(e))
|
|
517
538
|
);
|
|
518
|
-
const
|
|
519
|
-
|
|
520
|
-
|
|
539
|
+
const allFilesReadyDebounceMs = 100;
|
|
540
|
+
let currentAllFilesReadyGeneration = 0;
|
|
541
|
+
let completedAllFilesReadyGeneration = 0;
|
|
542
|
+
let lastAllFilesReadyResults;
|
|
543
|
+
const allFilesReadyState$ = buildEnd$.pipe(
|
|
521
544
|
switchMap(
|
|
522
|
-
(
|
|
523
|
-
|
|
545
|
+
() => outputFiles.change$.pipe(
|
|
546
|
+
startWith({ type: "start" }),
|
|
547
|
+
tap(() => {
|
|
548
|
+
currentAllFilesReadyGeneration += 1;
|
|
549
|
+
}),
|
|
550
|
+
debounceTime(allFilesReadyDebounceMs)
|
|
551
|
+
)
|
|
552
|
+
),
|
|
553
|
+
map(() => ({
|
|
554
|
+
generation: currentAllFilesReadyGeneration,
|
|
555
|
+
files: [...outputFiles.values()]
|
|
556
|
+
})),
|
|
557
|
+
switchMap(async ({ generation, files }) => {
|
|
558
|
+
const seen = /* @__PURE__ */ new Set();
|
|
559
|
+
const results = await Promise.allSettled(
|
|
560
|
+
files.map((file) => waitForOutputFile(file, seen))
|
|
561
|
+
);
|
|
562
|
+
return { generation, results };
|
|
563
|
+
}),
|
|
564
|
+
tap(({ generation, results }) => {
|
|
565
|
+
completedAllFilesReadyGeneration = generation;
|
|
566
|
+
lastAllFilesReadyResults = results;
|
|
567
|
+
}),
|
|
568
|
+
share()
|
|
569
|
+
);
|
|
570
|
+
const allFilesReady$ = allFilesReadyState$.pipe(
|
|
571
|
+
map(({ results }) => results)
|
|
524
572
|
);
|
|
525
573
|
async function waitForOutputFile(file, seen = /* @__PURE__ */ new Set()) {
|
|
526
574
|
if (seen.has(file))
|
|
@@ -529,6 +577,18 @@ async function waitForOutputFile(file, seen = /* @__PURE__ */ new Set()) {
|
|
|
529
577
|
const { deps } = await file.file;
|
|
530
578
|
await Promise.all(deps.map((dep) => waitForOutputFile(dep, seen)));
|
|
531
579
|
}
|
|
580
|
+
async function waitForAllFilesReadyResults() {
|
|
581
|
+
const targetGeneration = currentAllFilesReadyGeneration;
|
|
582
|
+
if (lastAllFilesReadyResults && completedAllFilesReadyGeneration >= targetGeneration) {
|
|
583
|
+
return lastAllFilesReadyResults;
|
|
584
|
+
}
|
|
585
|
+
const { results } = await firstValueFrom(
|
|
586
|
+
allFilesReadyState$.pipe(
|
|
587
|
+
filter(({ generation }) => generation >= targetGeneration)
|
|
588
|
+
)
|
|
589
|
+
);
|
|
590
|
+
return results;
|
|
591
|
+
}
|
|
532
592
|
const timestamp$ = new BehaviorSubject(Date.now());
|
|
533
593
|
allFilesReady$.subscribe(() => {
|
|
534
594
|
timestamp$.next(Date.now());
|
|
@@ -618,14 +678,16 @@ ${sourceMap}
|
|
|
618
678
|
mergeMap(async ({ target, code, deps }) => {
|
|
619
679
|
await lexer.init;
|
|
620
680
|
const [imports] = lexer.parse(code, fileName);
|
|
621
|
-
const
|
|
681
|
+
const isSelfDependency = (id) => getFileName({ type: "module", id }) === fileName;
|
|
682
|
+
const depSet = new Set(deps.filter((id) => !isSelfDependency(id)));
|
|
622
683
|
const magic = new MagicString(code);
|
|
623
684
|
for (const i of imports)
|
|
624
685
|
if (i.n) {
|
|
625
|
-
|
|
626
|
-
|
|
686
|
+
const depFileName = getFileName({ type: "module", id: i.n });
|
|
687
|
+
if (!isSelfDependency(i.n))
|
|
688
|
+
depSet.add(i.n);
|
|
627
689
|
const fullImport = code.substring(i.s, i.e);
|
|
628
|
-
magic.overwrite(i.s, i.e, fullImport.replace(i.n, `/${
|
|
690
|
+
magic.overwrite(i.s, i.e, fullImport.replace(i.n, `/${depFileName}`));
|
|
629
691
|
}
|
|
630
692
|
return { target, source: magic.toString(), deps: [...depSet] };
|
|
631
693
|
})
|
|
@@ -731,7 +793,7 @@ function prepIifeScript(fileName, script) {
|
|
|
731
793
|
);
|
|
732
794
|
}
|
|
733
795
|
async function allFilesReady() {
|
|
734
|
-
await
|
|
796
|
+
await waitForAllFilesReadyResults();
|
|
735
797
|
}
|
|
736
798
|
|
|
737
799
|
const { outputFile } = fsx;
|
|
@@ -856,6 +918,37 @@ async function write(fileId) {
|
|
|
856
918
|
return { start: start2, close: close2, deps };
|
|
857
919
|
}
|
|
858
920
|
|
|
921
|
+
function asRelativeImport(fromFileName, toFileName) {
|
|
922
|
+
const path = relative(dirname(fromFileName), toFileName);
|
|
923
|
+
return path.startsWith(".") ? path : `./${path}`;
|
|
924
|
+
}
|
|
925
|
+
function getExternallyConnectableMatch(match) {
|
|
926
|
+
if (match === "<all_urls>")
|
|
927
|
+
return null;
|
|
928
|
+
const parsed = /^(\*|https?):\/\/([^/]+)\/.*$/.exec(match);
|
|
929
|
+
if (!parsed)
|
|
930
|
+
return null;
|
|
931
|
+
const [, , host] = parsed;
|
|
932
|
+
if (host === "*")
|
|
933
|
+
return null;
|
|
934
|
+
return match;
|
|
935
|
+
}
|
|
936
|
+
function getExternallyConnectableMatches(matches) {
|
|
937
|
+
const result = /* @__PURE__ */ new Set();
|
|
938
|
+
const unsupported = /* @__PURE__ */ new Set();
|
|
939
|
+
for (const match of matches) {
|
|
940
|
+
const externallyConnectableMatch = getExternallyConnectableMatch(match);
|
|
941
|
+
if (externallyConnectableMatch) {
|
|
942
|
+
result.add(externallyConnectableMatch);
|
|
943
|
+
} else {
|
|
944
|
+
unsupported.add(match);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
return {
|
|
948
|
+
matches: [...result],
|
|
949
|
+
unsupported: [...unsupported]
|
|
950
|
+
};
|
|
951
|
+
}
|
|
859
952
|
const pluginContentScripts = () => {
|
|
860
953
|
const pluginName = "crx:content-scripts";
|
|
861
954
|
let server;
|
|
@@ -864,6 +957,8 @@ const pluginContentScripts = () => {
|
|
|
864
957
|
let liveReload = true;
|
|
865
958
|
let sub = new Subscription();
|
|
866
959
|
const worldMainIds = /* @__PURE__ */ new Set();
|
|
960
|
+
const worldMainExternallyConnectableMatches = /* @__PURE__ */ new Set();
|
|
961
|
+
const unsupportedWorldMainExternallyConnectableMatches = /* @__PURE__ */ new Set();
|
|
867
962
|
const findWorldMainIds = async (config, env) => {
|
|
868
963
|
const { manifest: _manifest } = await getOptions(config);
|
|
869
964
|
const manifest = await (typeof _manifest === "function" ? _manifest(env) : _manifest);
|
|
@@ -872,16 +967,32 @@ const pluginContentScripts = () => {
|
|
|
872
967
|
js.forEach((path) => worldMainIds.add(prefix$1("/", path)));
|
|
873
968
|
}
|
|
874
969
|
});
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
970
|
+
(manifest.content_scripts || []).forEach(({ world, matches = [] }) => {
|
|
971
|
+
if (world === "MAIN") {
|
|
972
|
+
const externallyConnectable = getExternallyConnectableMatches(matches);
|
|
973
|
+
externallyConnectable.matches.forEach(
|
|
974
|
+
(match) => worldMainExternallyConnectableMatches.add(match)
|
|
975
|
+
);
|
|
976
|
+
externallyConnectable.unsupported.forEach(
|
|
977
|
+
(match) => unsupportedWorldMainExternallyConnectableMatches.add(match)
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
});
|
|
981
|
+
};
|
|
982
|
+
const warnUnsupportedWorldMainExternallyConnectableMatches = () => {
|
|
983
|
+
if (unsupportedWorldMainExternallyConnectableMatches.size === 0)
|
|
984
|
+
return;
|
|
985
|
+
const name = `[${pluginName}]`;
|
|
986
|
+
const message = pc.yellow(
|
|
987
|
+
[
|
|
988
|
+
`${name} MAIN world HMR requires externally_connectable.matches. CRX cannot auto-add these Chrome-rejected content-script match patterns:`,
|
|
989
|
+
...[...unsupportedWorldMainExternallyConnectableMatches].map(
|
|
990
|
+
(match) => ` ${match}`
|
|
991
|
+
),
|
|
992
|
+
"Add explicit http(s) host addresses to your content script matches during development if you want MAIN world HMR for those pages."
|
|
993
|
+
].join("\r\n")
|
|
994
|
+
);
|
|
995
|
+
console.warn(message);
|
|
885
996
|
};
|
|
886
997
|
return [
|
|
887
998
|
{
|
|
@@ -889,6 +1000,7 @@ const pluginContentScripts = () => {
|
|
|
889
1000
|
apply: "serve",
|
|
890
1001
|
async config(config, env) {
|
|
891
1002
|
await findWorldMainIds(config, env);
|
|
1003
|
+
warnUnsupportedWorldMainExternallyConnectableMatches();
|
|
892
1004
|
const opts = await getOptions(config);
|
|
893
1005
|
const { contentScripts: contentScripts2 = {} } = opts;
|
|
894
1006
|
hmrTimeout = contentScripts2.hmrTimeout ?? 5e3;
|
|
@@ -916,11 +1028,20 @@ const pluginContentScripts = () => {
|
|
|
916
1028
|
preamble = add({ type: "module", id: preambleId });
|
|
917
1029
|
const client = add({ type: "module", id: viteClientId });
|
|
918
1030
|
const file = add({ type: "module", id });
|
|
1031
|
+
const loaderFileName = getFileName({ type: "loader", id });
|
|
919
1032
|
const loader = add({
|
|
920
1033
|
type: "asset",
|
|
921
|
-
id:
|
|
1034
|
+
id: loaderFileName,
|
|
922
1035
|
source: worldMainIds.has(file.id) ? createDevMainLoader({
|
|
923
|
-
|
|
1036
|
+
preamble: preamble.fileName ? asRelativeImport(loaderFileName, preamble.fileName) : "",
|
|
1037
|
+
client: asRelativeImport(
|
|
1038
|
+
loaderFileName,
|
|
1039
|
+
client.fileName
|
|
1040
|
+
),
|
|
1041
|
+
fileName: asRelativeImport(
|
|
1042
|
+
loaderFileName,
|
|
1043
|
+
file.fileName
|
|
1044
|
+
)
|
|
924
1045
|
}) : createDevLoader({
|
|
925
1046
|
preamble: preamble.fileName,
|
|
926
1047
|
client: client.fileName,
|
|
@@ -950,13 +1071,30 @@ const pluginContentScripts = () => {
|
|
|
950
1071
|
return defined;
|
|
951
1072
|
}
|
|
952
1073
|
if (id === contentHmrPortId) {
|
|
953
|
-
const defined = contentHmrPort.replace("__CRX_HMR_TIMEOUT__", JSON.stringify(hmrTimeout)).replace("__CRX_LIVE_RELOAD__", JSON.stringify(liveReload))
|
|
1074
|
+
const defined = contentHmrPort.replace("__CRX_HMR_TIMEOUT__", JSON.stringify(hmrTimeout)).replace("__CRX_LIVE_RELOAD__", JSON.stringify(liveReload)).replace(
|
|
1075
|
+
"__CRX_HMR_TOKEN__",
|
|
1076
|
+
JSON.stringify(
|
|
1077
|
+
getCrxHmrToken(server.config)
|
|
1078
|
+
)
|
|
1079
|
+
);
|
|
954
1080
|
return defined;
|
|
955
1081
|
}
|
|
956
1082
|
},
|
|
957
1083
|
closeBundle() {
|
|
958
1084
|
sub.unsubscribe();
|
|
959
1085
|
sub = new Subscription();
|
|
1086
|
+
},
|
|
1087
|
+
transformCrxManifest(manifest) {
|
|
1088
|
+
if (worldMainExternallyConnectableMatches.size === 0)
|
|
1089
|
+
return null;
|
|
1090
|
+
manifest.externally_connectable = manifest.externally_connectable ?? {};
|
|
1091
|
+
manifest.externally_connectable.matches = [
|
|
1092
|
+
.../* @__PURE__ */ new Set([
|
|
1093
|
+
...manifest.externally_connectable.matches ?? [],
|
|
1094
|
+
...worldMainExternallyConnectableMatches
|
|
1095
|
+
])
|
|
1096
|
+
];
|
|
1097
|
+
return manifest;
|
|
960
1098
|
}
|
|
961
1099
|
},
|
|
962
1100
|
{
|
|
@@ -1735,7 +1873,7 @@ async function prepareVitePayloadForCrx(p) {
|
|
|
1735
1873
|
return update(id).map((file) => file.file);
|
|
1736
1874
|
});
|
|
1737
1875
|
await Promise.all(pendingFiles);
|
|
1738
|
-
await
|
|
1876
|
+
await allFilesReady();
|
|
1739
1877
|
}
|
|
1740
1878
|
return mapVitePayloadForCrx(p);
|
|
1741
1879
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crxjs/vite-plugin",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Build Chrome Extensions with this Vite plugin.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rollup-plugin",
|
|
@@ -54,28 +54,26 @@
|
|
|
54
54
|
],
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@webcomponents/custom-elements": "^1.5.0",
|
|
57
|
-
"acorn-walk": "^8.
|
|
57
|
+
"acorn-walk": "^8.3.5",
|
|
58
58
|
"convert-source-map": "^1.7.0",
|
|
59
59
|
"debug": "^4.3.3",
|
|
60
60
|
"es-module-lexer": "^0.10.0",
|
|
61
|
-
"tinyglobby": "^0.2.
|
|
61
|
+
"tinyglobby": "^0.2.17",
|
|
62
62
|
"fs-extra": "^10.0.1",
|
|
63
63
|
"jsesc": "^3.0.2",
|
|
64
64
|
"magic-string": "^0.30.12",
|
|
65
|
-
"node-html-parser": "^7.0
|
|
65
|
+
"node-html-parser": "^7.1.0",
|
|
66
66
|
"pathe": "^2.0.1",
|
|
67
67
|
"picocolors": "^1.1.1",
|
|
68
|
-
"react-refresh": "^0.13.0",
|
|
69
68
|
"rollup": "2.80.0",
|
|
70
69
|
"rxjs": "7.5.7"
|
|
71
70
|
},
|
|
72
71
|
"devDependencies": {
|
|
73
72
|
"@arethetypeswrong/cli": "0.18.3",
|
|
74
|
-
"@eslint/eslintrc": "3.3.
|
|
73
|
+
"@eslint/eslintrc": "3.3.5",
|
|
75
74
|
"@eslint/js": "9.26.0",
|
|
76
75
|
"@extend-chrome/messages": "1.2.2",
|
|
77
76
|
"@extend-chrome/storage": "1.5.0",
|
|
78
|
-
"@rollup/pluginutils": "^4.1.2",
|
|
79
77
|
"@rollup/plugin-alias": "4.0.4",
|
|
80
78
|
"@rollup/plugin-commonjs": "21.1.0",
|
|
81
79
|
"@rollup/plugin-json": "^5.0.0",
|
|
@@ -84,10 +82,10 @@
|
|
|
84
82
|
"@types/acorn": "4.0.6",
|
|
85
83
|
"@types/chrome": "0.0.237",
|
|
86
84
|
"@types/convert-source-map": "^2.0.0",
|
|
87
|
-
"@types/debug": "4.1.
|
|
85
|
+
"@types/debug": "4.1.13",
|
|
88
86
|
"@types/fs-extra": "9.0.13",
|
|
89
87
|
"@types/jest-image-snapshot": "^5.1.0",
|
|
90
|
-
"@types/jsesc": "3.0.
|
|
88
|
+
"@types/jsesc": "3.0.3",
|
|
91
89
|
"@types/node": "17.0.18",
|
|
92
90
|
"@types/react": "17.0.52",
|
|
93
91
|
"@types/react-dom": "17.0.18",
|