Skip to content

Commit

Permalink
Merge pull request #1322 from mxstbr/3.4
Browse files Browse the repository at this point in the history
v3.4.0
  • Loading branch information
mxstbr committed Jan 14, 2017
2 parents a0e3257 + 60a83b5 commit fd77388
Show file tree
Hide file tree
Showing 189 changed files with 4,149 additions and 4,300 deletions.
9 changes: 8 additions & 1 deletion .editorconfig
@@ -1,7 +1,14 @@
# editorconfig.org

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = false
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
1 change: 1 addition & 0 deletions .gitattributes
Expand Up @@ -49,6 +49,7 @@

# server config
.htaccess text
.nginx.conf text

# git config
.gitattributes text
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE.md
Expand Up @@ -26,5 +26,6 @@ https://github.com/mxstbr/react-boilerplate/issues?q=is%3Aissue+is%3Aclosed

# Versions

- React-Boilerplate (see `package.json`):
- Node/NPM:
- Browser:
12 changes: 6 additions & 6 deletions .travis.yml
@@ -1,15 +1,14 @@
language: node_js

node_js:
- 7
- 6
- 5
- 4

script: npm run build

install:
- npm i -g npm@latest
- npm install
script:
- node ./internals/scripts/generate-templates-for-linting
- npm run test
- npm run build

before_install:
- export CHROME_BIN=chromium-browser
Expand All @@ -23,5 +22,6 @@ notifications:
after_success: 'npm run coveralls'

cache:
yarn: true
directories:
- node_modules
58 changes: 56 additions & 2 deletions Changelog.md
@@ -1,6 +1,61 @@
# Changelog

## RBP v3: The "JS Fatigue Antivenin" Edition
## 3.4 January 2017

### Main

- **Switch to Jest for testing**, massive thanks to @dmitriiabramov
- **Update to webpack 2 RC** (includes switching from `System.import` to `import()`), thanks to @Dattaya
- **Add progress bar while loading code splitted routes**, thanks to @KarandikarMihir
- **Add the "Hitchhikers Guide to `react-boilerplate` to the docs**, massive thanks to @KarandikarMihir
- Update all dependencies, as always huge thanks to @gihrig, our master of dependencies
- Enable `import/first` eslint rule and rewrite all imports, huge thanks to @KarandikarMihir
- Add Node v7 support and deprecate v4 support, thanks to @samit4me @MariusRumpf
- Prevent i18n language duplication, thanks to @harijoe
- Add the webpack circular dependency plugin to avoid hard to debug errors, thanks to @haikyuu
- Refactor all selectors and generators with new naming convention, thanks to @Dattaya
- Update generator templates, thanks to @Virsaviya @jeremyadavis
- Add support for the `--host` parameter when running `npm start`, thanks to @ifedotov
- Showcase reselects `createStructuredSelector` in the example, thanks to @Dattaya
- Exclude test files from coverage report, thanks to @samit4me
- Lint the templates for the generators, thanks to @Dattaya
- Huge improvement to DX testing a freshly cleaned project, thanks to @outdooricon

### Other Updates

- **Remove the webpack DedupePlugin** as it leads to errors in production and is now included by default, thanks to @samit4me
- Remove the `npm run pagespeed` command and all related dependencies and files, thanks to @mkhazov
- Trigger a full page reload when HMR fails, thanks @kachkaev
- Don't import all of lodash, thanks to @jwinn
- Improve `.editconfig`, thanks to @avdeev
- Improve the example components, thanks to @tomazy
- Fix `npm run clean` not working as expected, thanks to @adjnor
- Fix the i18n button not updating with new state, thanks to @adjnor
- Fix console error when changing language, thanks to @samit4me
- Fix default polyfill language, thanks to @web2style
- Fix language generation, thanks to @chaintng
- Switch to new webpack query syntax, thanks to @shrynx
- Add an Introductory document to help people get started, thanks to @KarandikarMihir
- Add security configuration recommendations for Nginx (`.nginx.conf`), thanks to @supergicko
- Add and fix lots to stuff in the documentation, thanks to @pavlin-policar, @samit4me @outdooricon @PierrickGT @nndung179 @outdooricon @kelsonic @jimmyheaddon
- A wide variety of small fixes, thanks to @Dattaya @gihrig @outdooricon

### News

Welcome @KarandikarMihir to the team! Karandikar has been all over the repo, providing fixes and features. Happy to have him on board to make `react-boilerplate` even better!

Special thanks as always to @gihrig for diligently testing everything and keeping our dependencies up to date!

Also, huge props to @samit4me and @Dattaya for being everywhere and fixing so many issues and of course to @KarandikarMihir for all his hard work.

If you want to help us make react-boilerplate great, please use the `dev` branch, test all the things and report all the bugs!

### Supporters

This release was made possible by [Fullstack React](https://www.fullstackreact.com/) and [Serverless](http://serverless.com)! _Want to support us too? [Click here!](http://opencollective.com/react-boilerplate)_


## RBP v3.0: The "JS Fatigue Antivenin" Edition

React Boilerplate (RBP) v3.0.0 is out, and it's a _complete_ rewrite! :tada:

Expand Down Expand Up @@ -44,7 +99,6 @@ website!
- **Performance**
- _Code splitting_: splitting/chunking by route means the leanest, meanest
payload (because the fastest code is the code you don't load!)
- _PageSpeed Metrics_ are built right in with `npm run pagespeed`

- **Testing setup**: Thanks to @jbinto's herculean efforts, testing is now a
first-class citizen of this boilerplate. (the example app has _99% test coverage!_)
Expand Down
5 changes: 3 additions & 2 deletions README.md
Expand Up @@ -93,7 +93,7 @@ But wait... there's more!

There’s also a <a href="https://vimeo.com/168648012">fantastic video</a> on how to structure your React.js apps with scalability in mind. It provides rationale for the majority of boilerplate's design decisions.

<sub><i>Keywords: React.js, Redux, Hot Reloading, ESNext, Babel, react-router, Offline First, ServiceWorker, `styled-components`, redux-saga, FontFaceObserver, PageSpeed Insights</i></sub>
<sub><i>Keywords: React.js, Redux, Hot Reloading, ESNext, Babel, react-router, Offline First, ServiceWorker, `styled-components`, redux-saga, FontFaceObserver</i></sub>

## Quick start

Expand All @@ -109,7 +109,8 @@ Now you're ready to rumble!
## Documentation

- [Intro](docs/general): What's included and why
- [**The Hitchhikers Guide to `react-boilerplate`**](docs/general/introduction.md): An introduction for newcomers to this boilerplate.
- [Overview](docs/general): A short overview of the included tools
- [**Commands**](docs/general/commands.md): Getting the most out of this boilerplate
- [Testing](docs/testing): How to work with the built-in test harness
- [Styling](docs/css): How to work with the CSS tooling
Expand Down
10 changes: 9 additions & 1 deletion app/.htaccess
Expand Up @@ -28,7 +28,7 @@
RewriteRule ^(.*) https://%{HTTP_HOST}/$1 [R,L]

# If we get to here, it means we are on https://

# If the file with the specified name in the browser doesn't exist
RewriteCond %{REQUEST_FILENAME} !-f

Expand All @@ -42,3 +42,11 @@
RewriteRule ^(.*) /

</ifModule>

<IfModule mod_headers.c>
# Do not cache sw.js, required for offline-first updates.
<FilesMatch "sw\.js$">
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"
</FilesMatch>
</IfModule>
56 changes: 51 additions & 5 deletions app/.nginx.conf
@@ -1,6 +1,6 @@
##
# Put this file in /etc/nginx/conf.d folder and make sure
# you have line 'include /etc/nginx/conf.d/*.conf;'
# you have a line 'include /etc/nginx/conf.d/*.conf;'
# in your main nginx configuration file
##

Expand All @@ -25,17 +25,54 @@ server {

server {

listen 443;
listen 443 ssl;

# Type your domain name below
server_name example.com;

ssl on;
# Configure the Certificate and Key you got from your CA (e.g. Lets Encrypt)
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/server.key;

# Use only TSL protocols for more secure
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

# Only use TLS v1.2 as Transport Security Protocol
ssl_protocols TLSv1.2;

# Only use ciphersuites that are considered modern and secure by Mozilla
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';

# Do not let attackers downgrade the ciphersuites in Client Hello
# Always use server-side offered ciphersuites
ssl_prefer_server_ciphers on;

# HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
add_header Strict-Transport-Security max-age=15768000;

# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
# Uncomment if you want to use your own Diffie-Hellman parameter, which can be generated with: openssl ecparam -genkey -out dhparam.pem -name prime256v1
# See https://wiki.mozilla.org/Security/Server_Side_TLS#DHE_handshake_and_dhparam
# ssl_dhparam /path/to/dhparam.pem;


## OCSP Configuration START
# If you want to provide OCSP Stapling, you can uncomment the following lines
# See https://www.digitalocean.com/community/tutorials/how-to-configure-ocsp-stapling-on-apache-and-nginx for more infos about OCSP and its use case
# fetch OCSP records from URL in ssl_certificate and cache them

#ssl_stapling on;
#ssl_stapling_verify on;

# verify chain of trust of OCSP response using Root CA and Intermediate certs (you will get this file from your CA)
#ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

## OCSP Configuration END

# To let nginx use its own DNS Resolver
# resolver <IP DNS resolver>;


# Always serve index.html for any request
location / {
Expand All @@ -44,6 +81,15 @@ server {
try_files $uri /index.html;
}

# Do not cache sw.js, required for offline-first updates.
location /sw.js {
add_header Cache-Control "no-cache";
proxy_cache_bypass $http_pragma;
proxy_cache_revalidate on;
expires off;
access_log off;
}

##
# If you want to use Node/Rails/etc. API server
# on the same port (443) config Nginx as a reverse proxy.
Expand Down
45 changes: 26 additions & 19 deletions app/app.js
Expand Up @@ -8,13 +8,6 @@
// Needed for redux-saga es6 generator support
import 'babel-polyfill';

/* eslint-disable import/no-unresolved, import/extensions */
// Load the favicon, the manifest.json file and the .htaccess file
import 'file?name=[name].[ext]!./favicon.ico';
import '!file?name=[name].[ext]!./manifest.json';
import 'file?name=[name].[ext]!./.htaccess';
/* eslint-enable import/no-unresolved, import/extensions */

// Import all the third party stuff
import React from 'react';
import ReactDOM from 'react-dom';
Expand All @@ -23,15 +16,35 @@ import { applyRouterMiddleware, Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import FontFaceObserver from 'fontfaceobserver';
import { useScroll } from 'react-router-scroll';
import configureStore from './store';
import 'sanitize.css/sanitize.css';

// Import root app
import App from 'containers/App';

// Import selector for `syncHistoryWithStore`
import { makeSelectLocationState } from 'containers/App/selectors';

// Import Language Provider
import LanguageProvider from 'containers/LanguageProvider';

// Load the favicon, the manifest.json file and the .htaccess file
/* eslint-disable import/no-webpack-loader-syntax */
import '!file-loader?name=[name].[ext]!./favicon.ico';
import '!file-loader?name=[name].[ext]!./manifest.json';
import 'file-loader?name=[name].[ext]!./.htaccess'; // eslint-disable-line import/extensions
/* eslint-enable import/no-webpack-loader-syntax */

import configureStore from './store';

// Import i18n messages
import { translationMessages } from './i18n';

// Import CSS reset and Global Styles
import 'sanitize.css/sanitize.css';
import './global-styles';

// Import routes
import createRoutes from './routes';

// Observe loading of Open Sans (to remove open sans, remove the <link> tag in
// the index.html file and this observer)
const openSansObserver = new FontFaceObserver('Open Sans', {});
Expand All @@ -43,9 +56,6 @@ openSansObserver.load().then(() => {
document.body.classList.remove('fontLoaded');
});

// Import i18n messages
import { translationMessages } from './i18n';

// Create redux store with history
// this uses the singleton browserHistory provided by react-router
// Optionally, this could be changed to leverage a created history
Expand All @@ -56,14 +66,11 @@ const store = configureStore(initialState, browserHistory);
// Sync history and store, as the react-router-redux reducer
// is under the non-default key ("routing"), selectLocationState
// must be provided for resolving how to retrieve the "route" in the state
import { selectLocationState } from 'containers/App/selectors';
const history = syncHistoryWithStore(browserHistory, store, {
selectLocationState: selectLocationState(),
selectLocationState: makeSelectLocationState(),
});

// Set up the router, wrapping all Routes in the App component
import App from 'containers/App';
import createRoutes from './routes';
const rootRoute = {
component: App,
childRoutes: createRoutes(store),
Expand Down Expand Up @@ -100,11 +107,11 @@ if (module.hot) {
// Chunked polyfill for browsers without Intl support
if (!window.Intl) {
(new Promise((resolve) => {
resolve(System.import('intl'));
resolve(import('intl'));
}))
.then(() => Promise.all([
System.import('intl/locale-data/jsonp/en.js'),
System.import('intl/locale-data/jsonp/de.js'),
import('intl/locale-data/jsonp/en.js'),
import('intl/locale-data/jsonp/de.js'),
]))
.then(() => render(translationMessages))
.catch((err) => {
Expand Down
7 changes: 3 additions & 4 deletions app/components/A/tests/index.test.js
Expand Up @@ -2,11 +2,10 @@
* Testing our link component
*/

import A from '../index';

import expect from 'expect';
import { shallow } from 'enzyme';
import React from 'react';
import { shallow } from 'enzyme';

import A from '../index';

const href = 'http://mxstbr.com/';
const children = (<h1>Test</h1>);
Expand Down
5 changes: 2 additions & 3 deletions app/components/Button/tests/A.test.js
@@ -1,5 +1,4 @@
import React from 'react';
import expect from 'expect';
import { shallow } from 'enzyme';

import A from '../A';
Expand All @@ -12,7 +11,7 @@ describe('<A />', () => {

it('should have a className attribute', () => {
const renderedComponent = shallow(<A />);
expect(renderedComponent.prop('className')).toExist();
expect(renderedComponent.prop('className')).toBeDefined();
});

it('should adopt a valid attribute', () => {
Expand All @@ -23,6 +22,6 @@ describe('<A />', () => {

it('should not adopt an invalid attribute', () => {
const renderedComponent = shallow(<A attribute={'test'} />);
expect(renderedComponent.prop('attribute')).toNotExist();
expect(renderedComponent.prop('attribute')).toBeUndefined();
});
});

0 comments on commit fd77388

Please sign in to comment.