UNPKG

10.1 kBJavaScriptView Raw
1var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2 return new (P || (P = Promise))(function (resolve, reject) {
3 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
4 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
5 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
6 step((generator = generator.apply(thisArg, _arguments || [])).next());
7 });
8};
9import { Origin } from 'aurelia-metadata';
10import { Loader } from 'aurelia-loader';
11import { DOM, PLATFORM } from 'aurelia-pal';
12/**
13* An implementation of the TemplateLoader interface implemented with text-based loading.
14*/
15export class TextTemplateLoader {
16 /**
17 * Loads a template.
18 * @param loader The loader that is requesting the template load.
19 * @param entry The TemplateRegistryEntry to load and populate with a template.
20 * @return A promise which resolves when the TemplateRegistryEntry is loaded with a template.
21 */
22 loadTemplate(loader, entry) {
23 return __awaiter(this, void 0, void 0, function* () {
24 const text = yield loader.loadText(entry.address);
25 entry.template = DOM.createTemplateFromMarkup(text);
26 });
27 }
28}
29export function ensureOriginOnExports(moduleExports, moduleId) {
30 let target = moduleExports;
31 let key;
32 let exportedValue;
33 if (target.__useDefault) {
34 target = target.default;
35 }
36 Origin.set(target, new Origin(moduleId, 'default'));
37 if (typeof target === 'object') {
38 for (key in target) {
39 exportedValue = target[key];
40 if (typeof exportedValue === 'function') {
41 Origin.set(exportedValue, new Origin(moduleId, key));
42 }
43 }
44 }
45 return moduleExports;
46}
47/**
48* A default implementation of the Loader abstraction which works with webpack (extended common-js style).
49*/
50export class WebpackLoader extends Loader {
51 constructor() {
52 super();
53 this.moduleRegistry = Object.create(null);
54 this.loaderPlugins = Object.create(null);
55 this.modulesBeingLoaded = new Map();
56 this.useTemplateLoader(new TextTemplateLoader());
57 this.addPlugin('template-registry-entry', {
58 fetch: (moduleId) => __awaiter(this, void 0, void 0, function* () {
59 // HMR:
60 if (module.hot) {
61 if (!this.hmrContext) {
62 // Note: Please do NOT import aurelia-hot-module-reload statically at the top of file.
63 // We don't want to bundle it when not using --hot, in particular in production builds.
64 // Webpack will evaluate the `if (module.hot)` above at build time
65 // and will include (or not) aurelia-hot-module-reload accordingly.
66 const { HmrContext } = require('aurelia-hot-module-reload');
67 this.hmrContext = new HmrContext(this);
68 }
69 module.hot.accept(moduleId, () => __awaiter(this, void 0, void 0, function* () {
70 yield this.hmrContext.handleViewChange(moduleId);
71 }));
72 }
73 const entry = this.getOrCreateTemplateRegistryEntry(moduleId);
74 if (!entry.templateIsLoaded) {
75 yield this.templateLoader.loadTemplate(this, entry);
76 }
77 return entry;
78 })
79 });
80 PLATFORM.eachModule = callback => {
81 const registry = __webpack_require__.c;
82 const cachedModuleIds = Object.getOwnPropertyNames(registry);
83 cachedModuleIds
84 // Note: we use .some here like a .forEach that can be "break"ed out of.
85 // It will stop iterating only when a truthy value is returned.
86 // Even though the docs say "true" explicitly, loader-default also goes by truthy
87 // and this is to keep it consistent with that.
88 .some(moduleId => {
89 const moduleExports = registry[moduleId].exports;
90 if (typeof moduleExports === 'object') {
91 return callback(moduleId, moduleExports);
92 }
93 return false;
94 });
95 };
96 }
97 _import(address, defaultHMR = true) {
98 return __awaiter(this, void 0, void 0, function* () {
99 const addressParts = address.split('!');
100 const moduleId = addressParts.splice(addressParts.length - 1, 1)[0];
101 const loaderPlugin = addressParts.length === 1 ? addressParts[0] : null;
102 if (loaderPlugin) {
103 const plugin = this.loaderPlugins[loaderPlugin];
104 if (!plugin) {
105 throw new Error(`Plugin ${loaderPlugin} is not registered in the loader.`);
106 }
107 if (module.hot && plugin.hot) {
108 module.hot.accept(moduleId, () => plugin.hot(moduleId));
109 }
110 return yield plugin.fetch(moduleId);
111 }
112 if (__webpack_require__.m[moduleId]) {
113 if (defaultHMR && module.hot && this.hmrContext) {
114 module.hot.accept(moduleId, () => this.hmrContext.handleModuleChange(moduleId, module.hot));
115 }
116 return __webpack_require__(moduleId);
117 }
118 const asyncModuleId = `async!${moduleId}`;
119 if (__webpack_require__.m[asyncModuleId]) {
120 if (defaultHMR && module.hot && this.hmrContext) {
121 module.hot.accept(moduleId, () => this.hmrContext.handleModuleChange(moduleId, module.hot));
122 module.hot.accept(asyncModuleId, () => this.hmrContext.handleModuleChange(moduleId, module.hot));
123 }
124 const callback = __webpack_require__(asyncModuleId);
125 return yield new Promise(callback);
126 }
127 throw new Error(`Unable to find module with ID: ${moduleId}`);
128 });
129 }
130 /**
131 * Maps a module id to a source.
132 * @param id The module id.
133 * @param source The source to map the module to.
134 */
135 map(id, source) { }
136 /**
137 * Normalizes a module id.
138 * @param moduleId The module id to normalize.
139 * @param relativeTo What the module id should be normalized relative to.
140 * @return The normalized module id.
141 */
142 normalizeSync(moduleId, relativeTo) {
143 return moduleId;
144 }
145 /**
146 * Normalizes a module id.
147 * @param moduleId The module id to normalize.
148 * @param relativeTo What the module id should be normalized relative to.
149 * @return The normalized module id.
150 */
151 normalize(moduleId, relativeTo) {
152 return Promise.resolve(moduleId);
153 }
154 /**
155 * Instructs the loader to use a specific TemplateLoader instance for loading templates
156 * @param templateLoader The instance of TemplateLoader to use for loading templates.
157 */
158 useTemplateLoader(templateLoader) {
159 this.templateLoader = templateLoader;
160 }
161 /**
162 * Loads a collection of modules.
163 * @param ids The set of module ids to load.
164 * @return A Promise for an array of loaded modules.
165 */
166 loadAllModules(ids) {
167 return Promise.all(ids.map(id => this.loadModule(id)));
168 }
169 /**
170 * Loads a module.
171 * @param moduleId The module ID to load.
172 * @return A Promise for the loaded module.
173 */
174 loadModule(moduleId, defaultHMR = true) {
175 return __awaiter(this, void 0, void 0, function* () {
176 let existing = this.moduleRegistry[moduleId];
177 if (existing) {
178 return existing;
179 }
180 let beingLoaded = this.modulesBeingLoaded.get(moduleId);
181 if (beingLoaded) {
182 return beingLoaded;
183 }
184 beingLoaded = this._import(moduleId, defaultHMR);
185 this.modulesBeingLoaded.set(moduleId, beingLoaded);
186 const moduleExports = yield beingLoaded;
187 this.moduleRegistry[moduleId] = ensureOriginOnExports(moduleExports, moduleId);
188 this.modulesBeingLoaded.delete(moduleId);
189 return moduleExports;
190 });
191 }
192 /**
193 * Loads a template.
194 * @param url The url of the template to load.
195 * @return A Promise for a TemplateRegistryEntry containing the template.
196 */
197 loadTemplate(url) {
198 return this.loadModule(this.applyPluginToUrl(url, 'template-registry-entry'), false);
199 }
200 /**
201 * Loads a text-based resource.
202 * @param url The url of the text file to load.
203 * @return A Promise for text content.
204 */
205 loadText(url) {
206 return __awaiter(this, void 0, void 0, function* () {
207 const result = yield this.loadModule(url, false);
208 // css-loader could use esModule:true
209 const defaultExport = result && result.__esModule ? result.default : result;
210 if (defaultExport instanceof Array && defaultExport[0] instanceof Array && defaultExport.hasOwnProperty('toString')) {
211 // we're dealing with a file loaded using the css-loader:
212 return defaultExport.toString();
213 }
214 return result;
215 });
216 }
217 /**
218 * Alters a module id so that it includes a plugin loader.
219 * @param url The url of the module to load.
220 * @param pluginName The plugin to apply to the module id.
221 * @return The plugin-based module id.
222 */
223 applyPluginToUrl(url, pluginName) {
224 return `${pluginName}!${url}`;
225 }
226 /**
227 * Registers a plugin with the loader.
228 * @param pluginName The name of the plugin.
229 * @param implementation The plugin implementation.
230 */
231 addPlugin(pluginName, implementation) {
232 this.loaderPlugins[pluginName] = implementation;
233 }
234}
235PLATFORM.Loader = WebpackLoader;