微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法使用craco在create-react-app中导入其他项目的组件

如何解决无法使用craco在create-react-app中导入其他项目的组件

我在将组件从一个 React 项目导入另一个项目时遇到问题。这些问题似乎非常基本,但我真的很难弄清楚问题出在哪里以及实现我的目标的确切 craco 配置是什么。

导出项目

我正在导出 App,这是一个功能性 React 组件。

src/index.js

import App from "./App";
export default App;

我用craco主要是因为Tailwindcss和antd,这是配置文件

craco.config.js

const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const WebpackBar = require("webpackbar");
const CracoAntDesignPlugin = require("craco-antd");

const path = require("path");

module.exports = {
  style: {
    postcss: {
      plugins: [require("tailwindcss"),require("autoprefixer")],},webpack: {
    plugins: [
      new WebpackBar({ profile: true }),...(process.env.NODE_ENV === "development"
        ? [new BundleAnalyzerPlugin({ openAnalyzer: false })]
        : []),],configure: (webpackConfig,{ env,paths }) => {
      paths.appBuild = webpackConfig.output.path = path.resolve("dist");

      webpackConfig.output = {
        ...webpackConfig.output,filename: "index.bundle.js",path: path.resolve(__dirname,"dist"),library: "library",libraryTarget: "umd",};

      webpackConfig.entry = path.join(__dirname,"./src/index.js");

      return webpackConfig;
    },plugins: [
    {
      plugin: CracoAntDesignPlugin,options: {
        customizeThemeLesspath: path.join(
          __dirname,"./src/styles/variables.less"
        ),lessLoaderOptions: {
          lessOptions: {
            javascriptEnabled: true,};

我正在使用 npm 发布我的包并将其导入到另一个项目中。这是 package.json 启动配置(出于隐私考虑删除了信息):

package.json

{
  "name": [company-repo-name],"version": "1.1.1-alpha16","homepage": ".","repository": [company-repo],"main": "dist/index.bundle.js","publishConfig": {
    "registry": [company-registry]
  },...

npm run build 按预期工作并在 dist 文件夹内生成一个 index.bundle.js。我不确定问题是否出在这里,但该文件充满了缩小的功能并且似乎没有导出任何内容

消费者项目

通过 npm 安装导出项目工作正常,尝试导入 App 组件没有结果:

  • import App from [company-repo-name]; 给我 {}(空对象)
  • import { App } from [company-repo-name]; 给我 undefined

我目前不知道问题出在哪里,我期待着尝试的建议。

解决方法

因此,经过几天摆弄 webpack 配置后,我看到了 this 救命文章。我没有尝试的是文章说的第一件事:“输出单个包而不是块”。使用技巧的行包括更改优化 webpack 配置:

config.optimization.splitChunks = {
    cacheGroups: {
      default: false,},};
config.optimization.runtimeChunk = false;

按照文章中介绍的所有步骤进行操作后,我最终得到了如下所示的 craco webpack 配置:

configure: (config,{ paths }) => {
  paths.appBuild = config.output.path = path.resolve("build");
  if (process.env.REACT_APP_INJECTABLE === "true") {
    config = disableChunks(config);
    config = makeInjectable(config,{ paths });
  }
  return config;
}

disableChunks() 是从将构建整合到单个包中的辅助文件中导入的。我还禁用了最小化,因此我的消费者项目中可能会有更多描述性错误。这是disable-chunks.js

module.exports = function disableChunks(config) {
  // Consolidate bundle instead of chunk
  // https://webpack.js.org/plugins/split-chunks-plugin
  config.optimization.splitChunks = {
    cacheGroups: {
      default: false,};

  // Move runtime into bundle instead of separate file
  // https://webpack.js.org/configuration/optimization
  config.optimization.runtimeChunk = false;

  config.optimization.minimize = false;

  // JS
  // https://webpack.js.org/configuration/output
  config.output.filename = "main.js";

  // CSS
  // https://webpack.js.org/plugins/mini-css-extract-plugin
  const cssPluginIdx = config.plugins
    .map((p) => p.constructor.name)
    .indexOf("MiniCssExtractPlugin");
  if (cssPluginIdx !== -1) {
    config.plugins[cssPluginIdx].options.filename = "main.css";
  }

  return config;
};

最后一个配置文件是 make-injectable.js,用于设置输出配置。我之前已经配置过,但出于组织原因决定将其移至另一个文件。

module.exports = function makeInjectable(config,{ paths }) {
  // Output a UMD module and define its name via the library key.
  // This key will be what is referenced when the hub looks for
  // the correct module to dynamically load after the bundle is
  // injected into the DOM
  // https://webpack.js.org/configuration/output
  config.output.library = basename(process.env.npm_package_name);
  config.output.libraryTarget = "umd";

  // Set separate entry point when building the injectable lib
  // https://webpack.js.org/concepts/entry-points
  config.entry = `${paths.appSrc}/index.injectable.js`;

  // Exclude shared dependencies to reduce bundle size
  // https://webpack.js.org/configuration/externals
  config.externals = {
    react: "react","react-router-dom": "react-router-dom",};

  return config;
};

同样,对我有用的代码基本上是从Implementing a Micro-Frontend Architecture With React的文章J.C. Yamokoski中复制的(如果你遇到这个问题,谢谢我的人)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。