You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Presets and Plugins -- a preset is a group of plugins
es2015 preset is all the plugins needed to get from es6 to es5
presets: ["es2015", {"modules": false}] <-- config for es2015 to make it so babel doesn't process modules
we do this for treeshaking
es2015 has a "loose": true config option
Creating a Webpack config.js File
webpack --module-bind="js=babel' js/ClientApp.js (all JS files get loaded through babel)
We could drop this into npm scripts, but let's make a config file because it's easier to maintain
webpack.config.js
// we're using default node include syntax to save effort of parsing es2015
const path = require('path') // node module that helps you resolve paths
module.exports = {
context: __dirname,
entry: './js/ClientApp.js',
devtool: 'source-map', // don't use devtool on production build
output: {
path: path.join(__dirname, '/public')
filename: 'bundle.js'
},
resolve: {
extensions: ['.js', '.json']
},
stats: { // what kind of stuff does webpack report on
colors: true, // because coloes
reasons: true, // why things fail
chunks: true // ...
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader' // if it passes this test, run it through this loader (we installed this npm module)
}
]
}
}
Webpack is a module bundler
Gulp and Grunt are task runners
with our config file, we should be able to just run webpack and it should just work
There's an entire course on configuring webpack
`webpack --watch
npm run build -- --watch
npm watch
package.json:
"scripts": {
"watch": "npm run build -- --watch"
}
JSX
Facebook launched React at a conference. People saw HTML inside of their JS and they didn't want it.
JSX is XML-Like syntax for JS that adds some HTML into your JavaScript
React, without JSX, is JavaScript code to mimic markup
import React from 'react'
var div = React.DOM.div
var h1 = React.DOM.h1
var MyTitle = React.createClass({
render: function() {
const style = {color: this.props.color}
return (
<div>
<h1 style={ style }>
{this.props.title}
</h1>
</div>
)
}
})
export default MyTitle
Having JS and HTML together like this adds a single entry-point for bug hunting
the curly braces mean to spit-out the result of the js expression
JSX vs createElement
createFactory is no longer useful, because of JSX
webcomponents are coming -- if it's your component, it must be uppercase, if it's a literal tag, use lowercase
Components can bemade up of multiple other components
Going too-small w/ components is both harder to reason about and performance-heavy
Configuring CSS Imports
React, React Router, Redux, Redux-thunk
we need to use both the style and css loader as module rules in webpack config, we could also use less or sass here
url: false? watch the webpack config -- don't inline images
Importing CSS in React
import React from 'react'
import { render } from 'react-dom' // I just want the render function -- webpack can eliminate dead code
import '../public/normalize.css'
import '../public/style.css'
const App = React.createClass({
render () {
return (
<div className='app'> // className is the JavaScript API name
<div className='landing'>
<h1>svideo</h1>
<input type="text" placeholder='Search' />
<a>or Browse All</a>
</div>
</div>
)
}
})
render(<App />, document.getElementById('app'))
Linting rules for React
Standard is not configurable, so if you want to extend it, you must wrap it with eslint
.eslintrc.json
{
"extends": ["standard", "standard-react"] // standard-react is pretty much required
}
Now our linter must run via eslint, now. Edit package.json:
"lint": "eslint js/**/*.js js/**/*.jsx webpack.config.js" // lint everything in the js folder that ends in js or jsx, include webpack config, recurse
npm run lint -s will suppress npm output
npm run lint -s -- --fix
Automated Linting
add "enforce": "pre" rule to webpack config
test will be the same as the other js test
loader is eslint-loader
"exclude": /mode_modules
watch is smart enough to only lint things that change
enforce: pre is synonamous with preloaders
Webpack Development
webpack config:
{
devServer: {
publicPath: '/public'
}
}
package.json:
"scripts": {
"dev": "webpack-dev-server"
}
npm run dev has watch built-in
Routing, Props, & State Management
ReactRouter4 is in alpha
React Router 4 is a total re-write, and got so much better that it's worth it.
Multiple pages single pagey
HashRouter
HashRouter doesn't show you anything it just encapsulates behavior (aka Higher Order Components / Behavior oriented Components)
Usually your root component
Site renders inside
* w/o exactly, this will match _all_ urls because they all start with /
Taking array of data, mapping it to a new data structure -- functional programming 101
var numbers = [1,5,8]
// if I want to double, I could use a for-loop
// or I could use 'map' which takes a funcion and applies it to the elements in the array
numbers.map(function(number) {
return number*2
})
// numbers = [2, 10, 16]
could also say:
var double = function(number) {
return number*2
}
numbers.map(double)
createClass({
getInitialState () {
return {
searchTerm: 'an empty string or a random string if you just want to debug'
}
},
...
<h1>{this.state.searchTerm}</h1>
<input value={this.state.searchTerm} .. />
...
This does not enable 2-way data binding -- typing in the search box still won't change state
The event that fires when you let up the key is caught by React, but nothing is bound to it
Events don't escape REact
We have to give the input an onChange listener
...
handleSearchTermChange (event) {
// event is a React synthetic-DOM event, but has the same API as the MDN event
// use setState all the time
this.setState({searchTerm: event.target.value}) // this is the "change" that we want to make to the state.
// The alternative of setState:
// this.state.searchTerm = event.target.value
// this.forceUpdate() -- you shouldn't ever need this.
},
...
<input value+{...} onChange={this.handleSearchTermChange}
The virtualDom just makes React feasible, not necessarily more desireable
"Given these props and this state, my app looks like this..."
Given these sets of props, I have this search component
Question: How would you re-render after a debounced event?