Project link: github.com/MrZhang123/…

The core

  • React: 16.3.2
  • The React – dom: 16.3.2
  • Webpack: 4.6.0
  • The React – the router – dom: 4.2.2
  • Story: 4.0.0
  • The React – hot – loader: 4.1.2

The directory structure

├ ─ ─ the README. Md ├ ─ ─ build │ ├ ─ ─ webpack. Base. Config. Js │ ├ ─ ─ webpack. Dev. Config. Js │ └ ─ ─ webpack. Production. Config. Js ├ ─ ─ Package. The json ├ ─ ─ postcss. Config. Js ├ ─ ─ the SRC │ ├ ─ ─ App. Js │ ├ ─ ─ components │ │ └ ─ ─ Loading │ │ └ ─ ─ index. The js │ ├ ─ ─ Index.html │ ├ ─ ─ main. Js │ ├ ─ ─ redux │ │ ├ ─ ─ the actions │ │ │ └ ─ ─ demo. Js │ │ ├ ─ ─ middleware │ │ │ └ ─ ─ index. The js │ │ ├ ─ ─ Reducers │ │ │ ├ ─ ─ demo. Js │ │ │ └ ─ ─ index. The js │ │ └ ─ ─ store │ │ └ ─ ─ index. The js │ ├ ─ ─ the static │ │ └ ─ ─ CSS │ │ └ ─ ─ Normalize the. CSS │ ├ ─ ─ styles. SCSS │ └ ─ ─ views │ ├ ─ ─ the Content │ │ ├ ─ ─ the About │ │ │ └ ─ ─ index. The js │ │ ├ ─ ─ Home │ │ │ └ ─ ─ Index. Js │ │ ├ ─ ─ switchable viewer │ │ │ └ ─ ─ index. The js │ │ └ ─ ─ the router. The js │ └ ─ ─ RouterLink │ └ ─ ─ index. The js └ ─ ─ yarn. The lockCopy the code

Basic building

First, build a basic React development environment, without redux and React-Router

Install the necessary packages

# dependencies
yarn add react react-dom

# devDependencies
yarn add --dev webpack webpack-cli webpack-dev-server babel-core babel-loader babel-polyfill babel-preset-env babel-preset-react babel-preset-stage-0 cross-env css-loader file-loader jsx-loader style-loader url-loader
Copy the code

instructions

  1. The Command line interface (CLI) of Webpack4 has been moved to Webpack-CLI. To use the CLI, you need to install Webpack-CLI. For details, see the webpack-CLI documentation.
  2. Since Babel only converts new JavaScript syntax by default and not new apis, such as Iterator, Generator, Set, Maps, Proxy, Reflect, Symbol, Promise, and other global objects, And some methods defined on global objects (such as Object.assign), so if you want to use these methods you must use babel-Polyfill to provide a shim for the current environment.

Configuration webpack

In the build new three files folder — webpack. Base. Config. Js, webpack. Dev. Config. Js, webpack. Production. Config. Js, Place the common parts of dev and produciton in the base file.

// webpack.base.config.js
const path = require('path')

module.exports = {
  entry: {
    main: [
      'babel-polyfill',
      path.resolve(__dirname, '.. /src/main.js')]},output: {
    path: path.resolve(__dirname, '.. /dist'),
    publicPath: '/'.filename: '[name].js'.chunkFilename: 'chunk/[name].[chunkhash].js'
  },
  module: {
    rules: [{test: /\.css$/.use: ['style-loader'.'css-loader'] {},test: /\.(js|jsx)$/.exclude: /(node_modules|bower_components)/.loader: 'babel-loader'
      },
      {
        test: /\.(png|jpg|gif|svg)$/.loader: 'url-loader'.options: {
          limit: 10000.name: '[name].[ext]? [hash]'}}},resolve: {
    modules: ['node_modules'].extensions: ['.web.js'.'.js'.'.jsx'.'.json']},mode: ' ' // webpack v4 add
}
Copy the code

Since this is a common configuration file for Webpack, the mode setting is null and will be set in dev and Prodctuon respectively.

The webpack4 mode

Added some default configurations in WebPack V4 to enable default configurations in both development and production environments by setting mode to development and Production (the default).

1. Both configurations exist

// Chunks resolved in parent Chunk will be deleted
optimization.removeAvailableModules:true
// Delete empty chunks
optimization.removeEmptyChunks:true
// Merge duplicate chunks
optimization.mergeDuplicateChunks:true
Copy the code

2. Default configuration for development

/ / debugging
devtool:eval
// Cache modules to avoid rebuilding them without changes.
cache:true
// Cache resolved dependencies to avoid reparsing them.
module.unsafeCache:true
// Add a comment to the bundle for "contained module information"
output.pathinfo:true
// Determine where possible the export of each module to be used for other optimizations or code generation.
optimization.providedExports:true
// Find the modules shared in the chunk and take them out to create separate chunks
optimization.splitChunks:true
Create a separate chunk for the WebPack runtime code
optimization.runtimeChunk:true
// Compile errors are not written to output
optimization.noEmitOnErrors:true
// Give the module meaningful names instead of ids
optimization.namedModules:true
// Give chunk meaningful names instead of IDS
optimization.namedChunks:true
Copy the code

3. Default Settings for production

// Performance related configuration
performance:{hints:"error". }// The sub-chunks of certain chunks are identified and marked in such a way that these sub-chunks do not have to be loaded when loading larger chunks
optimization.flagIncludedChunks:true
// Shorter values for frequently used IDS
optimization.occurrenceOrder:true
// Determine the exports to be used under each module
optimization.usedExports:true
// Identify package.json or rules sideEffects flags
optimization.sideEffects:true
// Try to find segments in the module diagram that can be securely connected to a single module. - -
optimization.concatenateModules:true
// Use uglip-js to compress the code
optimization.minimize:true
Copy the code

Configuration webpack. Dev. Config. Js

const webpack = require('webpack')
const config = require('./webpack.base.config.js')
const WebpackDevServer = require('webpack-dev-server')
const PORT = process.env.PORT || 8000 // The default port is 8000, which can be configured through package.json

config.entry.main = (config.entry.main || []).concat([
  `webpack-dev-server/client? http://localhost:${PORT}/ `.'webpack/hot/dev-server'
])

config.plugins = (config.plugins || []).concat([
  new webpack.HotModuleReplacementPlugin()
])

config.mode = 'development'

const compiler = webpack(config)

const server = new WebpackDevServer(compiler, {
  hot: true.// Start wbePack HMR
  quiet: true.historyApiFallback: true.filename: config.output.filename,
  publicPath: config.output.publicPath,
  stats: {
    colors: true
  }
})

server.listen(PORT, 'localhost', () = > {console.log(`server started at localhost:${PORT}`)})Copy the code

The difference between output.publicPath and devServer.publicPath can be explained in my article: publicPath in Webpack

Configuration webpack. Production. Config. Js

const path = require('path')
const webpack = require('webpack')
const config = require('./webpack.base.config')
const CleanWebpackPlugin = require('clean-webpack-plugin')

config.mode = 'production'

config.plugins = (config.plugins || []).concat([
	new CleanWebpackPlugin(['dist'] and {root: path.resolve(__dirname, '.. / ')}),new webpack.HashedModuleIdsPlugin()
])

module.exports = config
Copy the code

conclusion

Webpack packs JS and CSS together. For example, when using webPack HMR, when you save it, the page will refresh. The React application architecture addresses these issues, including resetting the page state and adding the redux and react-Router.