Home > Enterprise >  Webpack: Error: Element type is invalid: expected a string (for built-in components) or a class/func
Webpack: Error: Element type is invalid: expected a string (for built-in components) or a class/func

Time:05-06

I want to create custom component and build with webpack

// packages/button/src/index.js

import React from 'react';

function Button({ href }) {
  return <a href={href}>Test</a>;
}

export default Button;

// webpack.config.js

const path = require('path');

const entries = {
  button: {
    import: '/packages/button/src/index.js',
    filename: './button/dist/button.js',
  },
};

module.exports = {
  entry: { ...entries },
  output: {
    filename: '[name].js',
    path: __dirname   '/packages',
    asyncChunks: true,
    libraryTarget: 'umd',
    globalObject: 'this',
  },
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          {
            loader: 'css-loader',
          },
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                strictMath: true,
              },
            },
          },
        ],
      },

      {
        test: /\.m?js$/,
        exclude: /(node_modules)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-react'],
          },
        },
        resolve: {
          fullySpecified: false,
        },
      },
      {
        test: /\.m?js/,
        resolve: {
          fullySpecified: false,
        },
      },
    ],
  },
  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 20000,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
  resolve: {
    alias: {
      Styles: path.resolve(__dirname, '/shared/styles'),
    },
  },
};

it builds component but when I want to import it from node_modules I got error

// App.js

import React from 'react';
import Button from '@custom/button';

const App = () => {
   return <Button />
}

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

CodePudding user response:

I have switched bundler from webpack to rollup and it solved my issue

//rollup.config.js

import resolve from 'rollup-plugin-node-resolve';
import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import postcss from 'rollup-plugin-postcss';

const packages = ['button', 'select'];
const COMMON = {
  external: ['react', 'react-dom'],
  plugins: [
    resolve({ extensions: ['.jsx', '.js', '.tsx'] }),
    postcss({
      minimize: true,
      modules: true,
      use: {
        sass: null,
        stylus: null,
        less: { javascriptEnabled: true },
      },
    }),
    babel({
      extensions: ['.jsx', '.js', '.tsx'],
      exclude: 'node_modules/**',
      presets: ['@babel/preset-env', '@babel/preset-react'],
    }),
    commonjs(),
  ],
};

const ENTRIES = packages.map((pkg) => ({
  input: `./packages/${pkg}/src/index.js`,
  output: {
    file: `./packages/${pkg}/dist/index.js`,
    exports: 'default',
    format: 'cjs',
  },
  ...COMMON,
}));

export default ENTRIES;
  • Related