Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import ReactJS Material UI using a CDN through Webpack's externals?

The Problem:

I'm trying to create a website (web app) with React and Material UI, it's working just fine using npm. But when I try to make them as externals and import them through a CDN instead, I get an error with Material UI (React works fine).

My Code:

I linked CDNs in index.html like this:

<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@material-ui/core/umd/material-ui.production.min.js"></script>
<script src="app.min.js"></script>

And in app.min.js, I imported them like this:

import { Component } from 'react';
import ReactDOM from 'react-dom';
import { Button } from '@material-ui/core';

My Attempt:

In the webpack.config.js, I tried the following (again, only Material UI causes an error):

  1. Using a string:

    externals: {
      'react': 'React',
      'react-dom': 'ReactDOM',
      '@material-ui/core': 'Button'
    }
    

    gives:

    Uncaught ReferenceError: Button is not defined

  2. Using an object:

    externals: {
      'react': 'React',
      'react-dom': 'ReactDOM',
      '@material-ui/core': {
        Button: '@material-ui/core'
      }
    }
    

    gives:

    TypeError: Cannot read property 'Button' of undefined

  3. Doing it manually, so Material UI isn't in externals:

    externals: {
      'react': 'React',
      'react-dom': 'ReactDOM'
    }
    

    Then removing minified Material UI code from app.min.js, this leaves the code incomplete and it doesn't run.

  4. Searched through GitHub issue and SO questions without any luck, some links:

    • How should material-ui be externalized when bundling with webpack
    • Externals defined in webpack.config still getting error module not found
    • React CDN: Webpack externals library not resolved in code

Any idea how can I solve this?

like image 429
Omar Einea Avatar asked Jan 29 '23 00:01

Omar Einea


1 Answers

Solution::

in webpack.config.js:

externals: {
  'react': 'React',
  'react-dom': 'ReactDOM',
  'material-ui': 'window["material-ui"]'
},

then in app.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Button } from 'material-ui';

Explanation:

If you check the cdn version of material ui js, you will find it exports its content in to material-ui namespace.

enter image description here

if you config webpack like:

'material-ui': 'material-ui'

webpack will compile it to:

enter image description here

which leads to the code looking for material and ui in global environment which does not exist. So we have to specify window["material-ui"] explicitly

like image 133
loveky Avatar answered May 07 '23 03:05

loveky