微应用(qiankun)之样式隔离

前言

在上篇文章 微应用(qiankun)之 vite 构建 中,我们在应用的样式隔离方面并没有做过多的介绍。而在实际项目中,这确是一个不容忽视的问题。那么我们应该如何去做这样式隔离呢?接下来本文首先会从 qiankun 提供的样式隔离方案开始进行简单介绍,然后选取合适的方案来实现样式隔离。下面就让我们一起来看看吧!

为什么要做样式隔离

在使用 qiankun 时,我们会发现,当我们在主应用中引入了多个子应用时,子应用的样式会互相影响,这是因为子应用的样式是全局 的,而 qiankun 默认情况下并没有对子应用的样式进行隔离。而我们实际中想要的样式隔离效果又是怎么样的呢?其主要是下面两点:

  1. 子应用样式不会影响到其他子应用或主应用,同时也支持全局样式
  2. 主应用样式可以覆盖各子应用下的指定的样式,不容易影响到其他子应用

基于上面两点,我们需要的样式隔离方案应该是弱隔离型 。那么我们该如何去实现呢?首先,让我们先来了解一下 qiankun 提供的样式隔离方案。

qiankun 提供的样式隔离方案

qiankun 提供了两种样式隔离方案 strictStyleIsolationexperimentalStyleIsolation,我们可以根据实际情况来选择合适的方案。下面也会对这两种方案进行介绍,并给出示例代码,方便大家理解。更多详情可参考 qiankun-startopts

strictStyleIsolation

它是严格的样式隔离,也是官方推荐的,主要是通过 shadow dom 来实现的。

shadow dom

shadow dom 是一种浏览器技术,它可以将一个 DOM 节点及其子节点与另一个文档分离。这样它就可以有自己的 DOM 树、CSS 样式、计算样式等等,但它并不是所有浏览器都支持。更多详情可参考 shadow dom

下面是 qiankunstrictStyleIsolation 样式隔离的示例代码:

示例代码

ts 复制代码
import { start, loadMicroApp } from 'qiankun'

// 说明:结合加载子应用方式选择其中一种即可

// 方式1: 启动 qiankun
start({
  sandbox: {
    strictStyleIsolation: true,
  }
})

// 方式2: 手动加载子应用 reactApp
loadMicroApp('reactApp', {
  sandbox: {
    strictStyleIsolation: true,
  }
})

当开启 strictStyleIsolation 后,我们会发现子应用的样式已经被隔离了,同时子应用的样式也无法覆盖主应用的样式了。如下图所示:

结论

通过上面对 shadow dom 的了解,我们会发现它是强隔离型,也并不支持覆盖子应用样式及子应用无法设置全局样式等问题。所以它是不能满足我们需求的。

experimentalStyleIsolation

它是实验性的样式隔离。主要是通过 scoped css 来实现的。

scoped css

scoped css 是一种 css 技术,它可以让 css 样式只作用于当前组件中的元素。这种技术可以用来实现样式隔离。更多详情可参考下面的链接:

下面是 qiankunexperimentalStyleIsolation 样式隔离的示例代码:

示例代码

ts 复制代码
import { start, loadMicroApp } from 'qiankun'

// 说明:结合加载子应用方式选择其中一种即可

// 方式1: 启动 qiankun
start({
  sandbox: {
    experimentalStyleIsolation: true,
  }
})

// 方式2: 手动加载子应用 reactApp
loadMicroApp('reactApp', {
  sandbox: {
    experimentalStyleIsolation: true,
  }
})

当开启 experimentalStyleIsolation 后,其实我们可以看到 qiankun 会在外层容器上添加 data-qiankun="子应用名称" 属性,与此同时也会子应用的样式上添加 div[data-qiankun="子应用名称"] 选择器来实现了样式隔离。如下面结构所示:

scss 复制代码
// 子应用名称 = reactApp
div[data-qiankun="reactApp"] .layout {
  // 子应用样式
}

div[data-qiankun="reactApp"] .layout-container {
  // 子应用样式
}

但是在我的项目示例中并没有展现正确的效果,看早前有人提过 issues,可是并没有得到任何回复。不过其他人好像也并没有遇到类似的问题,它或许可能与我项目中的其它地方产生了冲突,如果有知道小伙伴的可以评论区留言哦!示例项目中效果如下图所示:

结论

通过上面对 scoped css 的了解,我们会发现它其实是可以满足我们需求的,但是 qiankunexperimentalStyleIsolation 却并没有支持全局样式的设置。故也是 pass,期待 qiankun 后续完善支持!

最终样式隔离方案

综上所述,我们可以得出结论:qiankun 目前提供的两种样式隔离方案并不能满足我们的需求。但给了我们一个思路,那就是 scoped css 方案。故此我们可以自己在项目通过 scoped css 来实现应用的样式隔离来满足我们的需求。下面依次介绍如何在 reactvue 中使用 scoped css 来实现样式隔离。

React

React 中,我们可以通过 scoped css 来实现样式隔离,它的原理是给每个 class 添加一个 hash 的属性,这样就可以实现样式隔离。vite 构建的 react 项目默认支持 scoped css,我们只需要将样式文件后缀改为 .module.scss 即可

示例代码
tsx 复制代码
import styles from './index.module.scss'

export default () => {
  return (
    <div className={styles.container}>
      <p className='title'>react app</p>
      <button className={styles.button}>button</button>
    </div>
  )
}

index.module.scss 样式文件正常 scss 语法 写即可,不需要做任何处理

scss 复制代码
.container {
  .title {}
  // :global 前缀可以让样式不被隔离,可以在全局使用
  :global.button {}
}

vue

vue 中,我们可以通过 scoped 来实现样式隔离,它的原理是给每个 class 添加一个 data-v-xxxx 的属性,这样就可以实现样式隔离。

示例代码

vue 复制代码
<style lang="scss" scoped></style>

文章介绍到这里就结束了,希望对大家有所帮助,如果有什么问题欢迎在评论区留言哦!

相关推荐
呆呆小雅5 分钟前
二、创建第一个VUE项目
前端·javascript·vue.js
Fighting_p15 分钟前
【记录】列表自动滚动轮播功能实现
前端·javascript·vue.js
木与子不厌21 分钟前
微服务自定义过滤器
运维·数据库·微服务
微扬嘴角33 分钟前
springcloud篇1(微服务技术栈、服务拆分与远程调用、Eureka、Nacos)
spring cloud·微服务·eureka
time_silence33 分钟前
微服务——技术选型与框架
微服务·架构
Domain-zhuo34 分钟前
Git和SVN有什么区别?
前端·javascript·vue.js·git·svn·webpack·node.js
dbcat官方36 分钟前
1.微服务灰度发布(方案设计)
java·数据库·分布式·微服务·中间件·架构
平行线也会相交1 小时前
云图库平台(二)前端项目初始化
前端·vue.js·云图库平台
ai产品老杨1 小时前
报警推送消息升级的名厨亮灶开源了。
vue.js·人工智能·安全·开源·音视频
嘤嘤怪呆呆狗1 小时前
【开发问题记录】使用 Docker+Jenkins+Jenkins + gitee 实现自动化部署前端项目 CI/CD(centos7为例)
前端·vue.js·ci/cd·docker·gitee·自动化·jenkins