Here I've placed what I see as essentials. Feel free to add or substract if your see overkill for your sitruation!
sinon
seems like the only potential overkill to me at the time of this writing.
{
"name": "app-name",
"jest": {
"verbose": true,
"moduleFileExtensions": [
"js",
"jsx",
],
"testURL": "https://testing.app.com"
},
"devDependencies": {
"babel-jest": "^21.2.0",
"browserify-incremental": "^3.1.1",
"eslint": "^4.4.1",
"eslint-config-prettier": "^2.3.0",
"eslint-plugin-babel": "^4.1.2",
"eslint-plugin-prettier": "^2.1.2",
"eslint-plugin-react": "^7.2.1",
"jest": "^21.0.1",
"nock": "^9.0.14",
"prettier": "^1.7.2",
"prettier-eslint": "^8.2.0",
"react-test-renderer": "^15.6.1",
"redux-mock-store": "^1.2.3",
"sinon": "^3.2.0"
},
"license": "",
"engines": {
"node": "^6.10"
},
"dependencies": {
"babel-core": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"babelify": "^7.3.0",
"browserify": "^14.4.0",
"isomorphic-fetch": "^2.2.1",
"prop-types": "^15.5.10",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",
},
"browserify": {
"transform": [
[
"babelify"
]
]
},
"scripts": {
"test": "jest",
"test:watch": "yarn jest -- --watch",
"lint": "eslint --ext .js --ext .jsx --max-warnings 0 .",
"lint-fix": "eslint --ext .js --ext .jsx --fix --max-warnings 0 ."
}
}
This is where babel configs live. This targets browsers with over 1% of global usage. This also is browserify compatible, meaning it compile everything down to ES5.
{
"presets": [
[
"env",
{
"targets": {
"browsers": "> 1%"
},
"useBuiltIns": "usage",
"forceAllTransforms": true,
"shippedProposals": true
}
],
"react"
],
"plugins": [
"syntax-dynamic-import",
"transform-object-rest-spread",
"transform-class-properties"
]
}
Similar to a .gitignore, this lists files that should not be babelified. You'll notice that we don't run babel on the root application.js file in assets/javascripts so that the comments are preserved and the traditional asset pipeline works as expected
node_modules
vendor/assets/
app/assets/javascripts/application.js # to save traditional rails asset pipeline!
This is a well-informed, yet opinionated set of eslint style guides that I chose to employ. If you hate trailing commas or like airbnb's guide better that is your perogative.
{
"extends": [
"plugin:react/recommended",
"prettier",
"prettier/react"
],
"parser": "babel-eslint",
"plugins": [
"react",
"prettier"
],
"env": {
"es6": true,
"node": true
},
"rules": {
"prettier/prettier": ["error", {"trailingComma": "es5"}]
}
}
This ignores files from the linting process. As noted, I chose to ignore the traditional assets by default. If you can address your existing codebase you certainly should!
node_modules
vendor/assets/
app/assets/javascripts # depending on your threshold to deal with the problem now or not
...
gem 'browserify-rails', '~> 4.2.0'
...
config.browserify_rails.commandline_options = "--extension=\".js\" --extension=\".jsx\" --extension=\".js.jsx\" -t [babelify]"
...
require('../entry_points/BigPicture');
<div class="row">
<div id="big-picture"></div> # unique elementId for ReactDOM to target
</div>
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import bigPictureStore from "../stores/bigPictureStore";
import BigPicturePageContainer from "../containers/BigPicturePageContainer";
document.addEventListener("DOMContentLoaded", function() {
const rootElement = document.getElementById("big-picture");
if (rootElement !== null) {
ReactDOM.render(
<Provider store={bigPictureStore}>
<BigPicturePageContainer />
</Provider>,
rootElement
);
}
});
import { createStore, applyMiddleware } from "redux";
import thunkMiddleware from "redux-thunk";
import rootReducer from "../reducers/bigPicture";
export default createStore(
rootReducer,
applyMiddleware(thunkMiddleware)
);
Then place reducers, components and containers inside of the /assets folder as you would for any create-react-app like app!
If you can get onto webpacker, that is certainly a better option for apps running Rails 4.2+
If you're realistically on an app that's been around the block and has a good deal of JS inside of the traditional Rails asset pipeline like many of us, however, this is the way to do it to use modern ES syntax and have a grand time