webpack-isomorphic-tools
Advanced tools
Comparing version 0.6.0 to 0.6.1
{ | ||
"name": "webpack-isomorphic-tools", | ||
"version": "0.6.0", | ||
"version": "0.6.1", | ||
"description": "Transforms CSS-alike text into a React style JSON object", | ||
@@ -5,0 +5,0 @@ "main": "babel-transpiled-modules/index.js", |
141
README.md
@@ -12,3 +12,3 @@ # webpack-isomorphic-tools | ||
Is a small helper module providing full support for isomorphic (universal) rendering when using Webpack. | ||
Is a small helper module providing support for isomorphic (universal) rendering when using Webpack. | ||
@@ -56,9 +56,7 @@ ## What it does and why is it needed? | ||
When you render your Html page on the server you need to include all the client scripts using `<script src={...}/>` tags. And for that purpose you need to know the real paths to your Webpack compiled javascripts. Which are gonna have names like `main-9059f094ddb49c2b0fa6a254a6ebf2ad.js` because we are using the `[hash]` file naming feature of Webpack which is required to make browser caching work correctly. And `webpack-isomorphic-tools` tells you these filenames (see the [Usage](#usage) section). It also tells you real paths to your Css styles in case you're using [extract-text-webpack-plugin](https://github.com/webpack/extract-text-webpack-plugin) (which is usually the case for production build). | ||
When you render your Html page on the server you need to include all the client scripts using `<script src={...}/>` tags. And for that purpose you need to know the real paths to your Webpack compiled javascripts. Which are gonna have names like `main-9059f094ddb49c2b0fa6a254a6ebf2ad.js` because we are using the `[hash]` file naming feature of Webpack which is required to make browser caching work correctly. And `webpack-isomorphic-tools` tells you these filenames (see the [Usage](#usage) section). | ||
For a comprehensive example of isomorphic React rendering you can look at this sample project: | ||
It also tells you real paths to your CSS styles in case you're using [extract-text-webpack-plugin](https://github.com/webpack/extract-text-webpack-plugin) which is usually the case for production build. | ||
* [webpack-isomorphic-tools initialization](https://github.com/halt-hammerzeit/cinema/blob/master/code/server/entry.js) | ||
* [webpage rendering express middleware](https://github.com/halt-hammerzeit/cinema/blob/master/code/server/webpage%20rendering.js) | ||
* [the Html file](https://github.com/halt-hammerzeit/cinema/blob/master/code/client/html.js) | ||
Aside all of that, `webpack-isomorphic-tools` is highly extensible, and finding the real paths for your assets is just the simplest example of what it's capable of. Using [custom configuration](#configuration) one can make `require()` calls return virtually anything (not just String, it may be a JSON object, for example). For example, if you're using Webpack [css-loader](https://github.com/webpack/css-loader) modules feature (also referred to as ["local styles"](https://medium.com/seek-ui-engineering/the-end-of-global-css-90d2a4a06284)) you can make `require(*.css)` calls return JSON objects with CSS class names like they do in [react-redux-universal-hot-example](https://github.com/erikras/react-redux-universal-hot-example#styles) (it's just a demonstration of what one can do with `webpack-isomorphic-tools`, and I'm not using this "modules" feature of `ccs-plugin` in my projects). | ||
@@ -68,3 +66,3 @@ ## Installation | ||
```bash | ||
$ npm install webpack-isomorphic-tools | ||
$ npm install webpack-isomorphic-tools --save | ||
``` | ||
@@ -74,3 +72,3 @@ | ||
First you create your Webpack configuration like you usually do except that you don't add module loaders for the `assets` you decide to manage with `webpack_isomorphic_tools` (`webpack_isomorphic_tools` will add these module loaders to your Webpack configuration instead of you doing it by yourself) | ||
First you take your existing Webpack configuration and then you instantiate `webpack_isomorphic_tools` and `.populate()` your Webpack configuration with it. | ||
@@ -113,3 +111,7 @@ ### webpack.config.js | ||
// (because it will be used in the web server code too) | ||
new Webpack_isomorphic_tools(webpack_configuration, require('./webpack-isomorphic-tools')).populate(webpack_configuration) | ||
new Webpack_isomorphic_tools(webpack_configuration, require('./webpack-isomorphic-tools')). | ||
// enter development mode (see the API section below for .development() method explanation) | ||
.development() | ||
// populate the existing webpack configuration | ||
.populate(webpack_configuration) | ||
@@ -119,2 +121,8 @@ module.exports = webpack_configuration | ||
What does `.development()` method do? It enables development mode. In short, when in development mode, it disables asset caching (and enables asset hot reload). This is required only for your development webpack configuration (i.e. the one used with `webpack-dev-server`). | ||
What does `.populate()` method do? It adds a couple of Webpack plugins to the end of the `plugins` list. The first one outputs some green info to the console when in development mode. The second one parses webpack "stats" to extract, for example, the real file paths for your assets (or it can do whatever you need it to do using [extension points](#configuration)). | ||
`webpack_isomorphic_tools` populator has an optional feature of adding module loaders to your webpack configuration. Why might it come in handy? The reason is that it knows how to generate a suitable `test` property of the loader (provided a file extension or a list of extensions). You can view it as a small bonus feature. In this particular example we're taking use of this feature by not specifying image loader in the existing webpack configuration: it will be created automatically during `.populate()` method call because we provided the `loader` parameter for the images asset type in `webpack-isomorphic-tools` configuration. | ||
### webpack-isomorphic-tools.js | ||
@@ -136,3 +144,3 @@ | ||
Then you create your server side instance of `webpack-isomorphic-tools` and register a Node.js require hook in the very main server script (and your web application code will reside in the server.js file which is `require()`d in the bottom): | ||
That was the client side. Next, the server side. You create your server side instance of `webpack-isomorphic-tools` and register a Node.js require hook in the very main server javascript file (and your web application code will reside in some `server.js` file which is `require()`d in the bottom): | ||
@@ -148,6 +156,4 @@ ### main.js | ||
// registers Node.js require() hooks for your assets | ||
// (these hooks must be set before you require() any of your React components) | ||
.register() | ||
// .ready() call is necessary in the end: | ||
// it waits for webpack-isomorphic-tools to finish all the preparations needed | ||
// waits for webpack-isomorphic-tools to finish all the preparations needed | ||
.ready(function() | ||
@@ -172,4 +178,4 @@ { | ||
{ | ||
// clear require() cache (used internally) | ||
// you don't need to understand the purpose of this call | ||
// clear require() cache if in development mode | ||
// (makes asset hot reloading work) | ||
if (_development_) | ||
@@ -218,2 +224,3 @@ { | ||
// (when the application launches) | ||
// you can refer to the "Require() vs import" section for more explanation | ||
const picture = require('./../cat.jpg') | ||
@@ -251,3 +258,3 @@ | ||
{Object.keys(assets.javascript).map((script, i) => | ||
<script src={assets.javascript[script]}/> | ||
<script src={assets.javascript[script]} key={i}/> | ||
)} | ||
@@ -263,23 +270,25 @@ </body> | ||
And that's it: now your web application is isomorphic. | ||
And that's it: now you can `require()` your assets "isomorphically" (both on client and server). | ||
If you don't like having the `main.js` file before all your web application code you can omit creating `main.js`. In this case you won't register a Node.js require hook and the only difference would be a bit more verbose syntax when `require()`ing images in your web components: | ||
## A working example | ||
```javascript | ||
// (use webpack DefinePlugin for setting _client_ environment variable) | ||
// (webpack_isomorphic_tools is taken from the "global" scope) | ||
const picture = _client_ ? require('./../cat.png') : webpack_isomorphic_tools.require('./cat.png') | ||
``` | ||
For a comprehensive example of isomorphic React rendering you can look at this sample project: | ||
## Fully working example project | ||
* clone [this repo](https://github.com/halt-hammerzeit/cinema) | ||
* npm install | ||
* npm run dev | ||
* `npm install` | ||
* `npm run dev` | ||
* wait a moment for Webpack to finish the first build (green stats will appear in the terminal) | ||
* go to http://localhost:3000 | ||
* Ctrl + C | ||
* npm run production | ||
* go to http://localhost:3000 | ||
* go to `http://localhost:3000` | ||
* `Ctrl + C` | ||
* `npm run production` | ||
* go to `http://localhost:3000` | ||
Some source code guidance for this particular project: | ||
* [webpack-isomorphic-tools configuration](https://github.com/halt-hammerzeit/cinema/blob/master/webpack/isomorphic.js) | ||
* [webpack-isomorphic-tools client initialization](https://github.com/halt-hammerzeit/cinema/blob/master/webpack/development%20server.js) | ||
* [webpack-isomorphic-tools server initialization](https://github.com/halt-hammerzeit/cinema/blob/master/code/server/entry.js) | ||
* [webpage rendering express middleware](https://github.com/halt-hammerzeit/cinema/blob/master/code/server/webpage%20rendering.js) | ||
* [the Html file](https://github.com/halt-hammerzeit/cinema/blob/master/code/client/html.js) | ||
## Configuration | ||
@@ -337,25 +346,3 @@ | ||
// [optional] | ||
// | ||
// transforms a webpack stats module name | ||
// to an asset name | ||
// | ||
// arguments: | ||
// | ||
// module - a webpack stats module | ||
// | ||
// options - various options | ||
// (development or production mode, | ||
// "debug" flag, | ||
// assets base path (on the disk or on the network), | ||
// regular_expressions{} for each asset type (by name), | ||
// "log" object (for logging)) | ||
// | ||
// returns: a String | ||
// | ||
// by default is: "return module.name" | ||
// | ||
naming: function(module) { ... }, | ||
// [optional] | ||
// | ||
// determines which webpack stats modules | ||
@@ -373,7 +360,7 @@ // belong to this asset type | ||
// options - various options | ||
// (development or production mode, | ||
// "debug" flag, | ||
// (development mode flag, | ||
// debug mode flag, | ||
// assets base path (on the disk or on the network), | ||
// regular_expressions{} for each asset type (by name), | ||
// "log" object (for logging)) | ||
// logger) | ||
// | ||
@@ -386,2 +373,24 @@ // returns: a Boolean | ||
// [optional] | ||
// | ||
// transforms a webpack stats module name | ||
// to an asset name | ||
// | ||
// arguments: | ||
// | ||
// module - a webpack stats module | ||
// | ||
// options - various options | ||
// (development mode flag, | ||
// debug mode flag, | ||
// assets base path (on the disk or on the network), | ||
// regular_expressions{} for each asset type (by name), | ||
// logger) | ||
// | ||
// returns: a String | ||
// | ||
// by default is: "return module.name" | ||
// | ||
naming: function(module, options) { ... }, | ||
// [required] | ||
@@ -399,9 +408,9 @@ // | ||
// options - various options | ||
// (development or production mode, | ||
// "debug" flag, | ||
// (development mode flag, | ||
// debug mode flag, | ||
// assets base path (on the disk or on the network), | ||
// regular_expressions{} for each asset type (by name), | ||
// "log" object (for logging)) | ||
// logger) | ||
// | ||
// returns: whatever (could be a filename, could be a JSON object) | ||
// returns: whatever (could be a filename, could be a JSON object, etc) | ||
// | ||
@@ -424,6 +433,10 @@ parser: function(module, options) { ... } | ||
#### .ready() | ||
#### .register() | ||
Waits for `webpack-isomorphic-tools` to finish all the preparations needed. To be more specific, it waits for Webpack to finish the build process and to output the assets info file. | ||
Registers Node.js `require()` hooks for your assets.This is what makes the `requre()` magic work on server. These `require()` hooks must be set before you `require()` any of your assets (e.g. before you `require()` any React components `require()`ing your assets). | ||
#### .ready(function callback() {}) | ||
Waits for `webpack-isomorphic-tools` to finish all the preparations needed. To be more specific, it waits for Webpack to finish the build process and to output the assets info file. You can get away without using this method but in that case make sure that Webpack has already finished the build process by the time you launch your web server. | ||
## Gotchas | ||
@@ -478,7 +491,7 @@ | ||
Initially based on [react-redux-universal-hot-example](https://github.com/erikras/react-redux-universal-hot-example) by Erik Rasmussen | ||
Initially based on the code from [react-redux-universal-hot-example](https://github.com/erikras/react-redux-universal-hot-example) by Erik Rasmussen | ||
Also the same codebase (as in the project mentioned above) can be found in [isomorphic500](https://github.com/gpbl/isomorphic500) by Giampaolo Bellavite | ||
Also uses require() hooking techniques from [node-hook](https://github.com/bahmutov/node-hook) by Gleb Bahmutov | ||
Also uses `require()` hooking techniques from [node-hook](https://github.com/bahmutov/node-hook) by Gleb Bahmutov | ||
@@ -485,0 +498,0 @@ ## Contributing |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
157374
528