Material-ui: Babel plugin to cherry-pick used modules a.k.a - `babel-plugin-material-ui`

Created on 23 Nov 2016  路  21Comments  路  Source: mui-org/material-ui

Most helpful comment

Old ticket, but you should also take a look at babel-plugin-import: https://github.com/ant-design/babel-plugin-import

It doesn't seem to resolve the issue where a component is not at the root, like the ./BottomNavigation/BottomNavigationItem example, but still maybe another way to explore...

All 21 comments

That sounds like a work around waiting for the tree shaking to work correctly.
I wish someone made an abstraction so we can ship it easily. (cc @neoziro if you are interested for recompact)

@oliviertassinari we could think about a generic way to do it for our two librairies, what do you think?

@oliviertassinari actually it's really easy to implement, if you look to this exampe

What it does:

  1. Find ImportDeclaration with material-ui package
  2. Replace each ImportSpecifier with new ImportDeclaration

So it will support only import {List, ListItem} from 'material-ui' declarations.

And will ignore:

  • import mui from 'material-ui'
  • import * as mui from 'material-ui'
  • import List from 'material-ui/List
  • const {List, ListItem} = require('material-ui')

@umidbekkarimov The babel plugin you linked is interesting. It doesn't have a hard dependency on the module.
I think that it can be parametrized quite easily.
We could call that plugin babel-plugin-transform-module-cherry-pick.

@oliviertassinari this part is written for 'commonjs' syncax (this file)

So minimal configuration should look like:

plugins: [
  ["babel-plugin-transform-module-cherry-pick", {
    "package": "material-ui",
    "modules": "import" // "amd", "common", "import"
  }]
]

What about people needed this plugin for different libraries?
I'm not sure that we can do:

plugins: [
  ["babel-plugin-transform-module-cherry-pick", {
    "package": "material-ui",
    "modules": "import"
  }],
  ["babel-plugin-transform-module-cherry-pick", {
    "package": "another-package",
    "modules": "import"
  }]
]

@oliviertassinari true,
what about:

{
  "plugins": [
    [
      "babel-plugin-transform-module-cherry-pick",
      {
        "packages": [
          {
            "name": "material-ui",
            "modules": "import",
          },
          {
            "name": "another-package",
            "modules": "import"
          }
        ],
      }
    ]
  ]
}

@umidbekkarimov Yeah, that interface looks good to me 馃憤 . I can find some time to work on this weekend. But if you want to give it a shot, go ahead :).

@oliviertassinari let's play game - "who will have free time first" :)
Actually there is not much work here, I guess it's possible to complete in 2-3 hours, so I will ping here when I start.

Ok, babel-plugin-material-ui ready for use, idea with generic plugin died as soon as I start parsing index files of different libs - so much pain. For generic purpose I can split cherry-picking part to the separate babel-cherry-pick-modules-utils package so it would be easier to write similar plugins.

Nice! I need it for https://github.com/neoziro/recompact/. I think I can develop it, and then we can try to factorize code in babel-cherry-pick-modules-utils.

@umidbekkarimov I will try, I keep you up to date.

Having a closer look at the transformation pipeline. The process can be represented with the following steps.

In

import { Card, BottomNavigationItem } from 'material-ui'

ImportName extracted

const importsExtracted = [Card, BottomNavigationItem];

Import name mapped

const importsMapped = [{
  Card: './Card'
}, {
  BottomNavigationItem: './BottomNavigation/BottomNavigationItem'
}];

Out

import Card from 'material-ui/Card';
import BottomNavigationItem from 'material-ui/BottomNavigation/BottomNavigationItem';

idea with generic plugin died as soon as I start parsing index files of different libs - so much pain

I agree, the most challenging part is to determine the mapping between the ImportName and the module path. That's basically the problem that the tree shaking feature backed into roll-up / webpack2 should be answering.
I don't think that we support all the ES2015 export syntax, but great work here 馃憤 .

Cool, even the LocalName is supported.

I don't think that we support all the ES2015 export syntax

I tried to add support for exports - but lack of documentation killed all my enthusiasm.

but great work here 馃憤 .

Thank you! My current project married to material-ui (over 160 components use it). So I did it for my team basically 馃槑

Cool, even the LocalName is supported.

Thanks for remind, totally forgot to add test case for it 馃槄


BTW! Just released v0.3.0 with material-ui/svg-icons support

If one of you does that plugin @neoziro I am all in to add some code to it. We are gonna need it also in React InstantSearch.

Actually, I'm wondering if we couldn't be using babel-lodash-plugin as done with recompose:
https://github.com/acdlite/recompose/commit/992d70ed15cd7e01e5ad4c15f587150cbef958b4.
At least, it would be great to document that usage for users. I'm reopening the issue.

OG, this one is really interesting !!

@oliviertassinari Ohh interesting

Old ticket, but you should also take a look at babel-plugin-import: https://github.com/ant-design/babel-plugin-import

It doesn't seem to resolve the issue where a component is not at the root, like the ./BottomNavigation/BottomNavigationItem example, but still maybe another way to explore...

The documentation has been updated with the suggested solution. We can close the issue :).

Was this page helpful?
0 / 5 - 0 ratings

Related issues

newoga picture newoga  路  3Comments

reflog picture reflog  路  3Comments

ryanflorence picture ryanflorence  路  3Comments

mb-copart picture mb-copart  路  3Comments

ericraffin picture ericraffin  路  3Comments