@farmfe/runtime
Version:
Runtime of Farm
150 lines • 5.7 kB
JavaScript
// 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