代码之家  ›  专栏  ›  技术社区  ›  Danziger

汇总绑定对等依赖项/多个MUI实例使ThemeProvider无法工作

  •  0
  • Danziger  · 技术社区  · 4 年前

    我有两份不同的回购协议, lib apps .

    • 解放党 有一些化学成分是用 MUI 我想用它来消费 应用程序 ,这是通过汇总构建的。

    • 应用程序 是Lerna monorepo和Next。导入的js应用程序 解放党 作为一个依赖项来使用它的组件,这些组件可以自定义,并将它们包装在 <ThemeProvider> 具有自定义主题。

    然而,这不起作用,因为存在重复的MUI实例/ ThemeProvider ,我可以通过将此添加到 解放党 的切入点:

    if (process.browser) {
      (window as any)._React = React;
      (window as any)._ThemeProvider = ThemeProvider;
    }
    

    然后这个变成了 应用程序 ':

    if (process.browser) {
      const {
        _React,
        _ThemeProvider,
      } = window as any;
    
      console.log(_React ? (_React === React ? "✅ Unique React" : "❌ Duplicate React") : "-");
      console.log(_ThemeProvider ? (_ThemeProvider === ThemeProvider ? "✅ Unique ThemeProvider" : "❌ Duplicate ThemeProvider") : "-");
    }
    

    其中打印:

    ✅ Unique React
    ❌ Duplicate ThemeProvider
    

    解放党 中的组件使用情况 app 看起来像这样:

    <ThemeProvider theme={ MY_CUSTOM_THEME }>
      <MyComponent{ ...myComponentProps } />
    </ThemeProvider>
    

    两者都在哪里 MyComponent MY_CUSTOM_THEME 是从中国进口的 解放党 虽然 ThemeProvider 是从中国进口的 @mui/material/styles ,就像在 解放党 .

    但是,所有MUI组件都将以默认主题显示。

    以下是两个回购协议的一些相关构建文件:

    lib > package.json :

    {
      "name": "@myscope/lib",
      "version": "1.0.0-alpha",
      "description": "",
      "main": "dist/cjs/src/index.js",
      "module": "dist/esm/src/index.js",
      "types": "dist/index.d.ts",
      "files": [
        "dist"
      ],
      "private": true,
      "scripts": {
        "build": "rollup -c",
      },
      "dependencies": {
        "@apollo/client": "^3.4.5",
        "@apollo/link-context": "^2.0.0-beta.3",
        "@hookform/resolvers": "^2.8.5",
        "@mui/icons-material": "^5.0.4",
        "@swyg/corre": "^1.0.1",
        "apollo-upload-client": "^16.0.0",
        "atob": "^2.1.2",
        "axios": "^0.24.0",
        "btoa": "^1.2.1",
        "country-codes-list": "^1.6.8",
        "country-region-data": "^1.6.0",
        "next": "^11.0.1",
        "next-images": "^1.8.2",
        "openpgp": "^5.0.0",
        "react-hook-form": "^7.22.0",
        "react-payment-inputs": "^1.1.8",
        "react-use-country-region": "^1.0.0",
        "styled-components": "^5.3.0",
        "use-callback-ref": "^1.2.5",
        "uuidv4": "^6.2.12",
        "yup": "^0.32.11"
      },
      "peerDependencies": {
        "@mui/material": "^5.0.4",
        "react-dom": "^17.0.2",
        "react": "^17.0.2"
      },
      "devDependencies": {
        "@auth0/auth0-react": "^1.6.0",
        "@babel/preset-react": "^7.16.7",
        "@emotion/react": "^11.5.0",
        "@emotion/styled": "^11.3.0",
        "@graphql-codegen/cli": "^1.21.5",
        "@graphql-codegen/introspection": "^1.18.2",
        "@graphql-codegen/typescript-operations": "^1.18.0",
        "@graphql-codegen/typescript-react-apollo": "^2.2.5",
        "@graphql-codegen/typescript": "^1.22.1",
        "@mui/material": "^5.2.8",
        "@rollup/plugin-babel": "^5.3.0",
        "@rollup/plugin-commonjs": "^21.0.1",
        "@rollup/plugin-node-resolve": "^13.1.2",
        "@rollup/plugin-typescript": "^8.3.0",
        "@testing-library/dom": "^8.1.0",
        "@testing-library/jest-dom": "^5.14.1",
        "@testing-library/react": "^12.0.0",
        "@testing-library/user-event": "^13.2.1",
        "@types/jest": "^26.0.24",
        "@types/react-dom": "^17.0.11",
        "@types/react": "^17.0.16",
        "@types/styled-components": "^5.1.12",
        "@typescript-eslint/eslint-plugin": "^4.29.0",
        "@typescript-eslint/parser": "^4.29.0",
        "babel-jest": "^27.0.6",
        "babel-plugin-styled-components": "^2.0.2",
        "eslint-config-next": "^11.0.1",
        "eslint-config-prettier": "^8.3.0",
        "eslint-plugin-react-hooks": "^4.2.0",
        "eslint-plugin-unused-imports": "^1.1.2",
        "eslint": "^7.32.0",
        "graphql": "^16.2.0",
        "jest": "^27.0.6",
        "prettier": "^2.3.2",
        "rollup-plugin-dts": "^4.1.0",
        "rollup-plugin-node-externals": "^3.1.2",
        "rollup-plugin-peer-deps-external": "^2.2.4",
        "rollup-plugin-typescript2": "^0.31.1",
        "rollup": "^2.63.0",
        "ts-jest": "^27.0.4",
        "typescript": "^4.3.5"
      }
    }
    

    注意 @mui/material 两者都出现在 peerDependencies devDependencies ,但不是 react rect-dom ,仅列为 对等依赖 .那是因为 @types/react @types/react-dom ,但与MUI没有类似之处,因此如果找不到正确的类型,汇总构建将失败。

    lib > rollup.config.js :

    import commonjs from '@rollup/plugin-commonjs';
    import dts from 'rollup-plugin-dts'
    import resolve from "@rollup/plugin-node-resolve";
    import typescript from 'rollup-plugin-typescript2'
    import babel from '@rollup/plugin-babel'
    
    import pkg from "./package.json";
    
    // Extensions handled by babel:
    const EXTENSIONS = [".ts", ".tsx"];
    
    // Exclude dev and peer dependencies:
    const EXTERNAL = [
      ...Object.keys(pkg.devDependencies),
      ...Object.keys(pkg.peerDependencies),
    ];
    
    export default [{
        input: 'src/index.ts',
    
        output: [{
            dir: "dist/esm",
            sourcemap: true,
            format: "esm",
            preserveModules: true,
            globals: {
              react: "React",
            },
        }, {
            dir: "dist/cjs",
            sourcemap: true,
            format: "cjs",
            preserveModules: true,
            globals: {
              react: "React",
            },
        }],
    
        external: EXTERNAL,
        
        plugins: [
           resolve(),
    
            commonjs({
                exclude: "node_modules",
                ignoreGlobal: true,
            }),
    
            typescript({
              useTsconfigDeclarationDir: true,
              tsconfig: "rollup.tsconfig.json",
            }),
        ],
    
    }, {
        input: './dist/types/src/index.d.ts',
        output: [{ file: './dist/index.d.ts', format: "esm" }],
        external: EXTERNAL,
        plugins: [dts()],
    }];
    

    apps > lerna.json :

    {
      "packages": ["apps/**/*", "packages/**/*"],
      "version": "0.0.1",
      "npmClient": "yarn",
      "useWorkspaces": true
    }
    

    apps > package.json :

    ...
    "dependencies": {
        "@myscope/lib": "file:../lib"
    },
    ...
    

    注意这是一个 file: 导入只是为了更容易地开发和测试更改。

    我还尝试添加 resolutions 对双方 应用程序>包裹json apps > app > package.json ,但也没什么好运气…:

    "resolutions": {
      "@mui/material": "5.2.8"
    }
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   Danziger    4 年前

    这可能不是最好的解决方案,但我通过导出 ThemeProvider 从…起 lib :

    export { ThemeProvider as MyComponentThemeProvider } from "@mui/material/styles";
    

    现在,当用这个在 app :

    <MyComponentThemeProvider theme={ MY_CUSTOM_THEME }>
      <MyComponent{ ...myComponentProps } />
    </MyComponentThemeProvider>
    

    一切正常:

    ✅ Unique React
    ✅ Unique ThemeProvider
    

    另外,看看 https://github.com/facebook/react/issues/19541

    推荐文章