├── .gitignore ├── README.md ├── index.js ├── mixinReactProxy.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | /node_modules 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | react-router-proxy-loader 2 | ========================= 3 | 4 | Based on [react-proxy-loader](https://github.com/webpack/react-proxy-loader), adapted for `react-router` route handlers. 5 | 6 | ## Installation 7 | 8 | `npm install react-router-proxy-loader` 9 | 10 | ## Dependencies 11 | 12 | Which version to use depends on your version of `react-router` 13 | 14 | | react-router | react-router-proxy-loader | 15 | | ---------------- | ------------------------- | 16 | | 0.11.x and below | 0.1.x | 17 | | 0.12.x | 0.2.x | 18 | | 0.13.x | 0.3.x | 19 | | 1.x | 0.4.x | 20 | | 2.x and above | 0.5.x | 21 | 22 | 23 | ## Usage 24 | 25 | [Documentation: Using loaders](http://webpack.github.io/docs/using-loaders.html) 26 | 27 | Use when requiring the `handler` for a `Route`, and the component will only be loaded when the route is rendered. 28 | 29 | ```js 30 | 31 | ``` 32 | 33 | Note that in react-router 0.x, `willTransitionTo` and `willTransitionFrom` will be proxied to the dynamically-loaded component. 34 | 35 | 36 | ### Named chunks (0.2.1 and above) 37 | 38 | If you have nested or sibling Routes that you want to be loaded together, you can name the components using `?name=chunkName` 39 | 40 | ```js 41 | 42 | 43 | 44 | 45 | 46 | ``` 47 | 48 | This will cause the `user` chunk to be loaded if any of the three user pages is loaded. 49 | It will also mean that you won't need two separate calls for the base class and child class. 50 | 51 | #### Named chunks with placeholders (0.5.1 and above) 52 | 53 | You can also use the [standard Webpack placeholders](https://github.com/webpack/loader-utils#interpolatename) in the name of your chunks. 54 | 55 | ```js 56 | 57 | 58 | 59 | ``` 60 | 61 | Would generate three chunks, exported in `userdetails.js`, `usersettings.js` and so on. 62 | Using this approach allows you to setup your loader globally through an exclude/include rule in your `webpack.config.js`. 63 | To avoid conflicts it may be best to prefix your `name` with a subfolder name, such as `routes/`: 64 | 65 | ```js 66 | loaders: [ 67 | { 68 | test: /\.js$/, 69 | exclude: /src\/Pages/, 70 | loader: 'babel', 71 | }, 72 | { 73 | test: /\.js$/, 74 | include: /src\/Pages/, 75 | loaders: ['react-router-proxy?name=routes/[name]', 'babel'], 76 | } 77 | ], 78 | ``` 79 | 80 | This has the advantage of making your router a lot leaner: 81 | 82 | ```js 83 | 84 | 85 | 86 | ``` 87 | 88 | The generated files would then go into `routes/userdetails`, `routes/usersettings` etc. 89 | 90 | ## Changelog 91 | 92 | ##### 0.5.1 93 | 94 | - Added named chunks with placeholders 95 | 96 | ##### 0.5.0 97 | 98 | - Upgraded to react-router 2.x 99 | 100 | ##### 0.4.3 101 | 102 | - Using module['default'] for IE8 compatibility 103 | 104 | ##### 0.4.2 105 | 106 | - Added support for ES6 modules 107 | 108 | ##### Before 0.4.2 109 | 110 | - See commit history 111 | 112 | # License 113 | 114 | MIT (http://www.opensource.org/licenses/mit-license.php) 115 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Taken and modified from react-proxy-loader to support react-router 3 | * willTransitionTo hooks. See "BEGIN CHANGE" - "END CHANGE" below. 4 | */ 5 | var loaderUtils = require("loader-utils"); 6 | 7 | module.exports = function() {}; 8 | module.exports.pitch = function(remainingRequest) { 9 | this.cacheable && this.cacheable(); 10 | var query = loaderUtils.parseQuery(this.query); 11 | var chunkName = loaderUtils.interpolateName(this, query.name, { 12 | context: this.options.context, 13 | content: remainingRequest, 14 | }).toLowerCase(); 15 | 16 | var moduleRequest = "!!" + remainingRequest; 17 | return [ 18 | 'var React = require("react");', 19 | 'var component;', 20 | 'var desc = {', 21 | 22 | // BEGIN CHANGE 23 | ' statics: {', 24 | ' willTransitionTo: function(transition, params, query, callback) {', 25 | ' require.ensure([], function() {', 26 | ' var module = require(' + JSON.stringify(moduleRequest) + ');', 27 | ' component = module.__esModule ? module["default"] : module;', 28 | ' if (component.willTransitionTo) { ', 29 | ' component.willTransitionTo(transition, params, query, callback);', 30 | ' if (component.willTransitionTo.length < 4) {', 31 | ' callback(); ', 32 | ' }', 33 | ' } ', 34 | ' else {', 35 | ' callback();', 36 | ' }', 37 | ' }' + (query.name ? ', ' + JSON.stringify(chunkName) : '') + ');', 38 | ' },', 39 | ' willTransitionFrom: function(transition, component, callback) {', 40 | ' var componentClass = component && component.state ? component.state.component : null;', 41 | ' if (componentClass && componentClass.willTransitionFrom) {', 42 | ' componentClass.willTransitionFrom(transition, component.refs["componentProxy"], callback);', 43 | ' if (componentClass.willTransitionFrom.length < 3) {', 44 | ' callback(); ', 45 | ' }', 46 | ' }', 47 | ' else {', 48 | ' callback();', 49 | ' }', 50 | ' }', 51 | ' }, ', 52 | // END CHANGE 53 | 54 | ' loadComponent: function(callback) {', 55 | ' if(!component) {', 56 | ' require.ensure([], function() {', 57 | ' var module = require(' + JSON.stringify(moduleRequest) + ');', 58 | ' component = module.__esModule ? module["default"] : module;', 59 | ' if(callback) callback(component);', 60 | ' }' + (query.name ? ', ' + JSON.stringify(chunkName) : '') + ');', 61 | ' } else if(callback) callback(component);', 62 | ' return component;', 63 | ' }', 64 | '};', 65 | 'var mixinReactProxy = require(' + JSON.stringify(require.resolve("./mixinReactProxy")) + ');', 66 | 'mixinReactProxy(React, desc);', 67 | 'module.exports = React.createClass(desc);', 68 | 'module.exports.Mixin = desc;' 69 | ].join("\n"); 70 | }; 71 | -------------------------------------------------------------------------------- /mixinReactProxy.js: -------------------------------------------------------------------------------- 1 | 2 | // Shorter version of https://github.com/sindresorhus/object-assign/blob/master/index.js 3 | var assign = Object.assign || function (target, source) { 4 | var keys = Object.keys(Object(source)); 5 | for (var i=0; i", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/odysseyscience/react-router-proxy-loader/issues" 23 | }, 24 | "dependencies": { 25 | "loader-utils": "~0.2.6" 26 | }, 27 | "homepage": "https://github.com/odysseyscience/react-router-proxy-loader", 28 | "peerDependencies": { 29 | "react-router": "^2.0.0-rc1" 30 | } 31 | } 32 | --------------------------------------------------------------------------------