umijs / qiankun

📦 🚀 Blazing fast, simple and complete solution for micro frontends.
https://qiankun.umijs.org
MIT License
15.79k stars 2.01k forks source link

[求答疑]子应用布局跑到主应用布局的问题 #1878

Open PingZaiDotTse opened 2 years ago

PingZaiDotTse commented 2 years ago

环境:

react 16.0.0 umi 3.5 ts 4.1.2 macOS chrome v93

问题描述:

主应用是umijs,子应用是antd Pro,主应用通过layout关闭了左侧菜单栏布局,子应用loyout里保留左侧菜单。 目前导致子应用的左侧菜单栏直接覆盖到了主应用上,初步判断是由于菜单是依靠position:fixed定位的原因,但是我已经开启了沙箱,按道理应该css隔离了的,求帮忙看看啥原因导致的,谢谢

问题截图:

issue.jpg

代码:


//主应用app.tsx
export const qiankun = async () => {
        return {
                // 注册子应用信息
                apps: [
                        {
                                name: 'app1', // 唯一 id,需要与微应用中的package.json中的name一致
                                entry: '//localhost:8804', // html entry
                                container: '#wraper'
                        },
                ],
                routes: [
                        {
                                path: '/',
                                microApp: 'app1',
                        },
                ],
                sandbox: {
                        strictStyleIsolation: true // 严格沙箱
                },
                // fetch:(url:string)=>{
                //         return fetch(url).then(response=>response).then(response=>response)
                // },
                // 完整生命周期钩子请看 https://qiankun.umijs.org/zh/api/#registermicroapps-apps-lifecycles
                lifeCycles: {
                        afterMount: (props: any) => {
                                console.log(props);
                        },
                },
                // 支持更多的其他配置,详细看这里 https://qiankun.umijs.org/zh/api/#start-opts
        }
};

export const layout = ({
        initialState,
      }: {
        initialState: { settings?: LayoutSettings; currentUser?:any };
      }): BasicLayoutProps => {
        return {
          headerContentRender:()=>(
                <TopBar 
                openedTabs={[]}
                onTabChange={data=>{}} 
                sysList={[]} 
                currentTab={undefined}
                userPannelTabClick={tag=>{}}
          />
          ),
          rightContentRender: () => <div></div>,
          footerRender: () => <div>footer</div>,
          menuRender:false,
          onPageChange: () => {
          },
          menuHeaderRender: undefined,
          ...initialState?.settings,
        };
};

//子应用app.tsx

export const layout: RunTimeLayoutConfig = ({ initialState,setInitialState }) => {

  return {
    logo:initialState?.logo,
    rightContentRender: () => <RightContent />,
    disableContentMargin: false,
    waterMarkProps: {
      // content: initialState?.currentUser?.name,
    },
    // footerRender: () => <Footer />,
    onPageChange: () => {

    },
    menu: {

      params:{
        currentUser:initialState?.currentUser
      },
      request: async () => {

      },
    },
};
PingZaiDotTse commented 2 years ago

HELP PLEASE!!

然后要主应用覆盖子应用的css解决?

gongshun commented 2 years ago

沙箱解决不了所有的样式污染,因为父子应用同属于一个 document,样式是互通的,沙箱只能限制子应用的 css 的生效范围,主应用的 css 任然会作用到子应用的 DOM

haixiangyan commented 2 years ago

这个其实属于 CSS 污染的问题,qiankun 默认情况下没有开启 CSS 沙箱,可以用下面的方法来启用沙箱:

image

但是 ant-design 互相样式污染是一个更复杂的问题,无论上面你用哪个沙箱,都会有对应的 Bug:

最好的方法应该是使用 ConfigProvider 的 prefixCls 里添加 antd 的前缀,同时,使用下面来更新 less 变量

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: { '@ant-prefix': 'myAnt' },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};

一定要用 webpack 的方法来更改 @ant-prefix!不然 ant-design-pro 不生效!!

PingZaiDotTse commented 2 years ago

这个其实属于 CSS 污染的问题,qiankun 默认情况下没有开启 CSS 沙箱,可以用下面的方法来启用沙箱:

image

但是 ant-design 互相样式污染是一个更复杂的问题,无论上面你用哪个沙箱,都会有对应的 Bug:

  • strictStyleIsolation: 完全隔离CSS,但是像 Dialog, message 这些挂在到 body 上的组件样式全完蛋
  • experimentalStyleIsolation: 在 CSS 前添加对应的前缀,同样的,挂在到 body 上的组件一样完蛋

最好的方法应该是使用 ConfigProvider 的 prefixCls 里添加 antd 的前缀,同时,使用下面来更新 less 变量

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: { '@ant-prefix': 'myAnt' },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};

一定要用 webpack 的方法来更改 @ant-prefix!不然 ant-design-pro 不生效!!

沙箱解决不了所有的样式污染,因为父子应用同属于一个 document,样式是互通的,沙箱只能限制子应用的 css 的生效范围,主应用的 css 任然会作用到子应用的 DOM

嗯,感谢解惑

PingZaiDotTse commented 2 years ago

沙箱解决不了所有的样式污染,因为父子应用同属于一个 document,样式是互通的,沙箱只能限制子应用的 css 的生效范围,主应用的 css 任然会作用到子应用的 DOM

嗯,感谢抽空解惑

hehaibo123 commented 2 years ago

请问如果是element plus组件如何处理呢

haixiangyan commented 2 years ago

请问如果是element plus组件如何处理呢

查了一下,看这里,https://github.com/element-plus/element-plus/discussions/1154#discussioncomment-251777 貌似 element 太多 hard code 了

或者可以使用 webpack 的一些添加前缀的插件来处理

hehaibo123 commented 2 years ago

如果是element plus组件如何处理呢?

查了一下,看这里,element-plus/element-plus#1154 (comment) element 太多硬代码了

或者可以使用 webpack 的一些添加前缀的插件来处理

感谢你的答复,请问webpack sass-loader 方式如何处理呢?

kkYFL commented 1 year ago

这个其实属于 CSS 污染的问题,qiankun 默认情况下没有开启 CSS 沙箱,可以用下面的方法来启用沙箱:

image

但是 ant-design 互相样式污染是一个更复杂的问题,无论上面你用哪个沙箱,都会有对应的 Bug:

  • strictStyleIsolation: 完全隔离CSS,但是像 Dialog, message 这些挂在到 body 上的组件样式全完蛋
  • experimentalStyleIsolation: 在 CSS 前添加对应的前缀,同样的,挂在到 body 上的组件一样完蛋

最好的方法应该是使用 ConfigProvider 的 prefixCls 里添加 antd 的前缀,同时,使用下面来更新 less 变量

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: { '@ant-prefix': 'myAnt' },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};

一定要用 webpack 的方法来更改 @ant-prefix!不然 ant-design-pro 不生效!!

这种配置有没有遇到配置后,前缀已添加但是页面布局错乱的问题?