alibaba / ice

🚀 ice.js: The Progressive App Framework Based On React(基于 React 的渐进式应用框架)

Home Page:https://ice.work

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

speedup 模式下的 baseURL 的应用问题

aspirantzhang opened this issue · comments

Describe the bug

这个问题很奇怪,我现在没有时间做复现,只能说困扰了我一上午,我希望用简单的语言描述。
希望大家琢磨一下大概是哪里的问题。

现象

无异常的原版本号:
"@ice/app": "3.4.5",
"@ice/runtime": "1.4.2",

升级到最新版:
"@ice/app": "3.4.6",
"@ice/runtime": "1.4.4",

在访问一个页面时:
image

一个页面中,先是走了全局定义的 store 接口,然后读取了页面中的一个普通服务。
全局定义的store前面没有应用baseURL,而页面中的调用的服务却成功应用了baseURL

app.ts 中大概是这样:

export const storeConfig = defineStoreConfig(async (appData) => {
  const { userInfo = {}, menus = {}, companies = {} } = appData;
  return {
    initialStates: {
      user: {
        currentUser: userInfo,
      },
      menu: {
        menus,
      },
      company: {
        companies,
      },
    },
  };
});

export const requestConfig = defineRequestConfig(() => {
  console.log('process.env.', process.env.ICE_BASEURL);  //打印时,成功收到值
  return {
    baseURL: process.env.ICE_BASEURL,
    withCredentials: true,
    headers: { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/json' },

注:

  1. 经过我多次测试,这个问题只有升级到最新版且使用 speedup 模式才会出现。
  2. 最新版如果不用 speedup 模式,不会出现这个问题

Expected behavior

Actual behavior

No response

Version of ice.js

3.4.6

Content of build.json or ice.config.mts

import { defineConfig } from '@ice/app';
import request from '@ice/plugin-request';
import store from '@ice/plugin-store';
import auth from '@ice/plugin-auth';
import SpeedMeasurePlugin from 'speed-measure-webpack-plugin';

// The project config, see https://v3.ice.work/docs/guide/basic/config
const minify = process.env.NODE_ENV === 'production' ? 'swc' : false;
export default defineConfig(() => ({
  ssg: false,
  minify,
  plugins: [request(), store(), auth()],
  hash: process.env.NODE_ENV === 'production' ? 'contenthash' : false,
  compileDependencies: false,
  routes: {
    ignoreFiles: ['**/components/**', '**/services/**', '**/configs/**', '**/config.ts', '**/data.d.ts'],
  },
  // webpack: (webpackConfig) => {
  //   if (process.env.NODE_ENV !== 'test') {
  //     webpackConfig.plugins?.push(new SpeedMeasurePlugin());
  //   }
  //   return webpackConfig;
  // },
}));

Additional context

No response

最好提供下 app.ts 中的 store 配置和 request 配置

app.ts 中没啥特别的:

export const storeConfig = defineStoreConfig(async (appData) => {
  const { userInfo = {}, menus = {}, companies = {} } = appData;
  return {
    initialStates: {
      user: {
        currentUser: userInfo,
      },
      menu: {
        menus,
      },
      company: {
        companies,
      },
    },
  };
});

export const requestConfig = defineRequestConfig(() => {
  console.log('process.env.', process.env.ICE_BASEURL);
  return {
    baseURL: process.env.ICE_BASEURL,
    withCredentials: true,
    headers: { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/json' },
    interceptors: {
      request: {
        onConfig: (config) => {
          const token = window.localStorage.getItem('access_token');
          if (token) {
            config.headers.common = config.headers.common || {};
            config.headers.common.Authorization = `Bearer ${token}`;
          }
          return config;
        },
        onError: (error) => {
          return Promise.reject(error);
        },
      },
      response: {
        onConfig: (response) => {
          return response;
        },
        onError: (error) => {
        },
      },
    },
  };

export const dataLoader = defineDataLoader(async () => {
  if (window.location.pathname.startsWith('/reset-password')) {
    return {
      userInfo: {},
      menus: {},
      companies: {},
    };
  }
  try {
    const userInfo = await fetchUserInfo();
    const menus = await fetchMenus();
    const companies = await fetchCompanies();
    return {
      userInfo: userInfo.data,
      menus: menus,
      companies,
    };
  } catch (error) {
    return {
      userInfo: {
        error,
      },
      menus: {
        error,
      },
      companies: {
        error,
      },
    };
  }
});

而 service 那块:

export async function fetchUserInfo(): Promise<{ data: UserInfo }> {
  return await request.get('/api/user/users/me');
}

export async function fetchMenus(): Promise<{ data: UserInfo }> {
  return await request.get('/api/user/users/menus');
}

export default {
  async getNews(id) {
    const result = await request({
      url: `/api/news/${id}`,
      params: {
        with_likes_count: true,
        with_category: true,
        with_creator_user: true,
      },
    });
    return result.data;
  },
}

最新版本的 speedup 模式,在构建 dataLoader 的前置脚本处理上做了修改,dataLoader 逻辑默认在构建时会独立构建 bundle 并前置,如果 request 相关初始化逻辑还未执行,的确会出现上述问题,至于版本间的差异情况,我们排查下具体问题

Try @ice/app@3.4.8-canary-52596beb5-20240423090146

Try @ice/app@3.4.8-canary-52596beb5-20240423090146

完美解决!

@ice/app@3.4.8 已发布

额,可是我3.4.8版本,依然不好使。

├── @ant-design/pro-components@2.7.1
├── @ice/app@3.4.8
├── @ice/plugin-antd@1.0.2
├── @ice/plugin-css-assets-local@1.0.2
├── @ice/plugin-request@1.0.2
├── @ice/runtime@1.4.7
├── @types/node@18.19.33
├── @types/react-dom@18.3.0
├── @types/react@18.3.2
├── antd@4.24.16
├── lodash@4.17.21
├── react-dom@18.3.1
├── react@18.3.1
├── typescript@4.9.5
└── video.js@7.21.5

/src/app.ts

import { defineRequestConfig } from '@ice/plugin-request/types';

// App config, see https://v3.ice.work/docs/guide/basic/app
export default defineAppConfig(() => ({
  // Set your configs here.
}));

export const request = defineRequestConfig(() => ({
  baseURL: '/v2',
}));

/ice.config.mts

import request from '@ice/plugin-request';
import cssAssetsLocal from '@ice/plugin-css-assets-local';
import antd from '@ice/plugin-antd';

// The project config, see https://v3.ice.work/docs/guide/basic/config
const minify = process.env.NODE_ENV === 'production' ? 'swc' : false;
const compileDependencies = process.env.NODE_ENV === 'development' ? false : true;
export default defineConfig(() => ({
  ssg: false,
  minify,
  plugins: [
    request(),
    cssAssetsLocal(),
    antd({
      importStyle: true,
    }),
  ],
  compileDependencies,
  proxy: {
    '/v2': {
      target: 'http://localhost:8800',
      changeOrigin: true,
    }
  }
}));