Skip to content

Commit

Permalink
Cleanup and Docs
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonardoGentile committed Jun 19, 2017
1 parent 1477c30 commit dc7737a
Show file tree
Hide file tree
Showing 22 changed files with 199 additions and 217 deletions.
3 changes: 0 additions & 3 deletions .jshintrc

This file was deleted.

110 changes: 40 additions & 70 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,13 @@
# react-webpack-babel-simple-starter
Simple React Webpack Babel Starter Kit
# react-mobx-router5-example

This is a simple setup example for the [react-mobx-router5](https://github.com/LeonardoGentile/react-mobx-router5) project.

Tired of complicated starters with 200MB of dependencies which are hard to understand and modify?
### Install and Run

Try this is a simple [React](https://facebook.github.io/react/), [Webpack](http://webpack.github.io/) and [Babel](https://babeljs.io/) application with nothing else in it.

This is a fork of [react-webpack-babel-simple-starter](https://github.com/alicoding/react-webpack-babel)

### What's in it?

* Simple src/app.jsx and src/app.scss (local module css).
* Webpack configuration for development (with hot reloading) and production (with minification).
* CSS module loading, so you can include your css by ```import styles from './path/to.css';```.
* Both js(x) and css hot loaded during development.

### To run

* You'll need to have [git](https://git-scm.com/) and [node](https://nodejs.org/en/) installed in your system.
* Fork and clone the project:
* Fork, clone, or download the project:

```
git clone https://github.com/alicoding/react-webpack-babel.git
git clone https://github.com/LeonardoGentile/react-mobx-router5-example.git
```

* Then install the dependencies:
Expand All @@ -37,63 +24,46 @@ npm start

Open the web browser to `http://localhost:8888/`

### To build the production package

```
npm run build
```

### Nginx Config
### Routes and Nodes

The project uses this routes configuration:

```javascript
export default [
{ name: 'home', path: '/', component: Home},
{ name: 'login', path: '/login', component: Login},
{ name: 'index', path: '/index/:id', component: Index},
{ name: 'section', path: '/section', component: Sections, children: [
// Sections
{ name: 'home', path: '/home', component: Home },
{ name: 'login', path: '/login', component: Login },
{ name: 'index', path: '/index/:id', component: Index },
{ name: 'subsection', path: '/subsection', component: SubSections, children: [
// Subsections
{ name: 'home', path: '/home', component: Home },
{ name: 'login', path: '/login', component: Login },
{ name: 'index', path: '/index/:id', component: Index }
]}
]}
];

Here is an example Nginx config:
```
server {
# ... root and other options
gzip on;
gzip_http_version 1.1;
gzip_types text/plain text/css text/xml application/javascript image/svg+xml;
location / {
try_files $uri $uri/ /index.html;
}
location ~ \.html?$ {
expires 1d;
}
location ~ \.(svg|ttf|js|css|svgz|eot|otf|woff|jpg|jpeg|gif|png|ico)$ {
access_log off;
log_not_found off;
expires max;
}
}
```

### Eslint
There is a .eslint.yaml config for eslint ready with React plugin.
To use it, you need to install additional dependencies though:
That means that the nodes of this app are:

```
npm install --save-dev eslint eslint-plugin-react
```
- `''` the root node, see the `Main` component
- `'section'`, see the `Sections` component
- `'section.subsection'`, see the `Subsections` component

All this components should be wrapped with `routeNode` HOC.
Notice that `routeNode` HOC injects an `activeRoute` (non-observable) and (mobx-router5) `routerStore` props to the wrapped component.

To do the actual linting, run:
Each one of these uses in turn the `RouteView` component, resposnsible to select and render the various
subcomponent.
Notice that a `RouteView` component injects a `route` prop (in this case the non-observable `activeRoute` that was injected into the routeNode components) to the newly created component.

```
npm run lint
```
The better way to learn about [react-mobx-router5](https://github.com/LeonardoGentile/react-mobx-router5) is to view the source code and play around with this example.

### Notes on importing css styles
* styles having /src/ in their absolute path are considered part of the application and exported as local css modules.
* other styles are considered global styles used by many components and are included in the css bundle directly.
If you have any trouble or doubt please open an issue either here or on [react-mobx-router5](https://github.com/LeonardoGentile/react-mobx-router5) repo.

### Contribute
Please contribute to the project if you know how to make it better, including this README :)

### Personal Setup
On the personal Setup branch I've added some tools and extra funcitonalities to better suit my needs.
- [babel-plugin-react-html-attrs](https://github.com/insin/babel-plugin-react-html-attrs) Transforms JSX `class` attributes into `className` and `for` attributes into `htmlFor`, allowing you to copy and paste HTML into your React components without having to manually edit these particular attributes each time.
- Personal `.editorconfig` setup
- Re-added `bootstrap` (it was stripped in the original project)
- [react-router](https://github.com/ReactTraining/react-router) basic setup
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
"webpack": "2.3.2",
"webpack-cleanup-plugin": "^0.4.2",
"webpack-dashboard": "^0.3.0",
"webpack-dev-server": "2.4.2"
"webpack-dev-server": "2.4.2",
"prop-types": "latest"
},
"scripts": {
"build": "webpack --config webpack.production.config.js --progress --profile --colors",
Expand Down
4 changes: 2 additions & 2 deletions postcss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ const AUTOPREFIXER_BROWSERS = [
module.exports = {
plugins: [
require('autoprefixer')({ browsers: AUTOPREFIXER_BROWSERS }),
require('lost')
// require('lost')
]
}
};


8 changes: 4 additions & 4 deletions src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ import './styles/base/_commons.sass';

const router = createRouter(true);

// Provider will add your router instance in context.
const wrappedApp = (
// Provider will add your pass the stores instances using context
const App = (
<Provider { ...stores } >
<Layout/>
<Layout/>
</Provider>
);

// Render the entire app when the router starts
router.start((err, state) => {
ReactDOM.render(
wrappedApp,
App,
document.getElementById('app')
);
});
Expand Down
8 changes: 7 additions & 1 deletion src/components/Index/Index.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import {observer, inject} from 'mobx-react';
import styles from './Index.sass';

Expand All @@ -16,7 +17,7 @@ class Index extends React.Component {
tabStore.setActiveTab(id);
}

// Triggered when a component will be scheduled to re-render because data it observes has changed.
// Triggered when a component will be scheduled to re-render because data it observes has changed (because @observer)
// This makes it easy to trace renders back to the action that caused the rendering.
componentWillReact() {
console.debug("I will re-render, since the todo has changed!");
Expand Down Expand Up @@ -55,4 +56,9 @@ class Index extends React.Component {
}
}

Index.PropTypes = {
tabStore: PropTypes.object, // injected
route: PropTypes.object // injected by RouteView (non-observable)
};

export default Index;
22 changes: 21 additions & 1 deletion src/components/Layout/Footer/Footer.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import {withRoute, Link} from "react-mobx-router5";
import styles from './Footer.sass';

Expand All @@ -13,9 +14,22 @@ function AnotherElement(props) {
);
}


AnotherElement.propTypes = {
// These are injected by withRoute
routerStore: PropTypes.object,
route: PropTypes.object,
isActive: PropTypes.bool,
className: PropTypes.string,
// This is passed to the wrapper for computing isActive and className
routeName: PropTypes.string,
};

const AnotherComponentWithRoute = withRoute(AnotherElement);




class Footer extends React.Component {
constructor(props) {
super(props);
Expand All @@ -41,7 +55,13 @@ class Footer extends React.Component {
}
}


Footer.propTypes = {
// These are injected by withRoute
routerStore: PropTypes.object,
route: PropTypes.object,
isActive: PropTypes.bool,
className: PropTypes.string
};


export default withRoute(Footer);
48 changes: 27 additions & 21 deletions src/components/Layout/Header/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,46 @@
import React from 'react';
import PropTypes from 'prop-types';
import {inject} from 'mobx-react';
import {Link} from "react-mobx-router5";

import NavMenu from './NavMenu/NavMenu';
import * as styles from './Header.sass';
import {Link} from "react-mobx-router5";


@inject('routerStore')
class Header extends React.Component {

render() {
const routerStore = this.props.routerStore;
return (
<div className={styles.headerContainer}>
<header className={styles.header}>
<Link
routeName={'home'}
routerStore={routerStore}
className={styles.homeLink}> Home </Link>
<div className={styles.navContainer}>
<NavMenu />
</div>
<div className={styles.explanationHome}>
<p>^ This is a Link Component => It will apply automatically an active class on the `a` element</p>
</div>
<div className={styles.explanationNav}>
<p> These are NavLink Components => The `active` class will be applied to the 'li' wrappers ^</p>
</div>
<br/>

</header>
</div>
<header className={styles.header}>

<Link
routeName={'home'}
routerStore={routerStore}
className={styles.homeLink}> Home </Link>

<div className={styles.navContainer}>
<NavMenu />
</div>

<div className={styles.explanationHome}>
<p>^ This is a Link Component => It will apply automatically an active class on the `a` element</p>
</div>

<div className={styles.explanationNav}>
<p> These are NavLink Components => The `active` class will be applied to the 'li' wrappers ^</p>
</div>

<br/>

</header>
);
}
}

Header.propTypes = {
routerStore: PropTypes.object // injected
};

// will passe the router trough context
export default Header;
Expand Down
37 changes: 13 additions & 24 deletions src/components/Layout/Header/Header.sass
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
.header
+container
+clearfix
position: relative
height: 100%

$headerHeight: 126px
.home-link
+simple-nav-link
text-decoration: none

.headerContainer
position: relative // so we can use absolute inside it
z-index: $zindex_headerContainer
height: $headerHeight
// ****
background: $red
border-bottom: 2px solid $red-dark
border-top: 2px solid $red-dark
.nav-container
position: absolute
top: 0
right: 0
z-index: $zindex_navAccount

.explanation-home
position: absolute
Expand All @@ -20,18 +24,3 @@ $headerHeight: 126px
top: 90px
right: 10px

.header
+container
+clearfix
position: relative
height: 100%

.navContainer
position: absolute
top: 0
right: 0
z-index: $zindex_navAccount

.home-link
+simple-nav-link
text-decoration: none
Loading

0 comments on commit dc7737a

Please sign in to comment.