Skip to content

Packaging Components (Legacy)

Geoff Pleiss edited this page Jul 27, 2015 · 1 revision

(LEGACY) Packaging Pivotal UI

These are legacy instructions. We're keeping them around because they document the motivation for our packaging strategy. Please refer to our getting started documentation for more up-to-date instructions on using our module system.


Pivotal UI is a component library for Pivotal applications. It is built on Bootstrap and has many more components than any single app would need. You can include the entire library if you want, but the unused components increase the size of your assets and add opportunities for namespace collisions and unexpected behavior. Ideally, you would like to get only the components you want

Loading JavaScript

The applications maintained by the Pivotal UI team all use node and npm to manage the assets. The client-side JavaScript is created using Webpack (the examples should also work with Browserify). The apps are all based on React. Here is an example usage of Alerts components:

First, install the component:

npm install pui-react-alerts --save

Next, use it in your application:

var React = require('react/addons');
var SuccessAlert = require('pui-react-alerts').SuccessAlert;
var ErrorAlert = require('pui-react-alerts').ErrorAlert;

var MyComponent = React.createClass({
  propTypes: {
    success: React.PropTypes.boolean
  }
  render: function() {
    var alert;    
    if (this.props.success) {
      return (<UI.SuccessAlert withIcon>success</UI.SuccessAlert>);
    } else {
      return (<UI.ErrorAlert withIcon>error</UI.ErrorAlert>);
    }
  }
});

MyComponent will render a green alert with "success" and a checkbox if success is true and a red alert with "error" and a warning symbol if success if false. The component system in React allows you to easily encapsulate nested HTML in a single tag, so the user does not need to know the html generated by the alerts.

Loading CSS

Loading client-side JavaScript from npm is a mostly-solved problem. The only service provided by Pivotal UI in this case is publishing an npm package for each React component separately. Loading css is another matter. The CommonJS require is only designed for use with JavaScript. Webpack does offer partial solutions, but Pivotal UI is a component library and cannot dictate how users compile their assets.

CSS dependencies

The Alerts component requires the pui-css-alerts package, which includes all of the alert-specific css. There are libraries like rework-npm that could load this css file. We need more css files however. pui-css-alerts requires pui-css-typography and pui-css-bootstrap, which are building blocks required by many other packages. The end user needs pui-css-typography and pui-css-bootstrap to load before pui-css-alerts, but they should not have to know about any of this.

Dr Frankenstyle

To get all of the styles you want, including the dependencies, we wrote a small utility Dr Frankenstyle. Dr Frankenstyle will find all of the css packages in your npm tree and loads them in the correct order without duplicates. It identifies css packages by looking for the style keyword in the package.json, which should point to a css file.

Using Dr Frankenstyle requires a small gulp (or grunt) task:

var gulp = require('gulp');
var fs = require('fs');
var path = require('path');
 
gulp.task('buildCss', function(callback) {
  var DrFrankenstyle = require('dr-frankenstyle');
  DrFrankenstyle(function(css) {
    fs.writeFile(path.resolve('public', 'pui.css'), css, callback);
  });
});

Once this task is part of your asset build step and you serve the folder with pui.css (public in the example), you can include a link tag in your html

<link rel="stylesheet" type="text/css" href="pui.css"/>

CSS Packaging Beyond Pivotal UI

We are currently using this packaging story in xray and it is quite convenient. We can update, add, or remove individual components and it is just as easy as maintaining our JavaScript dependencies (React, Babel, Lodash, ...). There is nothing in Dr Frankenstyle that is unique to Pivotal UI. The only non-standard interaction is the use of the style key in the package.json (the style keyword is used in the same way by rework-npm). Any CSS libraries with nested dependencies should be able to offer the same work flow.