|
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