-
Notifications
You must be signed in to change notification settings - Fork 0
DIY repository setup
Martin Corevski edited this page Apr 19, 2018
·
13 revisions
- This wiki page is for those that want to create the repository from scratch in order to learn more about React setup.
- Node.js for windows
- Node.js for linux
- Node.js npm cheat-sheet
- UNIX commands
mkdir "directory-name"
cd "directory-name"
npm init
- For Webpack setup please refer to this wiki and the repository
npm i -S react react-dom react-router-dom react-transition-group
- i -S stands for install and save, installs packages locally in the project under dependencies
npm i -D babel-cli babel-preset-react babel-plugin-transform-class-properties babel-plugin-transform-object-rest-spread babel-plugin-syntax-dynamic-import babel-plugin-transform-regenerator
-
i -D stands for install-save-dev, installs packages locally in the project under dev-dependencies
-
Testing with Jest (identity-obj-proxy) and Enzyme
npm i -D jest jest-cli babel-jest identity-obj-proxy enzyme enzyme-adapter-react-16 react-test-renderer
- Linter packages installed, I am using Atom and I had some problems with my linters, specifically linter-js-standard. In order to resolve the issues i installed the standard and babel-eslint packages.
npm i -D babel-eslint standard
npm i -D eslint
- After creating your
.eslintrc
file you will need to install prettier-eslint in order to use Prettier and ESLint fix on your files.
npm i -D prettier-eslint
- There are two main options to choose from when working with CSS and React:
- CSS modules with scoped classes css-modules and a Webpack demo. With this option all the classes are local scoped by default, if we want to make them globally scoped we need to add :global in front of the class name. In order to enable this option please see the webpack.config.js update for css-loader.
- Inline styles but since React's inline styling doesn't support some basic effects like :hover you need to install a library:
- PropTypes is now a separate package, see link
npm i -S prop-types
PS: Local installation is recommended! If you want to install the packages globally you can use i -g
- Then update package.json or create/update .babelrc (THIS IS HIGHLY RECOMMENDED) file in the root directory, for the webpack setup and package.json updates please refer to this wiki
"babel": {
"presets": ["react", "env", "stage-0"]
}
- If you installed the linter packages you need to add standard parser and you can add it just after scripts or wherever you please inside package.json
"scripts" : {
…
},
"standard": {
"parser": "babel-eslint",
"globals": ["shallow", "render", "mount", "describe", "it", "expect"]
}
- Jest config file in root directory
module.exports = {
setupFiles: [
'<rootDir>/config/tests-setup.js'
],
transform: {
'^.+\\.(jsx|js)?$': '<rootDir>/node_modules/babel-jest'
},
moduleNameMapper: {
'^.+\\.(css|scss)$': 'identity-obj-proxy'
}
}
- Jest setup file for Enzyme init, this file is in a separate config folder
import Enzyme, { shallow, render, mount } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
Enzyme.configure({ adapter: new Adapter() })
// Make Enzyme functions available in all test files without importing
global.shallow = shallow
global.render = render
global.mount = mount
- Parser added, space before function, jsx single quotes because of the standard js rules, generator functions spacing.
{
"env": {
"browser": true,
"es6": true
},
"extends": "eslint:recommended",
"parser": "babel-eslint",
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true
},
"sourceType": "module"
},
"plugins": ["react"],
"rules": {
"indent": ["error", 2, { "SwitchCase": 1 }],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "single"],
"semi": ["error", "never"],
"space-before-function-paren": ["error", "always"],
"jsx-quotes": ["error", "prefer-single"],
"generator-star-spacing": ["error", {"before": true, "after": true}]
}
}
- In order to use ES6-7 JS syntax (features) the transform-class-properties plugin needs to be installed and added to the babel configuration. For the ability to use the spread operator for objects (example:
let itSpread = {…someObject}
) the transform-object-rest-spread plugin needs to be installed. - For generator functions (function * funcName ()) to work, transform-regenerator plugin needs to be installed and also babel-polyfill to be added
npm i -S babel-polyfill
. After adding babel polyfill you need to update the entry option in webpack.config.jsentry: ['babel-polyfill', './index.js']
- The import() method is made available by the syntax-dynamic-import plugin. Enables async load of components, bonus package react-loadable. Currently an error might appear
Uncaught (in promise) TypeError: Cannot read property 'call' of undefined
for css files inside async components when using chunks, see issue and issue in create-react-app also, since it's Webpack problem. Workaround until the issue is solved, inside the HOC yourComponent.js add at the beginning:
require('style-loader/lib/addStyles')
require('css-loader/lib/css-base')
- This is how the babel loader part of the webpack.config.js file should look like:
{
test: /\.js$/,
include: /src/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['react', 'env', 'stage-0'],
plugins: ['transform-class-properties', 'transform-object-rest-spread', 'syntax-dynamic-import', 'transform-regenerator']
}
}
- css-loader modules update this is how the CSS loader should look like:
{
test: /\.(css|scss|sass)$/,
use: extractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 2, // postcss and sass
localIdentName: '[name]___[local]___[hash:base64:5]'
}
},
'postcss-loader',
'sass-loader'
],
fallback: 'style-loader'
})
}
- Everything is documented inside the files.
- Additional docs on:
- Babel installation, preset-env and preset-react
- React hash-router and router-quick-start
- The folder structure can be updated and then all the paths in
webpack.config.js
need to be updated accordingly. - Here are some articles on React project folder structure:
- From reactjs-org
- Blog atomic-web-design
- How to structure react-project
- How to organize large-react-project
- But is there a 100% correct way to structure react-app?