UNPKG

@farmfe/runtime

Version:
150 lines 5.7 kB
// using native ability to load resources if target env is node. // Injected during build export const __farm_global_this__ = '<@__farm_global_this__@>'; export const __global_this__ = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : {}; export const targetEnv = __farm_global_this__.__FARM_TARGET_ENV__ || 'node'; export const isBrowser = targetEnv === 'browser' && __global_this__.document; /** * Loading resources according to their type and target env. */ export class ResourceLoader { constructor(moduleSystem, publicPaths) { this.moduleSystem = moduleSystem; this._loadedResources = {}; this._loadingResources = {}; this.publicPaths = publicPaths; } load(resource, index = 0) { // it's not running in browser if (!isBrowser) { const result = this.moduleSystem.pluginContainer.hookBail('loadResource', resource); if (result) { return result.then((res) => { if (!res.success && res.retryWithDefaultResourceLoader) { if (resource.type === 0) { return this._loadScript(`./${resource.path}`); } else if (resource.type === 1) { return this._loadLink(`./${resource.path}`); } } else if (!res.success) { throw new Error(`[Farm] Failed to load resource: "${resource.path}, type: ${resource.type}". Original Error: ${res.err}`); } }); } else { if (resource.type === 0) { return this._loadScript(`./${resource.path}`); } else if (resource.type === 1) { return this._loadLink(`./${resource.path}`); } } } const publicPath = this.publicPaths[index]; const url = `${publicPath.endsWith('/') ? publicPath.slice(0, -1) : publicPath}/${resource.path}`; if (this._loadedResources[resource.path]) { return Promise.resolve(); // @ts-ignore } else if (this._loadingResources[resource.path]) { // @ts-ignore return this._loadingResources[resource.path]; } const result = this.moduleSystem.pluginContainer.hookBail('loadResource', resource); if (result) { return result.then((res) => { if (res.success) { this.setLoadedResource(resource.path); } else if (res.retryWithDefaultResourceLoader) { return this._load(url, resource, index); } else { throw new Error(`[Farm] Failed to load resource: "${resource.path}, type: ${resource.type}". Original Error: ${res.err}`); } }); } else { return this._load(url, resource, index); } } setLoadedResource(path, loaded = true) { this._loadedResources[path] = loaded; } isResourceLoaded(path) { return this._loadedResources[path]; } _load(url, resource, index) { let promise = Promise.resolve(); if (resource.type === 0) { promise = this._loadScript(url); } else if (resource.type === 1) { promise = this._loadLink(url); } this._loadingResources[resource.path] = promise; promise .then(() => { this._loadedResources[resource.path] = true; // @ts-ignore this._loadingResources[resource.path] = null; }) .catch((e) => { console.warn(`[Farm] Failed to load resource "${url}" using publicPath: ${this.publicPaths[index]}`); index++; if (index < this.publicPaths.length) { return this._load(url, resource, index); } else { // @ts-ignore this._loadingResources[resource.path] = null; throw new Error(`[Farm] Failed to load resource: "${resource.path}, type: ${resource.type}". ${e}`); } }); return promise; } _loadScript(path) { // @ts-ignore if (FARM_RUNTIME_TARGET_ENV !== 'browser') { return import(path); } else { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = path; document.body.appendChild(script); script.onload = () => { resolve(); }; script.onerror = (e) => { reject(e); }; }); } } _loadLink(path) { // @ts-ignore if (FARM_RUNTIME_TARGET_ENV !== 'browser') { // return Promise.reject(new Error('Not support loading css in SSR')); // ignore css loading in SSR return Promise.resolve(); } else { return new Promise((resolve, reject) => { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = path; document.head.appendChild(link); link.onload = () => { resolve(); }; link.onerror = (e) => { reject(e); }; }); } } } //# sourceMappingURL=resource-loader.js.map