Webpack: module bundler for JS but can be used for HTMl, CSS and images
- can give you more control over the number of HTTP requests your app is making
- can easily consume packages from nom
Can create an npm script for running webpack -> npm run develop (dev mode) or npm run build for production
- production is minified and file size is much smaller - optimizes for execution speed at runtime and output file size
- dev mode optimizes for build speed and debugging

ES Modules (split your program into many small, self-contained programs
- importing modules from npm don’t uses a relative path but all of your own imports do need a relative path

Tree Shaking
* in dev mode, webpack includes whole packages but in production mode all of the unused modules are removed from bundle

Loaders
* let you run preprocessors (eg. babel) on files as they are imported - allows you to bundle resources beyond js
* loaders can be chained to gather into a series of transforms

CSS in JSimport ‘./style.scss’
* needs the style-loader npm package which outputs the string tiny an embedded <style> tag
* Makes it easier to bundle assets together (images, css, HTML)
* dead code elimination: when the JS component is no longer loaded, the CSS file will also not be loaded
* css modules: local CSS with unique classes to avoid css overwriting
* this allows us to decrease HTTP requests by bundling/splitting code cleverly

Images (eg package: file-loader)
* store the source of images as strings inside js - preloads them and the browser doesn’t have to fetch them with separate requests later

import imageExample from ‘./image-example’
img.src = imageExample

this will include an image where the src attribute contains a dataURI of the image itself

We can import the webpack chunk when we click the button (lazy loading)

Plugins
* loaders operate transform on single files, plugins operate across larger chunks of code
* help split code in clever ways and optimize for production
* webpack plugin "mode" lets us use dev and production specific plugins (eg: UglifyJsPlugin)

Production
* need a config file for dev, and prod (webpack.common.js, webpack.dev.js, webpack.prod.js - use common file in both dev and prod file)

Split CSS
* best practise is to split CSS from JS when bundling for production (use ExtractTextWebpackPlugin) and add the css file to your html as a link
* allows for parallel loading of JS and CSS so it will be faster

Development
* webpack-dev-server provides a simple web server with live reloading
* HotModuleReplacement swaps module at runtime without the refresh

HTTP/2
* webpack gives you control over how assets are fetched as well
* HTTP/2 allows multiple files to be delivered in a single request (so concatenation isn’t a silver bullet anymore)
* Could be more performant to cache several small files

webpackChunkNAme in the component will cause our separate bundle to be named loads.bundle.js

import() returns a promise so ti can be used with async functions

Prefetching/Preloading modules
Use inline directives when declaring imports allows webpack to output "Resource Hint" which tells the browser that for prefetch (probably needed for nav sometime in the future) and preload (resource might be deemed in the current nav)

Prefetch: webpack will add the prefetch hint once the parent chunk has been loaded

Preload vs prefetch (browser support could be different!)
* preload chunk loads in parallel to parent and prefetch loads after parent
* preloaded has medium priority and is instantly downloaded, prefetch loads in browser idle time
* preloaded instantly requested by parent, prefetch is used anytime in the future

Bundle Analysis:
* useful to analyze code splits to check where modules end up (use like webpack-chart and webpack-visulizer or webpack-bundle-analyzer)

async: a function will always return a promise (js will automatically wrap the return statement in a promiseawait: only works inside the async function - makes js wait until that promise is resolved, and then evaluates the expression

the waiting doesn’t cost CPU resources because the engine can do other jobs in the meanwhile

Error Handling:
- await Promise.reject(new Error("Whoops!"))
- await waits for the promise to resolve then throws the error
- Can use in a try/catch as per usual
- if not in a regular try/catch, the promise is rejected and we can do something like: f().catch(alert);