in packages/runtime/src/dataLoader.ts [208:275]
async function init(loaders: Loaders, options: Options) {
const {
fetcher,
decorator,
runtimeModules,
appExport,
} = options;
const runtimeApi = {
appContext: {
appExport,
},
};
if (runtimeModules) {
await Promise.all(runtimeModules.map(module => {
const runtimeModule = ((module as CommonJsRuntime).default || module) as StaticRuntimePlugin;
return runtimeModule(runtimeApi);
}).filter(Boolean));
}
if (fetcher) {
setFetcher(fetcher);
}
if (decorator) {
setDecorator(decorator);
}
try {
loadInitialDataInClient(loaders);
} catch (error) {
console.error('Load initial data error: ', error);
}
(window as any).__ICE_DATA_LOADER__ = {
getLoader: (id) => {
return loaders[id];
},
getData: (id, options: LoadRoutesDataOptions) => {
let result;
// First render for ssg use data from build time, second render for ssg will use data from data loader.
const cacheKey = `${id}${options?.renderMode === 'SSG' ? '_ssg' : ''}`;
// In CSR, all dataLoader is called by global data loader to avoid bundle dataLoader in page bundle duplicate.
result = cache.get(cacheKey);
// Always fetch new data after cache is been used.
cache.delete(cacheKey);
// Already send data request.
if (result) {
return result.value;
}
const dataLoaderConfig = loaders[id];
// No data loader.
if (!dataLoaderConfig) {
return null;
}
// Call dataLoader.
const { loader } = dataLoaderConfig;
return callDataLoader(loader, options?.requestContext || getRequestContext(window.location));
},
};
}