vite-plugin-cross-origin-storage 1.7.0 → 1.8.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/README.md +33 -20
- package/dist/index.js +268 -46
- package/dist/loader.js +8 -7
- package/loader.js +8 -7
- package/package.json +22 -11
package/README.md
CHANGED
|
@@ -95,26 +95,39 @@ export default defineConfig({
|
|
|
95
95
|
|
|
96
96
|
## How It Works
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
98
|
+
### Build Time
|
|
99
|
+
|
|
100
|
+
1. **Magic Externals**: For `include` patterns that resolve to npm package
|
|
101
|
+
names (e.g. `vendor-react` → `react`), the plugin externalizes the package
|
|
102
|
+
from Rollup and uses esbuild to produce a single self-contained ESM bundle.
|
|
103
|
+
This bundle is emitted as a hashed asset (e.g. `assets/react-a1b2c3d4.js`)
|
|
104
|
+
and treated as a managed chunk.
|
|
105
|
+
2. **Import Rewriting**: All inter-chunk imports are rewritten from relative
|
|
106
|
+
paths (`"./chunk.js"`) to bare specifiers (`"coschunk-assets-chunk-js"`).
|
|
107
|
+
This applies to both managed and unmanaged chunks, because managed chunks
|
|
108
|
+
run as Blob URLs and cannot resolve relative paths at runtime.
|
|
109
|
+
3. **Manifest Generation**: A JSON manifest is built containing the base path,
|
|
110
|
+
the entry chunk filename, a map of every managed chunk filename to its
|
|
111
|
+
SHA-256 hash, and a list of unmanaged chunks that need network-URL entries
|
|
112
|
+
in the import map.
|
|
113
|
+
4. **Loader Injection**: The plugin disables the default
|
|
114
|
+
`<script type="module">` entry tag and injects a `<script id="cos-loader">`
|
|
115
|
+
containing the runtime loader with the manifest inlined.
|
|
116
|
+
|
|
117
|
+
### Runtime
|
|
118
|
+
|
|
119
|
+
1. The loader checks for `navigator.crossOriginStorage`.
|
|
120
|
+
2. For each managed chunk it calls
|
|
121
|
+
`navigator.crossOriginStorage.requestFileHandles([{ algorithm: 'SHA-256', value: hash }])`:
|
|
122
|
+
- **Cache hit**: wraps the returned `File` as a Blob URL.
|
|
123
|
+
- **Cache miss**: fetches the chunk from the network, stores it in COS via
|
|
124
|
+
`requestFileHandles(..., { create: true })`, then wraps it as a Blob URL.
|
|
125
|
+
3. Unmanaged chunks receive absolute network URLs.
|
|
126
|
+
4. An `<script type="importmap">` is injected into `<head>` mapping every
|
|
127
|
+
`coschunk-*` bare specifier to its resolved URL.
|
|
128
|
+
5. The entry point is imported via its bare specifier inside a `setTimeout`
|
|
129
|
+
callback so the browser has time to register the import map before the
|
|
130
|
+
first module resolution occurs.
|
|
118
131
|
|
|
119
132
|
## Requirements
|
|
120
133
|
|
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var require_constants = __commonJS({
|
|
|
30
30
|
"use strict";
|
|
31
31
|
var WIN_SLASH = "\\\\/";
|
|
32
32
|
var WIN_NO_SLASH = `[^${WIN_SLASH}]`;
|
|
33
|
+
var DEFAULT_MAX_EXTGLOB_RECURSION = 0;
|
|
33
34
|
var DOT_LITERAL = "\\.";
|
|
34
35
|
var PLUS_LITERAL = "\\+";
|
|
35
36
|
var QMARK_LITERAL = "\\?";
|
|
@@ -80,6 +81,7 @@ var require_constants = __commonJS({
|
|
|
80
81
|
SEP: "\\"
|
|
81
82
|
};
|
|
82
83
|
var POSIX_REGEX_SOURCE = {
|
|
84
|
+
__proto__: null,
|
|
83
85
|
alnum: "a-zA-Z0-9",
|
|
84
86
|
alpha: "a-zA-Z",
|
|
85
87
|
ascii: "\\x00-\\x7F",
|
|
@@ -96,6 +98,7 @@ var require_constants = __commonJS({
|
|
|
96
98
|
xdigit: "A-Fa-f0-9"
|
|
97
99
|
};
|
|
98
100
|
module.exports = {
|
|
101
|
+
DEFAULT_MAX_EXTGLOB_RECURSION,
|
|
99
102
|
MAX_LENGTH: 1024 * 64,
|
|
100
103
|
POSIX_REGEX_SOURCE,
|
|
101
104
|
// regular expressions
|
|
@@ -646,6 +649,213 @@ var require_parse = __commonJS({
|
|
|
646
649
|
var syntaxError = (type, char) => {
|
|
647
650
|
return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
|
|
648
651
|
};
|
|
652
|
+
var splitTopLevel = (input) => {
|
|
653
|
+
const parts = [];
|
|
654
|
+
let bracket = 0;
|
|
655
|
+
let paren = 0;
|
|
656
|
+
let quote = 0;
|
|
657
|
+
let value = "";
|
|
658
|
+
let escaped = false;
|
|
659
|
+
for (const ch of input) {
|
|
660
|
+
if (escaped === true) {
|
|
661
|
+
value += ch;
|
|
662
|
+
escaped = false;
|
|
663
|
+
continue;
|
|
664
|
+
}
|
|
665
|
+
if (ch === "\\") {
|
|
666
|
+
value += ch;
|
|
667
|
+
escaped = true;
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
if (ch === '"') {
|
|
671
|
+
quote = quote === 1 ? 0 : 1;
|
|
672
|
+
value += ch;
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
if (quote === 0) {
|
|
676
|
+
if (ch === "[") {
|
|
677
|
+
bracket++;
|
|
678
|
+
} else if (ch === "]" && bracket > 0) {
|
|
679
|
+
bracket--;
|
|
680
|
+
} else if (bracket === 0) {
|
|
681
|
+
if (ch === "(") {
|
|
682
|
+
paren++;
|
|
683
|
+
} else if (ch === ")" && paren > 0) {
|
|
684
|
+
paren--;
|
|
685
|
+
} else if (ch === "|" && paren === 0) {
|
|
686
|
+
parts.push(value);
|
|
687
|
+
value = "";
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
value += ch;
|
|
693
|
+
}
|
|
694
|
+
parts.push(value);
|
|
695
|
+
return parts;
|
|
696
|
+
};
|
|
697
|
+
var isPlainBranch = (branch) => {
|
|
698
|
+
let escaped = false;
|
|
699
|
+
for (const ch of branch) {
|
|
700
|
+
if (escaped === true) {
|
|
701
|
+
escaped = false;
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
if (ch === "\\") {
|
|
705
|
+
escaped = true;
|
|
706
|
+
continue;
|
|
707
|
+
}
|
|
708
|
+
if (/[?*+@!()[\]{}]/.test(ch)) {
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
return true;
|
|
713
|
+
};
|
|
714
|
+
var normalizeSimpleBranch = (branch) => {
|
|
715
|
+
let value = branch.trim();
|
|
716
|
+
let changed = true;
|
|
717
|
+
while (changed === true) {
|
|
718
|
+
changed = false;
|
|
719
|
+
if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
|
|
720
|
+
value = value.slice(2, -1);
|
|
721
|
+
changed = true;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
if (!isPlainBranch(value)) {
|
|
725
|
+
return;
|
|
726
|
+
}
|
|
727
|
+
return value.replace(/\\(.)/g, "$1");
|
|
728
|
+
};
|
|
729
|
+
var hasRepeatedCharPrefixOverlap = (branches) => {
|
|
730
|
+
const values = branches.map(normalizeSimpleBranch).filter(Boolean);
|
|
731
|
+
for (let i = 0; i < values.length; i++) {
|
|
732
|
+
for (let j = i + 1; j < values.length; j++) {
|
|
733
|
+
const a = values[i];
|
|
734
|
+
const b = values[j];
|
|
735
|
+
const char = a[0];
|
|
736
|
+
if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) {
|
|
737
|
+
continue;
|
|
738
|
+
}
|
|
739
|
+
if (a === b || a.startsWith(b) || b.startsWith(a)) {
|
|
740
|
+
return true;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
return false;
|
|
745
|
+
};
|
|
746
|
+
var parseRepeatedExtglob = (pattern, requireEnd = true) => {
|
|
747
|
+
if (pattern[0] !== "+" && pattern[0] !== "*" || pattern[1] !== "(") {
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
let bracket = 0;
|
|
751
|
+
let paren = 0;
|
|
752
|
+
let quote = 0;
|
|
753
|
+
let escaped = false;
|
|
754
|
+
for (let i = 1; i < pattern.length; i++) {
|
|
755
|
+
const ch = pattern[i];
|
|
756
|
+
if (escaped === true) {
|
|
757
|
+
escaped = false;
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
if (ch === "\\") {
|
|
761
|
+
escaped = true;
|
|
762
|
+
continue;
|
|
763
|
+
}
|
|
764
|
+
if (ch === '"') {
|
|
765
|
+
quote = quote === 1 ? 0 : 1;
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
if (quote === 1) {
|
|
769
|
+
continue;
|
|
770
|
+
}
|
|
771
|
+
if (ch === "[") {
|
|
772
|
+
bracket++;
|
|
773
|
+
continue;
|
|
774
|
+
}
|
|
775
|
+
if (ch === "]" && bracket > 0) {
|
|
776
|
+
bracket--;
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
if (bracket > 0) {
|
|
780
|
+
continue;
|
|
781
|
+
}
|
|
782
|
+
if (ch === "(") {
|
|
783
|
+
paren++;
|
|
784
|
+
continue;
|
|
785
|
+
}
|
|
786
|
+
if (ch === ")") {
|
|
787
|
+
paren--;
|
|
788
|
+
if (paren === 0) {
|
|
789
|
+
if (requireEnd === true && i !== pattern.length - 1) {
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
return {
|
|
793
|
+
type: pattern[0],
|
|
794
|
+
body: pattern.slice(2, i),
|
|
795
|
+
end: i
|
|
796
|
+
};
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
var getStarExtglobSequenceOutput = (pattern) => {
|
|
802
|
+
let index = 0;
|
|
803
|
+
const chars = [];
|
|
804
|
+
while (index < pattern.length) {
|
|
805
|
+
const match = parseRepeatedExtglob(pattern.slice(index), false);
|
|
806
|
+
if (!match || match.type !== "*") {
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
const branches = splitTopLevel(match.body).map((branch2) => branch2.trim());
|
|
810
|
+
if (branches.length !== 1) {
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
const branch = normalizeSimpleBranch(branches[0]);
|
|
814
|
+
if (!branch || branch.length !== 1) {
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
chars.push(branch);
|
|
818
|
+
index += match.end + 1;
|
|
819
|
+
}
|
|
820
|
+
if (chars.length < 1) {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
const source = chars.length === 1 ? utils.escapeRegex(chars[0]) : `[${chars.map((ch) => utils.escapeRegex(ch)).join("")}]`;
|
|
824
|
+
return `${source}*`;
|
|
825
|
+
};
|
|
826
|
+
var repeatedExtglobRecursion = (pattern) => {
|
|
827
|
+
let depth = 0;
|
|
828
|
+
let value = pattern.trim();
|
|
829
|
+
let match = parseRepeatedExtglob(value);
|
|
830
|
+
while (match) {
|
|
831
|
+
depth++;
|
|
832
|
+
value = match.body.trim();
|
|
833
|
+
match = parseRepeatedExtglob(value);
|
|
834
|
+
}
|
|
835
|
+
return depth;
|
|
836
|
+
};
|
|
837
|
+
var analyzeRepeatedExtglob = (body, options) => {
|
|
838
|
+
if (options.maxExtglobRecursion === false) {
|
|
839
|
+
return { risky: false };
|
|
840
|
+
}
|
|
841
|
+
const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants.DEFAULT_MAX_EXTGLOB_RECURSION;
|
|
842
|
+
const branches = splitTopLevel(body).map((branch) => branch.trim());
|
|
843
|
+
if (branches.length > 1) {
|
|
844
|
+
if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) {
|
|
845
|
+
return { risky: true };
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
for (const branch of branches) {
|
|
849
|
+
const safeOutput = getStarExtglobSequenceOutput(branch);
|
|
850
|
+
if (safeOutput) {
|
|
851
|
+
return { risky: true, safeOutput };
|
|
852
|
+
}
|
|
853
|
+
if (repeatedExtglobRecursion(branch) > max) {
|
|
854
|
+
return { risky: true };
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
return { risky: false };
|
|
858
|
+
};
|
|
649
859
|
var parse = (input, options) => {
|
|
650
860
|
if (typeof input !== "string") {
|
|
651
861
|
throw new TypeError("Expected a string");
|
|
@@ -776,6 +986,8 @@ var require_parse = __commonJS({
|
|
|
776
986
|
token.prev = prev;
|
|
777
987
|
token.parens = state.parens;
|
|
778
988
|
token.output = state.output;
|
|
989
|
+
token.startIndex = state.index;
|
|
990
|
+
token.tokensIndex = tokens.length;
|
|
779
991
|
const output = (opts.capture ? "(" : "") + token.open;
|
|
780
992
|
increment("parens");
|
|
781
993
|
push({ type, value: value2, output: state.output ? "" : ONE_CHAR });
|
|
@@ -783,6 +995,26 @@ var require_parse = __commonJS({
|
|
|
783
995
|
extglobs.push(token);
|
|
784
996
|
};
|
|
785
997
|
const extglobClose = (token) => {
|
|
998
|
+
const literal = input.slice(token.startIndex, state.index + 1);
|
|
999
|
+
const body = input.slice(token.startIndex + 2, state.index);
|
|
1000
|
+
const analysis = analyzeRepeatedExtglob(body, opts);
|
|
1001
|
+
if ((token.type === "plus" || token.type === "star") && analysis.risky) {
|
|
1002
|
+
const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0;
|
|
1003
|
+
const open = tokens[token.tokensIndex];
|
|
1004
|
+
open.type = "text";
|
|
1005
|
+
open.value = literal;
|
|
1006
|
+
open.output = safeOutput || utils.escapeRegex(literal);
|
|
1007
|
+
for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
|
|
1008
|
+
tokens[i].value = "";
|
|
1009
|
+
tokens[i].output = "";
|
|
1010
|
+
delete tokens[i].suffix;
|
|
1011
|
+
}
|
|
1012
|
+
state.output = token.output + open.output;
|
|
1013
|
+
state.backtrack = true;
|
|
1014
|
+
push({ type: "paren", extglob: true, value, output: "" });
|
|
1015
|
+
decrement("parens");
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
786
1018
|
let output = token.close + (opts.capture ? ")" : "");
|
|
787
1019
|
let rest;
|
|
788
1020
|
if (token.type === "negate") {
|
|
@@ -1626,6 +1858,22 @@ function cosPlugin(options = {}) {
|
|
|
1626
1858
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
1627
1859
|
const loaderPath = path.resolve(__dirname, "./loader.js");
|
|
1628
1860
|
let config;
|
|
1861
|
+
const cwdRequire = createRequire(path.join(process.cwd(), "index.js"));
|
|
1862
|
+
const esbuildRequire = createRequire(import.meta.url);
|
|
1863
|
+
const esbuild = esbuildRequire("esbuild");
|
|
1864
|
+
const include = options.include || ["**/*"];
|
|
1865
|
+
const includeArray = Array.isArray(include) ? include : [include];
|
|
1866
|
+
function getPackageName(item) {
|
|
1867
|
+
if (typeof item === "string") {
|
|
1868
|
+
return item.startsWith("vendor-") ? item.replace("vendor-", "") : item;
|
|
1869
|
+
}
|
|
1870
|
+
if (item instanceof RegExp) {
|
|
1871
|
+
const source = item.source;
|
|
1872
|
+
const match = source.match(/vendor-([a-zA-Z0-9-@/]+?)(?:[-._]|\/|$)/);
|
|
1873
|
+
return match ? match[1] : null;
|
|
1874
|
+
}
|
|
1875
|
+
return null;
|
|
1876
|
+
}
|
|
1629
1877
|
return {
|
|
1630
1878
|
name: "vite-plugin-cos",
|
|
1631
1879
|
apply: "build",
|
|
@@ -1635,25 +1883,11 @@ function cosPlugin(options = {}) {
|
|
|
1635
1883
|
config2.build.rollupOptions = config2.build.rollupOptions || {};
|
|
1636
1884
|
const external = config2.build.rollupOptions.external || [];
|
|
1637
1885
|
const externalArray = Array.isArray(external) ? external : typeof external === "string" ? [external] : [];
|
|
1638
|
-
const include = options.include || ["**/*"];
|
|
1639
|
-
const includeArray = Array.isArray(include) ? include : [include];
|
|
1640
|
-
const require2 = createRequire(path.join(process.cwd(), "index.js"));
|
|
1641
|
-
function getPackageName(item) {
|
|
1642
|
-
if (typeof item === "string") {
|
|
1643
|
-
return item.startsWith("vendor-") ? item.replace("vendor-", "") : item;
|
|
1644
|
-
}
|
|
1645
|
-
if (item instanceof RegExp) {
|
|
1646
|
-
const source = item.source;
|
|
1647
|
-
const match = source.match(/vendor-([a-zA-Z0-9-@/]+?)(?:[-._]|\/|$)/);
|
|
1648
|
-
return match ? match[1] : null;
|
|
1649
|
-
}
|
|
1650
|
-
return null;
|
|
1651
|
-
}
|
|
1652
1886
|
for (const item of includeArray) {
|
|
1653
1887
|
const pkgName = getPackageName(item);
|
|
1654
1888
|
if (pkgName) {
|
|
1655
1889
|
try {
|
|
1656
|
-
|
|
1890
|
+
cwdRequire.resolve(pkgName);
|
|
1657
1891
|
const externalPatterns = [pkgName, `${pkgName}/*`];
|
|
1658
1892
|
for (const pattern of externalPatterns) {
|
|
1659
1893
|
if (!externalArray.includes(pattern)) {
|
|
@@ -1676,7 +1910,7 @@ function cosPlugin(options = {}) {
|
|
|
1676
1910
|
order: "post",
|
|
1677
1911
|
handler(html) {
|
|
1678
1912
|
return html.replace(
|
|
1679
|
-
/<script\s+[^>]*type=["']module["'][^>]*src=["'][^"']
|
|
1913
|
+
/<script\s+[^>]*type=["']module["'][^>]*src=["'][^"']+["'][^>]*><\/script>/gi,
|
|
1680
1914
|
"<!-- Entry script disabled by COS Plugin -->"
|
|
1681
1915
|
);
|
|
1682
1916
|
}
|
|
@@ -1684,7 +1918,7 @@ function cosPlugin(options = {}) {
|
|
|
1684
1918
|
async generateBundle(_options, bundle) {
|
|
1685
1919
|
const managedChunks = {};
|
|
1686
1920
|
let mainChunk = null;
|
|
1687
|
-
|
|
1921
|
+
const htmlAssets = [];
|
|
1688
1922
|
for (const fileName in bundle) {
|
|
1689
1923
|
const chunk = bundle[fileName];
|
|
1690
1924
|
if (chunk.type === "chunk") {
|
|
@@ -1700,32 +1934,18 @@ function cosPlugin(options = {}) {
|
|
|
1700
1934
|
managedChunks[fileName] = chunk;
|
|
1701
1935
|
}
|
|
1702
1936
|
}
|
|
1703
|
-
if (fileName
|
|
1704
|
-
|
|
1937
|
+
if (fileName.endsWith(".html") && chunk.type === "asset") {
|
|
1938
|
+
htmlAssets.push(chunk);
|
|
1705
1939
|
}
|
|
1706
1940
|
}
|
|
1707
1941
|
const externalToFileName = {};
|
|
1708
|
-
const require2 = createRequire(path.join(process.cwd(), "index.js"));
|
|
1709
|
-
const include = options.include || ["**/*"];
|
|
1710
|
-
const includeArray = Array.isArray(include) ? include : [include];
|
|
1711
|
-
function getPackageName(item) {
|
|
1712
|
-
if (typeof item === "string") {
|
|
1713
|
-
return item.startsWith("vendor-") ? item.replace("vendor-", "") : item;
|
|
1714
|
-
}
|
|
1715
|
-
if (item instanceof RegExp) {
|
|
1716
|
-
const source = item.source;
|
|
1717
|
-
const match = source.match(/vendor-([a-zA-Z0-9-@/]+?)(?:[-._]|\/|$)/);
|
|
1718
|
-
return match ? match[1] : null;
|
|
1719
|
-
}
|
|
1720
|
-
return null;
|
|
1721
|
-
}
|
|
1722
1942
|
for (const item of includeArray) {
|
|
1723
1943
|
const pkgName = getPackageName(item);
|
|
1724
1944
|
if (!pkgName) continue;
|
|
1725
1945
|
try {
|
|
1726
1946
|
let pkgPath = "";
|
|
1727
1947
|
try {
|
|
1728
|
-
const mainPath =
|
|
1948
|
+
const mainPath = cwdRequire.resolve(pkgName);
|
|
1729
1949
|
let currentDir = path.dirname(mainPath);
|
|
1730
1950
|
let pkgJsonPath = "";
|
|
1731
1951
|
while (currentDir !== path.parse(currentDir).root) {
|
|
@@ -1751,10 +1971,8 @@ function cosPlugin(options = {}) {
|
|
|
1751
1971
|
pkgPath = mainPath;
|
|
1752
1972
|
}
|
|
1753
1973
|
} catch (e) {
|
|
1754
|
-
pkgPath =
|
|
1974
|
+
pkgPath = cwdRequire.resolve(pkgName);
|
|
1755
1975
|
}
|
|
1756
|
-
const esbuildRequire = createRequire(import.meta.url);
|
|
1757
|
-
const esbuild = esbuildRequire("esbuild");
|
|
1758
1976
|
const buildResult = await esbuild.build({
|
|
1759
1977
|
entryPoints: [pkgPath],
|
|
1760
1978
|
bundle: true,
|
|
@@ -1784,7 +2002,7 @@ function cosPlugin(options = {}) {
|
|
|
1784
2002
|
managedChunks[fileName] = {
|
|
1785
2003
|
type: "chunk",
|
|
1786
2004
|
fileName,
|
|
1787
|
-
code: content.toString(),
|
|
2005
|
+
code: Buffer.from(content).toString("utf-8"),
|
|
1788
2006
|
name: item
|
|
1789
2007
|
};
|
|
1790
2008
|
externalToFileName[pkgName] = fileName;
|
|
@@ -1863,13 +2081,19 @@ function cosPlugin(options = {}) {
|
|
|
1863
2081
|
unmanagedDependencies.add(mainChunk.fileName);
|
|
1864
2082
|
}
|
|
1865
2083
|
manifest.unmanaged = Array.from(unmanagedDependencies);
|
|
1866
|
-
if (
|
|
2084
|
+
if (htmlAssets.length > 0) {
|
|
2085
|
+
let loaderCode;
|
|
1867
2086
|
try {
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
2087
|
+
loaderCode = fs.readFileSync(loaderPath, "utf-8");
|
|
2088
|
+
} catch (e) {
|
|
2089
|
+
console.error("COS Plugin: Failed to read loader.js", e);
|
|
2090
|
+
return;
|
|
2091
|
+
}
|
|
2092
|
+
loaderCode = loaderCode.replace(
|
|
2093
|
+
"__COS_MANIFEST__",
|
|
2094
|
+
JSON.stringify(manifest, null, 2)
|
|
2095
|
+
);
|
|
2096
|
+
for (const htmlAsset of htmlAssets) {
|
|
1873
2097
|
let htmlSource = htmlAsset.source;
|
|
1874
2098
|
htmlSource = htmlSource.replace(
|
|
1875
2099
|
/<link\s+[^>]*rel=["']modulepreload["'][^>]*>/gi,
|
|
@@ -1880,8 +2104,6 @@ function cosPlugin(options = {}) {
|
|
|
1880
2104
|
() => `<head>
|
|
1881
2105
|
<script id="cos-loader">${loaderCode}</script>`
|
|
1882
2106
|
);
|
|
1883
|
-
} catch (e) {
|
|
1884
|
-
console.error("COS Plugin: Failed to read loader.js", e);
|
|
1885
2107
|
}
|
|
1886
2108
|
}
|
|
1887
2109
|
}
|
package/dist/loader.js
CHANGED
|
@@ -120,13 +120,14 @@
|
|
|
120
120
|
// through the import map and can find other managed chunks.
|
|
121
121
|
const entrySpecifier = `coschunk-${mainEntry.replace(/\//g, '-')}`;
|
|
122
122
|
|
|
123
|
-
//
|
|
124
|
-
// import map before
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
123
|
+
// Yield to the event loop once so the browser registers the dynamically
|
|
124
|
+
// injected import map before the first module import.
|
|
125
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
126
|
+
try {
|
|
127
|
+
await import(entrySpecifier);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.error('COS Loader: Failed to start app', err);
|
|
130
|
+
}
|
|
130
131
|
} catch (err) {
|
|
131
132
|
console.error('COS Loader: Initialization failed', err);
|
|
132
133
|
}
|
package/loader.js
CHANGED
|
@@ -120,13 +120,14 @@
|
|
|
120
120
|
// through the import map and can find other managed chunks.
|
|
121
121
|
const entrySpecifier = `coschunk-${mainEntry.replace(/\//g, '-')}`;
|
|
122
122
|
|
|
123
|
-
//
|
|
124
|
-
// import map before
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
123
|
+
// Yield to the event loop once so the browser registers the dynamically
|
|
124
|
+
// injected import map before the first module import.
|
|
125
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
126
|
+
try {
|
|
127
|
+
await import(entrySpecifier);
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.error('COS Loader: Failed to start app', err);
|
|
130
|
+
}
|
|
130
131
|
} catch (err) {
|
|
131
132
|
console.error('COS Loader: Initialization failed', err);
|
|
132
133
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-cross-origin-storage",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Vite plugin to load chunks from Cross-Origin Storage",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"vite",
|
|
@@ -37,23 +37,34 @@
|
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsup index.ts --format esm --dts --clean && cp loader.js dist/",
|
|
39
39
|
"prepublishOnly": "npm run build",
|
|
40
|
-
"test:dev": "npm run build && vite testing",
|
|
41
|
-
"test:build": "npm run build && vite build testing",
|
|
42
|
-
"test:preview": "vite preview testing"
|
|
40
|
+
"test:simple:dev": "npm run build && vite testing/simple-test",
|
|
41
|
+
"test:simple:build": "npm run build && vite build testing/simple-test",
|
|
42
|
+
"test:simple:preview": "vite preview testing/simple-test",
|
|
43
|
+
"test:react-hello-world:dev": "npm run build && vite testing/react-hello-world",
|
|
44
|
+
"test:react-hello-world:build": "npm run build && vite build testing/react-hello-world",
|
|
45
|
+
"test:react-hello-world:preview": "vite preview testing/react-hello-world",
|
|
46
|
+
"test:react-todo:dev": "npm run build && vite testing/react-todo",
|
|
47
|
+
"test:react-todo:build": "npm run build && vite build testing/react-todo",
|
|
48
|
+
"test:react-todo:preview": "vite preview --port 4174 testing/react-todo"
|
|
43
49
|
},
|
|
44
50
|
"peerDependencies": {
|
|
45
|
-
"vite": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
51
|
+
"vite": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
|
|
46
52
|
},
|
|
47
53
|
"devDependencies": {
|
|
48
54
|
"@rollup/pluginutils": "^5.3.0",
|
|
49
|
-
"@types/node": "^25.2
|
|
50
|
-
"
|
|
51
|
-
"
|
|
55
|
+
"@types/node": "^25.6.2",
|
|
56
|
+
"@types/react": "^19.2.14",
|
|
57
|
+
"@types/react-dom": "^19.2.3",
|
|
58
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
59
|
+
"react": "^19.2.6",
|
|
60
|
+
"react-dom": "^19.2.6",
|
|
61
|
+
"rollup": "^4.60.3",
|
|
62
|
+
"three": "^0.184.0",
|
|
52
63
|
"tsup": "^8.5.1",
|
|
53
|
-
"typescript": "^
|
|
54
|
-
"vite": "^
|
|
64
|
+
"typescript": "^6.0.3",
|
|
65
|
+
"vite": "^8.0.11"
|
|
55
66
|
},
|
|
56
67
|
"dependencies": {
|
|
57
|
-
"esbuild": "^0.
|
|
68
|
+
"esbuild": "^0.28.0"
|
|
58
69
|
}
|
|
59
70
|
}
|