|
4 | 4 | */
|
5 | 5 | import warning from 'warning';
|
6 | 6 | import { debug } from '../env';
|
7 |
| -import { defineResolver } from '../resolver'; |
| 7 | +import { defineResolverCreator } from '../resolver'; |
8 | 8 |
|
9 | 9 | const isIE11 = typeof navigator !== 'undefined' && navigator.userAgent.indexOf('Trident') !== -1;
|
10 | 10 |
|
@@ -70,81 +70,84 @@ function noteGlobalProps(global: WindowProxy) {
|
70 | 70 | const scriptsCache = new Map<string, any>();
|
71 | 71 | const stylesCache = new Map<string, HTMLLinkElement>();
|
72 | 72 |
|
73 |
| -function createSandbox() { |
| 73 | +function createSandbox(globalVariables: Record<string, any> = {}) { |
74 | 74 | // TODO: load in sandbox
|
75 | 75 | const global: WindowProxy = window;
|
| 76 | + Object.assign(global, globalVariables); |
76 | 77 | return global;
|
77 | 78 | }
|
78 | 79 |
|
79 |
| -export const getUmdResolver = defineResolver<WindowProxy>((container = (proxy) => proxy.document.body) => { |
80 |
| - const proxy = createSandbox(); |
81 |
| - return { |
82 |
| - context: proxy, |
83 |
| - execScript(entry) { |
84 |
| - if (scriptsCache.has(entry)) return Promise.resolve(scriptsCache.get(entry)); // 从 catch 中获取 |
| 80 | +export const createUmdResolver = defineResolverCreator<WindowProxy>( |
| 81 | + ({ container = (proxy) => proxy.document.body, globalVariables }) => { |
| 82 | + const proxy = createSandbox(globalVariables); |
| 83 | + return { |
| 84 | + context: proxy, |
| 85 | + execScript(entry) { |
| 86 | + if (scriptsCache.has(entry)) return Promise.resolve(scriptsCache.get(entry)); // 从 catch 中获取 |
85 | 87 |
|
86 |
| - const selector = typeof container === 'string' ? proxy.document.querySelector(container) : container(proxy); |
87 |
| - if (!selector) { |
88 |
| - return Promise.reject(new Error(`[@vue-async/module-loader] The container to append script is not found.`)); |
89 |
| - } |
90 |
| - |
91 |
| - return new Promise((resolve, reject) => { |
92 |
| - noteGlobalProps(proxy); |
93 |
| - |
94 |
| - const script = proxy.document.createElement('script'); |
95 |
| - script.src = entry; |
96 |
| - script.onload = () => { |
97 |
| - const propName = getGlobalProp(proxy); |
98 |
| - const exports = propName ? proxy[propName] || {} : {}; |
99 |
| - scriptsCache.set(entry, exports); // add to catch |
100 |
| - resolve(exports); |
101 |
| - }; |
102 |
| - script.onerror = (err) => { |
103 |
| - warning(!debug, `[@vue-async/module-loader] script had a problem to create, entry:${entry}`); |
104 |
| - selector.removeChild(script); // remove script |
105 |
| - reject(new Error(`script load error, error: ${err.toString()}`)); |
106 |
| - }; |
107 |
| - |
108 |
| - selector!.appendChild(script); |
109 |
| - }); |
110 |
| - }, |
111 |
| - async addStyles(styles: string[]) { |
112 |
| - if (styles.length) { |
113 | 88 | const selector = typeof container === 'string' ? proxy.document.querySelector(container) : container(proxy);
|
114 | 89 | if (!selector) {
|
115 |
| - return Promise.reject(new Error(`[@vue-async/module-loader] The container to append link is not found.`)); |
| 90 | + return Promise.reject(new Error(`[@vue-async/module-loader] The container to append script is not found.`)); |
116 | 91 | }
|
117 |
| - await Promise.all( |
118 |
| - styles.map((href) => { |
119 |
| - if (stylesCache.has(href)) return Promise.resolve(); // 从 catch 中获取 |
120 |
| - |
121 |
| - return new Promise<void>((resolve, reject) => { |
122 |
| - const link = document.createElement('link'); |
123 |
| - link.rel = 'stylesheet'; |
124 |
| - link.type = 'text/css'; |
125 |
| - link.href = href; |
126 |
| - link.onload = () => { |
127 |
| - stylesCache.set(href, link); |
128 |
| - resolve(); |
129 |
| - }; |
130 |
| - link.onerror = (err) => { |
131 |
| - warning(!debug, `[@vue-async/module-loader] href had a problem to create, href${href}`); |
132 |
| - selector.removeChild(link); // remove link |
133 |
| - reject(new Error(`style load error, error: ${err.toString()}`)); |
134 |
| - }; |
135 |
| - selector.appendChild(link); |
136 |
| - }); |
137 |
| - }), |
138 |
| - ); |
139 |
| - } |
140 |
| - }, |
141 |
| - removeStyles(styles: string[]) { |
142 |
| - if (styles.length) { |
143 |
| - styles.forEach((href) => { |
144 |
| - const link = stylesCache.get(href); |
145 |
| - link?.remove(); |
| 92 | + |
| 93 | + return new Promise((resolve, reject) => { |
| 94 | + noteGlobalProps(proxy); |
| 95 | + |
| 96 | + const script = proxy.document.createElement('script'); |
| 97 | + script.src = entry; |
| 98 | + script.onload = () => { |
| 99 | + const propName = getGlobalProp(proxy); |
| 100 | + const exports = propName ? proxy[propName] || {} : {}; |
| 101 | + scriptsCache.set(entry, exports); // add to catch |
| 102 | + resolve(exports); |
| 103 | + }; |
| 104 | + script.onerror = (err) => { |
| 105 | + warning(!debug, `[@vue-async/module-loader] script had a problem to create, entry:${entry}`); |
| 106 | + selector.removeChild(script); // remove script |
| 107 | + reject(new Error(`script load error, error: ${err.toString()}`)); |
| 108 | + }; |
| 109 | + |
| 110 | + selector!.appendChild(script); |
146 | 111 | });
|
147 |
| - } |
148 |
| - }, |
149 |
| - }; |
150 |
| -}); |
| 112 | + }, |
| 113 | + async addStyles(styles: string[]) { |
| 114 | + if (styles.length) { |
| 115 | + const selector = typeof container === 'string' ? proxy.document.querySelector(container) : container(proxy); |
| 116 | + if (!selector) { |
| 117 | + return Promise.reject(new Error(`[@vue-async/module-loader] The container to append link is not found.`)); |
| 118 | + } |
| 119 | + await Promise.all( |
| 120 | + styles.map((href) => { |
| 121 | + if (stylesCache.has(href)) return Promise.resolve(); // 从 catch 中获取 |
| 122 | + |
| 123 | + return new Promise<void>((resolve, reject) => { |
| 124 | + const link = document.createElement('link'); |
| 125 | + link.rel = 'stylesheet'; |
| 126 | + link.type = 'text/css'; |
| 127 | + link.href = href; |
| 128 | + link.onload = () => { |
| 129 | + stylesCache.set(href, link); |
| 130 | + resolve(); |
| 131 | + }; |
| 132 | + link.onerror = (err) => { |
| 133 | + warning(!debug, `[@vue-async/module-loader] href had a problem to create, href${href}`); |
| 134 | + selector.removeChild(link); // remove link |
| 135 | + reject(new Error(`style load error, error: ${err.toString()}`)); |
| 136 | + }; |
| 137 | + selector.appendChild(link); |
| 138 | + }); |
| 139 | + }), |
| 140 | + ); |
| 141 | + } |
| 142 | + }, |
| 143 | + removeStyles(styles: string[]) { |
| 144 | + if (styles.length) { |
| 145 | + styles.forEach((href) => { |
| 146 | + const link = stylesCache.get(href); |
| 147 | + link?.remove(); |
| 148 | + }); |
| 149 | + } |
| 150 | + }, |
| 151 | + }; |
| 152 | + }, |
| 153 | +); |
0 commit comments