16

I'm trying to import material-ui into my React app using System.JS

In my app, I'm doing this:

import {AppBar, Tabs, Tab, Card, CardTitle} from 'material-ui';

Here's my System.JS config:

System.config({
    baseURL: '/node_modules',
    packageConfigPaths: [
        '*/package.json'
    ],
    packages: {
        '.': {
            defaultExtension: 'js',
            main: 'index.js'
        },
    }
});

It loads node_modules/material-ui/index.js which has a bunch of imports inside it:

var _AppBar2 = require('./AppBar');

var _AppBar3 = _interopRequireDefault(_AppBar2);

var _AutoComplete2 = require('./AutoComplete');

var _AutoComplete3 = _interopRequireDefault(_AutoComplete2);

// ... etc, about 40 of them.

exports.AppBar = _AppBar3.default;
exports.AutoComplete = _AutoComplete3.default;

// ... etc

In the package's tree structure, each of these modules is stored under its own directory like this:

material-ui/
  index.js
  AppBar/
     AppBar.js
     index.js -- just reexports './AppBar'
  AutoComplete/
     AutoComplete.js
     index.js -- just reexports './AutoComplete'

, etc., so in fact to import material-ui/AppBar, I need System.JS to load node_modules/material-ui/AppBar/AppBar.js or node_modules/material-ui/AppBar/index.js.

Instead, System.JS is trying to load node_modules/material-ui/AppBar.js which is not there.

If I add individual entries for each module under packages:

'material-ui': {
    map: {
        './AppBar': './AppBar/AppBar.js'
    }
}

it works, however wildcards:

'material-ui': {
    map: {
        './*': './*/*.js'
    }
}

don't.

How do I make System.JS map ./* to ./*/*.js under a certain package?


As a side note, browserify does not have any problems with this layout, so when I bundle my app using browserify just by calling browserify('./path/to/root/index.js'), all material-ui modules get imported without any issues.

Quassnoi
  • 413,100
  • 91
  • 616
  • 614
  • The real issue here is that SystemJS doesn't support Node module resolution. I think they plan to add it, but for now stuff like Browserify and Webpack can do stuff like that out of the box. Is there any reason you need to use SystemJS? – Menello Feb 22 '17 at 17:17
  • @Menello: no reason at all, except I'm only familiar with Browserify's ability to do bundles (that's how I actually use it in my system) and not familiar with Webpack at all. I was under impression SystemJS could parse `package.json` in the modules. What I'm after is to be able to use individual packages from `node_modules` and the source tree without having to bundle them during the development cycle, so that I could hack a package in `node_modules` in place, refresh and instantly see what happens, without having to bundle the whole thing. I'm not going to use System.JS in production. – Quassnoi Feb 22 '17 at 19:49
  • If you're serving your node modules folder you could just add a script tag to it: ``? Would that be sufficient? – Menello Feb 22 '17 at 22:10
  • @Menello: for all the modules in the folder you mean? I'd like them load on demand recursively, as I import them in the JS code – Quassnoi Feb 22 '17 at 23:44
  • Hmm I don't think that's possible besides using a bundling system or maybe you could do it in a browser that supports JS imports... That's interesting though. – Menello Feb 23 '17 at 01:32

1 Answers1

4

Wildcard paths are not supported in System.js. You will have to manually add an entry for each module:

'material-ui': {
  map: {
    './AppBar': './AppBar/AppBar.js',
    './AppHeader': './AppHeader/AppHeader.js',
    './AppFooter': './AppFooter/AppFooter.js',
    //etc
  }
}

You can also use jspm to generate that list for you.

hackerrdave
  • 6,486
  • 1
  • 25
  • 29
  • 1
    Note that the comment you link to is talking about the `paths` setting, not the `map` setting. – Louis Feb 20 '17 at 14:34
  • @hackerrdave: thanks. Is `jspm` a tool for generating System.JS configs? (seems like yes, it's just not obvious from the documentation to me). Given that I have an `index.js` file which recursively loads a bunch of modules and which I can convert to a bundle by running it through `browserify` with zero configuration, as mentioned in OP, how would I use `jspm` to generate the config? – Quassnoi Feb 20 '17 at 15:47