Overview
The goal of this project is to enable us to share components in npm. I've split it into three responsibilities:
- Bundling static resources in npm and getting a public URL to them
- Requiring stylesheets in a way that works on both the client and the server
- Optimizing stylesheets (both as a necessity and as a demo for how to do it in the future for images)
statics
statics
implements the first item on this list. You specify a staticRoot
key in your package.json
and you can run the collect-static
command on your project. It will link all the static resources into the directory of your choice that you can put on a CDN or a development server. When you run or browserify your app, run it with a STATIC_ROOT variable pointing to where you uploaded the directory. This will be available in your code as process.env.STATIC_ROOT
. So if you have staticRoot
in your package set to ./statics
and you have a file ./statics/myfile.jpg
, the public URL for it will always be process.env.STATIC_ROOT + 'myfile.jpg'
.
browserify
(via envify
), webpack
and node
all support this functionality.
stylesheets
stylesheets
implements the second item on the list. If you have set up your statics as described above and you want to include a stylesheet, simply do: var requireStylesheet = require('stylesheets').requireStylesheet; requireStylesheet(process.env.STATIC_ROOT + 'mystyles.css');
Caveat: this must be statically analyzable, so the function call must use the identifier requireStylesheet
and may only contain string literals, concat operators, and process.env.STATIC_ROOT
. This will allow for future tooling to be smart.
requireStylesheet()
is smart about its environment. If it detects it's in the browser it appends a <link>
tag to the head if it's not already there. If it detects it's on the server it will generate markup for you. Here's how:
var stylesheets = require('stylesheets');
var markup = stylesheets.getHeadMarkupFor(function() {
// code that calls stylesheets.requireStylesheet() executes in here
});
// markup is a string containing `<link>` tags that you can insert into your static HTML response
This allows the same code to run on both the client and the server, leaves the door open for future optimizations with static analysis, and leaves the door open for new resource types (i.e. creating a sprited-image
library similar to stylesheets
).
statics-stylesheets
This is a plugin for the statics
tool. Simply add "staticPlugin": "statics-stylesheets"
to your package.json
and when the NODE_ENV=production
environment variable is set collect-static
will concatenate all of your stylesheets together into one global stylesheet.
What needs to be done
I need to get the react-boilerplate
and react-browserify-template
packages (used by the generator-react-quickstart
yeoman generator) to work with these. When that's done, people can use Yeoman to simply do yo react-quickstart
to start hacking an app and can npm install react-datepicker
to use components. And if they want to build a new sharable component they just do yo react-quickstart --library
and a skeleton library is set up for them.
@chenglou if you could help with getting these integrated (it's mostly straightforward except for JSX in react-browserify-template
) we could ship this in January!