Skip to content
This repository has been archived by the owner on Nov 17, 2022. It is now read-only.

fix: request in data loader #662

Merged
merged 8 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion examples/with-plugin-request/ice.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { defineConfig } from '@ice/app';
import request from '@ice/plugin-request';

export default defineConfig({
dataLoader: false,
plugins: [
request(),
],
Expand Down
4 changes: 2 additions & 2 deletions packages/ice/src/plugins/web/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import getServerCompilerPlugin from '../../utils/getServerCompilerPlugin.js';

const plugin: Plugin = () => ({
name: 'plugin-web',
setup: ({ registerTask, onHook, context, generator, serverCompileTask, dataCache }) => {
setup: ({ registerTask, onHook, context, generator, serverCompileTask, dataCache, getAllPlugin }) => {
const { rootDir, commandArgs, command, userConfig } = context;
const { ssg } = userConfig;

Expand Down Expand Up @@ -52,7 +52,7 @@ const plugin: Plugin = () => ({
serverOutfile = path.join(outputDir, SERVER_OUTPUT_DIR, `index${userConfig?.server?.format === 'esm' ? '.mjs' : '.cjs'}`);
webpackConfigs[0].plugins.push(
// Add webpack plugin of data-loader in web task
new DataLoaderPlugin({ serverCompiler, rootDir, dataCache }),
new DataLoaderPlugin({ serverCompiler, rootDir, dataCache, getAllPlugin }),
// Add ServerCompilerPlugin
getServerCompilerPlugin(serverCompiler, {
rootDir,
Expand Down
1 change: 1 addition & 0 deletions packages/ice/src/types/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export interface OverwritePluginAPI extends ExtendsPluginAPI {
export interface PluginData extends _Plugin<Config, OverwritePluginAPI> {
runtime?: string;
staticRuntime?: boolean;
keepExports?: string[];
}

export type Plugin<Options = any> = (options?: Options) => PluginData;
19 changes: 16 additions & 3 deletions packages/ice/src/webpack/DataLoaderPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import fse from 'fs-extra';
import consola from 'consola';
import type { Compiler } from 'webpack';
import webpack from '@ice/bundles/compiled/webpack/index.js';
import type { ServerCompiler } from '../types/plugin.js';
import type { Context } from 'build-scripts';
import type { ServerCompiler, PluginData } from '../types/plugin.js';
import { RUNTIME_TMP_DIR } from '../constant.js';
import { getRoutePathsFromCache } from '../utils/getRoutePaths.js';

Expand All @@ -14,19 +15,31 @@ export default class DataLoaderPlugin {
private serverCompiler: ServerCompiler;
private rootDir: string;
private dataCache: Map<string, string>;
private getAllPlugin: Context['getAllPlugin'];

public constructor(options: {
serverCompiler: ServerCompiler;
rootDir: string;
dataCache: Map<string, string>;
getAllPlugin?: Context['getAllPlugin'];
}) {
const { serverCompiler, rootDir, dataCache } = options;
const { serverCompiler, rootDir, dataCache, getAllPlugin } = options;
this.serverCompiler = serverCompiler;
this.rootDir = rootDir;
this.dataCache = dataCache;
this.getAllPlugin = getAllPlugin;
}

public apply(compiler: Compiler) {
const plugins = this.getAllPlugin(['keepExports']) as PluginData[];

let keepExports = ['getData', 'getAppData'];
plugins.forEach(plugin => {
if (plugin.keepExports) {
keepExports = keepExports.concat(plugin.keepExports);
}
});

compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
compilation.hooks.processAssets.tapAsync({
name: pluginName,
Expand All @@ -45,7 +58,7 @@ export default class DataLoaderPlugin {
},
{
swc: {
keepExports: ['getData', 'getAppData'],
keepExports,
keepPlatform: 'web',
getRoutePaths: () => {
return getRoutePathsFromCache(this.dataCache);
Expand Down
27 changes: 23 additions & 4 deletions packages/ice/templates/exports/data-loader.ts.ejs
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
import { dataLoader } from '@ice/runtime';
<% if(hasExportAppData) {-%>import { getAppData } from '@/app';<% } -%>

<% if(hasExportAppData) {-%>import * as app from '@/app';<% } -%>
<% if(dataLoaderImport.imports) {-%><%-dataLoaderImport.imports%><% } -%>
<% const staticModuleNames = []; -%>
<% if (runtimeModules.length) { -%>
<% runtimeModules.forEach((runtimeModule, index) => { -%>
<% if (runtimeModule.staticRuntime) { -%>
import module<%= index %> from '<%= runtimeModule.path %>';
<% staticModuleNames.push('module' + index) -%>
<% } -%>
<% }) -%>
<% } -%>

<% if (loaders) {-%>
<%- loaders %>
<% } else { -%>
const loaders = {};
<% } -%>

<% if(hasExportAppData) {-%>loaders['__app'] = getAppData;<% } -%>
<% if(hasExportAppData) {-%>loaders['__app'] = app.getAppData;<% } -%>

<% if(!dataLoaderImport.imports) {-%>
let fetcher = (options) => {
window.fetch(options.url, options);
}
<% } -%>

dataLoader.init(loaders, fetcher);
// Only init static runtime in data-loader.
const staticRuntimeModules = [
<% staticModuleNames.forEach((moduleName, index) => { -%>
<%= moduleName %>,
<% }) -%>
];

dataLoader.init(loaders, {
fetcher,
runtimeModules: staticRuntimeModules,
appExport: app,
});
1 change: 1 addition & 0 deletions packages/plugin-request/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const plugin: Plugin<PluginRequestOptions | void> = () => ({
},
runtime: `${PLUGIN_NAME}/esm/runtime`,
staticRuntime: true,
keepExports: ['request'],
});

export type {
Expand Down
29 changes: 27 additions & 2 deletions packages/runtime/src/dataLoader.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { GetData, GetDataConfig } from './types.js';
import type { GetData, GetDataConfig, RuntimeModules, AppExport, RuntimePlugin, CommonJsRuntime } from './types.js';
import getRequestContext from './requestContext.js';

interface Loaders {
Expand Down Expand Up @@ -110,11 +110,36 @@ function getLoaders(loadersConfig: LoadersConfig, fetcher: Function): Loaders {
return loaders;
}

interface Options {
fetcher: Function;
runtimeModules: RuntimeModules['statics'];
appExport: AppExport;
}

/**
* Load initial data and register global loader.
* In order to load data, JavaScript modules, CSS and other assets in parallel.
*/
function init(loadersConfig: LoadersConfig, fetcher: Function) {
async function init(loadersConfig: LoadersConfig, options: Options) {
const {
fetcher,
runtimeModules,
appExport,
} = options;

const runtimeApi = {
appContext: {
appExport,
},
};

if (runtimeModules) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个是干啥的?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

通过插件注册的一些运行时模块,比如 request 插件,会配置请求的 baseUrl,需要对 data-loader 生效

await Promise.all(runtimeModules.map(module => {
const runtimeModule = (module as CommonJsRuntime).default || module as RuntimePlugin;
return runtimeModule(runtimeApi);
}).filter(Boolean));
}

const loaders = getLoaders(loadersConfig, fetcher);

try {
Expand Down
13 changes: 13 additions & 0 deletions packages/runtime/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,26 @@ export interface RuntimeAPI {
useAppContext: UseAppContext;
}

export interface StaticRuntimeAPI {
appContext: {
appExport: AppExport;
};
}

export interface RuntimePlugin {
(
apis: RuntimeAPI,
runtimeOptions?: Record<string, any>,
): Promise<void> | void;
}

export interface RuntimePlugin {
(
apis: StaticRuntimeAPI,
runtimeOptions?: Record<string, any>,
): Promise<void> | void;
}

export interface CommonJsRuntime {
default: RuntimePlugin;
}
Expand Down