0.4.0 • Published 6 years ago

inferno-compat-mui v0.4.0

Weekly downloads
-
License
MIT
Repository
-
Last release
6 years ago

inferno-compat-mui

This package provides a compatibility layer between Material-UI and Inferno.

Inferno is not 100% compatible with React. Material UI is a relatively large library, and requires a lot of the new features that React provides. Installing inferno-compat is not sufficient. But it turns out that only a few pieces were missing.

  1. Inferno does not have React.createContext (issue #1299). Material-UI relies on this function to ensure it is running on a fairly recent version of React. It has no other purpose. This package patches Inferno and sets createContext to an empty function just to satisfy Material-UI.

  2. Inferno does not have fragments (issue #501). It seems that Material-UI uses it mostly on its SVG icons. This package provides a very crude shim to cover this shortage. Good news is that fragments are about to come to Inferno. This shim will have a very short life span.

  3. Inferno does not have Component.getDerivedStateFromProps (issue #1371). This package hooks into Inferno's options.beforeRender to call getDerivedStateFromProps for those components who provide it.

  4. Material-UI's Input component relies on onChange to receive text, but Inferno uses onInput instead. This library patches Input, rewiring onChange to onInput.

  5. Some components of Material-UI (notably Select) attempt to reset the target property of the event object when an item is selected, or when the component looses focus. While this is fine for the React event object, it is not for Inferno's counterpart. This package will dynamically clone instances of Select and provide its own implementations of handleItemClick and handleBlur. The replacement functions do not attempt to reset event.target. Sadly, I could not simply decorate or override those functions. I had to copy them over and make a couple of adjustments. Material-UI folks decided to implement them as ES6 class properties instead of standard prototype functions.

Disclaimer

As mentioned, this package is a compilation of quick hacks that provide interoperability between Material-UI and Inferno. Expect things to break.

This package was tested on a single, small, Material UI 1.5 application. The tests did not cover every Material-UI component, or use case, as it was not intended to. Although I expect it work with most components, it might not. YMMV.

This is just the first step torwards moving away from React, into a faster library. The NPM package should be merely a convenient way to replace React with Inferno, nothing more.

To really take full advantage of Inferno performance on your Material-UI application, be prepared to work.

  1. Implement the counterparts of React.createContext, React.Fragment and Component.getDerivedStateFromProps on Inferno. Respectively, issues #1299, #501 and #1371.

  2. Fork Material-UI, patch the incompatible components, create test cases, submit pull requests, and hope they get merged.

  3. Drop this package from your project.

  4. Alias React to Inferno.

Installation (Webpack)

Install Inferno and inferno-compat-mui.

npm install --save inferno inferno-compat-mui

Then, open your Webpack configuration file and add aliases for react, react-dom, and patched Material-UI components.

module.exports = {
    mode: …,

    entry: …,

    output: …,

    module: …,

    resolve: {
        alias: {
            // Alias React to Inferno.
            react: 'inferno-compat-mui',
            'react-dom': 'inferno-compat-mui',

            // Alias Material UI components to shims.
            '@material-ui/core/Input$': 'inferno-compat-mui/mui_input_shim',
            '@material-ui/core/Select$': 'inferno-compat-mui/mui_select_shim',
            '@material-ui/core/TextField$': 'inferno-compat-mui/mui_textfield_shim'
        }
    }
}

Notice the $ suffix on the component aliases above. Omitting them will create circular dependencies on your project.

Important considerations

As you can see in the previous section, component aliases require ES6 default imports in your application code.

So, instead of doing named imports.

import { Select, TextField } from '@material-ui/core' // Not supported!

Do default imports.

import Select from '@material-ui/core/Select'
import TextField from '@material-ui/core/TextField'

This import style is used on all code samples, and is recommended first by Material-UI docs.