├── .gitignore ├── .travis.yml ├── .npmignore ├── CHANGELOG.md ├── .editorconfig ├── package.json ├── mixinReactProxy.js ├── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | /node_modules 3 | *.idea 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.12' 4 | sudo: false 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .editorconfig 2 | .gitignore 3 | .travis.yml 4 | *.iml 5 | .idea 6 | .git 7 | 8 | node_modules/ 9 | CHANGELOG.md 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change log 2 | 3 | ##### 0.5.4 4 | 5 | - Added named chunks with placeholders 6 | - Support default query name 7 | 8 | ##### 0.5.0 9 | 10 | - Upgraded to react-router 2.x -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # Change these settings to your own preference 10 | indent_style = space 11 | indent_size = 2 12 | 13 | # We recommend you to keep these unchanged 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-router-loader", 3 | "version": "0.5.4", 4 | "description": "Dynamically load react-router components on-demand", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/luqin/react-router-loader" 12 | }, 13 | "keywords": [ 14 | "react", 15 | "router", 16 | "react-router", 17 | "proxy", 18 | "loader", 19 | "webpack" 20 | ], 21 | "license": "MIT", 22 | "dependencies": { 23 | "loader-utils": "~0.2.12" 24 | }, 25 | "devDependencies": { 26 | "react": "^0.14.5" 27 | }, 28 | "peerDependencies": { 29 | "react-router": ">1.0.0 || >2.0.0-rc1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /mixinReactProxy.js: -------------------------------------------------------------------------------- 1 | module.exports = function (React, desc) { 2 | desc.displayName = "ReactRouterProxy"; 3 | desc.getInitialState = function () { 4 | return { component: this.loadComponent() }; 5 | }; 6 | desc.componentDidMount = function () { 7 | this.___isMounted = true; 8 | if (!this.state.component) { 9 | this.loadComponent(function (component) { 10 | if (this.___isMounted) { 11 | this.setState({ component: component }); 12 | } 13 | }.bind(this)); 14 | } 15 | }; 16 | desc.componentWillUnmount = function () { 17 | this.___isMounted = false; 18 | }; 19 | desc.render = function () { 20 | var Component = this.state.component; 21 | if (Component) { 22 | return React.createElement(Component, this.props, this.props.children); 23 | } else if (this.renderUnavailable) { 24 | return this.renderUnavailable(); 25 | } 26 | return null; 27 | }; 28 | }; 29 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Taken and modified from react-router-proxy-loader to support react-router 3 | */ 4 | var loaderUtils = require("loader-utils"); 5 | 6 | var defaultQueryName; 7 | 8 | module.exports = function () {}; 9 | module.exports.setDefaultQueryName = function (name) { 10 | defaultQueryName = name; 11 | } 12 | module.exports.pitch = function (remainingRequest) { 13 | this.cacheable && this.cacheable(); 14 | var query = loaderUtils.parseQuery(this.query); 15 | var chunkName; 16 | if (query.name || defaultQueryName) { 17 | chunkName = loaderUtils.interpolateName(this, query.name || defaultQueryName, { 18 | context: query.context || this.options.context, 19 | content: remainingRequest, 20 | }); 21 | } 22 | var chunkNameParam = !!chunkName ? (', ' + JSON.stringify(chunkName)) : ''; 23 | 24 | var moduleRequest = '!!' + remainingRequest; 25 | return [ 26 | 'var React = require("react");', 27 | 'var component;', 28 | 'var desc = {', 29 | ' loadComponent: function(callback) {', 30 | ' if(!component) {', 31 | ' require.ensure([], function() {', 32 | ' var module = require(' + JSON.stringify(moduleRequest) + ');', 33 | ' component = module.__esModule ? module.default : module;', 34 | ' if(callback) callback(component);', 35 | ' }' + chunkNameParam + ');', 36 | ' } else if(callback) callback(component);', 37 | ' return component;', 38 | ' }', 39 | '};', 40 | 'var mixinReactProxy = require(' + JSON.stringify(require.resolve("./mixinReactProxy")) + ');', 41 | 'mixinReactProxy(React, desc);', 42 | 'module.exports = React.createClass(desc);', 43 | 'module.exports.Mixin = desc;' 44 | ].join("\n"); 45 | }; 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-router-loader 2 | 3 | Based on [react-router-proxy-loader](https://github.com/odysseyscience/react-router-proxy-loader) and [react-proxy-loader](https://github.com/webpack/react-proxy-loader), adapted for [react-router](https://github.com/rackt/react-router) route handlers. 4 | 5 | [![NPM version][npm-badge]][npm] [![Build Status][travis-ci-image]][travis-ci-url] 6 | 7 | [![Dependency Status][deps-badge]][deps] 8 | [![devDependency Status][dev-deps-badge]][dev-deps] 9 | [![peerDependency Status][peer-deps-badge]][peer-deps] 10 | 11 | [npm-badge]: https://img.shields.io/npm/v/react-router-loader.svg?style=flat-square 12 | [npm]: https://www.npmjs.com/package/react-router-loader 13 | 14 | [travis-ci-image]: https://travis-ci.org/luqin/react-router-loader.svg 15 | [travis-ci-url]: https://travis-ci.org/luqin/react-router-loader 16 | 17 | [deps-badge]: https://david-dm.org/luqin/react-router-loader.svg 18 | [deps]: https://david-dm.org/luqin/react-router-loader 19 | 20 | [dev-deps-badge]: https://david-dm.org/luqin/react-router-loader/dev-status.svg 21 | [dev-deps]: https://david-dm.org/luqin/react-router-loader#info=devDependencies 22 | 23 | [peer-deps-badge]: https://david-dm.org/luqin/react-router-loader/peer-status.svg 24 | [peer-deps]: https://david-dm.org/luqin/react-router-loader#info=peerDependencies 25 | 26 | ## Installation 27 | 28 | 29 | ```sh 30 | npm install react-router-loader --save-dev 31 | ``` 32 | 33 | ## Dependencies 34 | 35 | Which version to use depends on your version of `react-router` 36 | 37 | | react-router | react-router-loader | 38 | | ---------------- | ------------------------- | 39 | | 1.x | 0.4.x | 40 | | 2.x and above | 0.5.x | 41 | 42 | 43 | ## Usage 44 | 45 | [Documentation: Using loaders](http://webpack.github.io/docs/using-loaders.html) 46 | 47 | Use when requiring the `component` for a `Route`, and the component will only be loaded when the route is rendered. 48 | 49 | ```js 50 | 51 | ``` 52 | 53 | ### Named chunks 54 | 55 | You can give the chunk a name with the `name` query parameter: 56 | 57 | ```js 58 | 59 | ``` 60 | 61 | #### Default global named chunks (0.5.4 and above) 62 | 63 | ```js 64 | import ReactRouterLoader from 'react-router-loader'; 65 | ReactRouterLoader.setDefaultQueryName('[path][name]xyz'); 66 | ``` 67 | 68 | #### Named chunks with placeholders (0.5.4 and above) 69 | 70 | You can also use the [standard Webpack placeholders](https://github.com/webpack/loader-utils#interpolatename) in the name of your chunks. 71 | 72 | ```js 73 | 74 | 75 | 76 | ``` 77 | 78 | Would generate three chunks, exported in `userdetails.js`, `usersettings.js` and so on. 79 | Using this approach allows you to setup your loader globally through an exclude/include rule in your `webpack.config.js`. 80 | To avoid conflicts it may be best to prefix your `name` with a subfolder name, such as `routes/`: 81 | 82 | ```js 83 | loaders: [ 84 | { 85 | test: /\.js$/, 86 | exclude: /src\/Pages/, 87 | loader: 'babel', 88 | }, 89 | { 90 | test: /\.js$/, 91 | include: /src\/Pages/, 92 | loaders: ['react-router?name=routes/[name]', 'babel'], 93 | } 94 | ], 95 | ``` 96 | 97 | This has the advantage of making your router a lot leaner: 98 | 99 | ```js 100 | 101 | 102 | 103 | ``` 104 | 105 | The generated files would then go into `routes/userdetails`, `routes/usersettings` etc. 106 | 107 | ## License 108 | 109 | MIT (http://www.opensource.org/licenses/mit-license.php) 110 | --------------------------------------------------------------------------------