React and jspm
Tim Kye
I've been tinkering with React a lot lately; I am really loving it. Since I still believe that jspm offers a better development and bundling experience than WebPack (unless you need hot module reloading), I spend some time this week getting a solid project template down for React and jspm.
Directory Structure
Let's just jump straight to the solution, and then break down the reasons.
Project
|--assets/
| |--css/
| |--fonts/
| |--images/
| +--stylus/
|--dist/
+--built.js
|--node_modules/
|--jspm_packages/
|--src/
|--jspm.config.js
+--server.js
Assets
I like to keep this stuff seperate from the code that will end up going into src
. I find myself going into these folders for very different reasons, and the fewer things I have to look for the easier it is to find them. It also feels like a natural seperation to me.
The css
directory is going to contain any external css, like the kind a 3rd party widget or plugin might need, as well as the compiled css generated by Stylus, my favorite css pre-processor. The stylus
directory will obviously contain these pre-processed files.
Dist
This will contain the build JavaScript files. It's in a seperate directory so that when production goes to host files, it can switch from hosting src
to hosting dist
. This stops uncompiled source code from being hosted, without the server needing to know which file exactly needs to be provided (in case I am datestamping on the fillename to cache bust).
3rd Part Code and Src
Both node_modules
and jspm_packages
are at the root to keep them out of the src
folder. When I try to Find all, having my code and only my code in a single folder saves me from digging through a lot of giant, minified results. I want all 3rd party code seperated from my app's code.
jspm.config.js
To get bundling to work alongside development hosting with the jspm_packages
folder outside the src
folder, I use the following config.
paths: {
"*": "src/*",
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*"
}
This allows my ES6 imports to reference app code without the src/
prefix.
server.js
To ensure bunlding works alongside development, jspm_packages
needs to get served at /jspm_packages
. jspm.config.js
also needs to be served, preferably from the root. I don't want to just host everything in __dirname
though; I only want to host what the public needs access to. Luckily express makes setting up multiple static directories easy.
var port = process.env.PORT || 9000,
ip = process.env.IP || "0.0.0.0",
isProduction = process.env.NODE_ENV == 'production',
clientDir = __dirname + (isProduction ? '/dist/' : '/src/'),
assetDir = __dirname + '/assets',
jspmConfigName = '/jspm.config.js',
jspmConfig = __dirname + jspmConfigName,
jspmDir = __dirname + '/jspm_packages/',
express = require('express'),
app = express();
//Configure
app.use('/jspm_packages', express.static(jspmDir));
app.use('/assets', express.static(assetDir));
app.use('/src', express.static(clientDir));
app.use(jspmConfigName, express.static(jspmConfig));
Yeoman
I've packaged all of this into a Yeoman generator: https://www.npmjs.com/package/generator-react-jspm