Search code examples
javascriptsystemjs

How do I map ./[module] to /[module]/[module].js in System.JS?


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.


Solution

  • 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.