Jervis2049 / vite-plugin-crx-mv3

Build a Chrome Extension with Vite⚡
204 stars 30 forks source link

关于content样式隔离 #18

Open panghuangdehaozi opened 1 year ago

panghuangdehaozi commented 1 year ago

您好 再content_scripts中页面的样式是和谷歌插件公用的,这样会导致某些页面会出现偏移情况,请问如何能做的样式隔离?

Jervis2049 commented 1 year ago

你好。没明白你说的意思,可以提供一个简单的demo吗。

panghuangdehaozi commented 1 year ago

我在项目中使用了 tailwindcss 这样会导致有些网站页面出现错乱,我看别的插件时使用shadow DOM来做样式隔离的,但是目前我不知道怎么注入样式,现在的样式是全局生效的,所以会导致网页布局出现错乱; https://gitee.com/yaoyaolei/plugin-demo.git 这是一个demo 如果有解决办法麻烦请告诉我一下 目前我取消使用tailwindcss 看起来不会影响页面 1682044898896 比如这个网站https://www.antdv.com/components/overview 我的demo就会影响它的布局

Jervis2049 commented 1 year ago

初步看了一下,明白你意思了,我之后有空再看看怎么处理这个问题。

leacoleaco commented 1 year ago

我也遇到了这个问题...

Jervis2049 commented 1 year ago

我在项目中使用了 tailwindcss 这样会导致有些网站页面出现错乱,我看别的插件时使用shadow DOM来做样式隔离的,但是目前我不知道怎么注入样式,现在的样式是全局生效的,所以会导致网页布局出现错乱; https://gitee.com/yaoyaolei/plugin-demo.git 这是一个demo 如果有解决办法麻烦请告诉我一下 目前我取消使用tailwindcss 看起来不会影响页面 1682044898896 比如这个网站https://www.antdv.com/components/overview 我的demo就会影响它的布局

在你这个例子中,可以尝试这样做。后续会想办法,在vite plugin层面做一些工作,以此简化这些写法。

// 删除src/content-scripts/App.tsx的 import "../style.css";
// src/content-scripts/content.ts 调整为以下:

import { createApp } from "vue";
import App from "./App";
import style from "../style.css?inline";
import contentClass from "./content.module.css?inline";

function loadStyle(
  styleContent: string,
  rootElement = document.querySelector("head")
) {
  const style = document.createElement("style");
  style.innerText = styleContent;
  rootElement?.appendChild(style);
}

const createShadowElement = (elementId: string): Element => {
  let rootElement = document.getElementById(elementId);
  if (rootElement) {
    const shadowMountNode = rootElement.shadowRoot?.querySelector(
      `#${elementId}Children`
    ) as Element;
    return shadowMountNode;
  }

  rootElement = document.createElement("div");
  rootElement.setAttribute("id", elementId);
  document.body.appendChild(rootElement);
  const shadowRoot: any = rootElement.attachShadow({ mode: "open" });

  loadStyle(style, shadowRoot);
  loadStyle(contentClass, shadowRoot);

  shadowRoot.defaultView = shadowRoot.ownerDocument.defaultView;

  shadowRoot.createElement = function (elementName: string) {
    const node = document.createElement(elementName);
    Object.defineProperty(node, "ownerDocument", { value: shadowRoot });
    return node;
  };
  const shadowMountNode = shadowRoot.createElement("div");
  shadowMountNode.setAttribute("id", `${elementId}Children`);

  shadowRoot.appendChild(shadowMountNode);

  return shadowMountNode;
};

window.onload =  () => {
  const rootElement = createShadowElement("crx-app");
  const app = createApp(App);
  app.mount(rootElement);
};
leacoleaco commented 1 year ago

@Jervis2049 这样写好像 vue 页面中的 style 里的样式就不生效了... 😮‍💨

panghuangdehaozi commented 1 year ago

@leacoleaco 你可以试试这个plasmo

heng1025 commented 1 year ago

可以试试这种方案https://github.com/tailwindlabs/tailwindcss/discussions/9633

leacoleaco commented 1 year ago

@panghuangdehaozi plasmo 用过了, 但是感觉它用于 react 比较友好, 用在vue 感觉好鸡肋哦....写法好麻烦

chen-af commented 11 months ago

antd 的 css in js 可以解决呀 如果是content-scripts的话 也可以解决吧?

import { defineConfig, splitVendorChunkPlugin } from "vite";
import vue from "@vitejs/plugin-vue";
import crx from "vite-plugin-crx-mv3";
import Components from "unplugin-vue-components/vite";
import { AntDesignVueResolver } from "unplugin-vue-components/resolvers";

export default defineConfig(({ mode }) => {
  return {
    plugins: [
      vue(),
      crx({
        manifest: "./src/manifest.json",
      }),
      Components({
        resolvers: [
          AntDesignVueResolver({
            importStyle: false, // css in js
          }),
        ],
      }),
      splitVendorChunkPlugin(),
    ],
    build: {
      emptyOutDir: mode === "production",
      minify: "esbuild",
    },
  };
});