preface
This is the fourth article in the Webpack Study Notes series, the previous path:
- If you meet me for the first time, please give me your advice
- Webpack Study Notes ii: Basic property management
- Webpack Study Notes (3) : Environment configuration
Through the previous three articles, you can basically build a Webpack project development environment from scratch. In this article, we use WebPack instead of the React scaffolding to build the React project.
Webpack5 + React Configuration procedure
The configuration in this article is not based on any previous project, but rather re-establishes a project file. The server used in the development process is webpack-dev-server server. React + WebPack5
Initialize the project
- Create a new project folder and switch the terminal directory under the project folder
- run
npm init
Command to generate a package.json file - Install webpack, webpack-CLI, and webpack-dev-server to set up the WebPack development environment
npm install --save-dev webpack webpack-cli webpack-dev-server
Copy the code
- Install dependency packages that support CSS files
// Install these dependency packages as required. NPM install --save-dev CSs-loader sas-loaderCopy the code
Install react and react-dom
Install the React and React-dom packages using the NPM command
npm install --save react react-dom
Copy the code
Install Babel dependencies
Install babel-loader @babel/ core@babel /preset-env @babel/preset-react
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react
Copy the code
Install plug-ins used in development
Install plug-ins that generate HTML files, plug-ins that open browsers, plug-ins that extract text from bundles into separate files, and plug-ins that package directory files cleanly
npm install --save-dev html-webpack-plugin open-browser-webpack4-plugin mini-css-extract-plugin happypack
Copy the code
Adding a Configuration File
The environment in this article is separate from the development and production environment, so there are three webPack-related configuration files.
- Install webpack – merge
npm intall --save-dev webpack-merge
Copy the code
- Add three files in the root directory and write three configuration files respectively
- webpack.base.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HappyPack = require('happypack')
const os = require('os')
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })
function concatPath(relatedPath) {
return path.join(__dirname, relatedPath)
}
const webpackConfBase = {
mode: "development".entry: concatPath('.. /app/app.jsx'),
output: {
path: concatPath('.. /dist'),
filename: '[name].[fullhash:4].js'.chunkFilename: 'chunks/[name].[fullhash:4].js',},module: {
rules: [{test: /\.js[x]? $/,
use: 'babel-loader'
},
{
test: /\.(sc|sa|c)ss$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'.'sass-loader']]}},plugins: [
new HappyPack({
// Use the id to identify the class file that happypack processes
id: 'happyBabel'.// How to handle the same usage as the loader configuration
loaders: [{
loader: 'babel-loader',}],// Indicates a shared process pool. That is, multiple Instances of HappyPack use child processes in the same shared process pool to handle tasks to prevent excessive resource usage.
threadPool: happyThreadPool,
// Allow HappyPack to output logs
verbose: true,}).new HappyPack({
// Use the id to identify the class file that happypack processes
id: 'happyStyle'.// How to handle the same usage as the loader configuration
loaders: [MiniCssExtractPlugin.loader, 'css-loader? sourceMap=true'.'sass-loader? sourceMap=true'].// Indicates a shared process pool. That is, multiple Instances of HappyPack use child processes in the same shared process pool to handle tasks to prevent excessive resource usage.
threadPool: happyThreadPool,
// Allow HappyPack to output logs
verbose: true,}).// Extract the text (CSS) from the bundle into a separate file
new MiniCssExtractPlugin({
// The configuration item is the same as webPackoptions. output
// All configurations are optional
filename: '[name].[fullhash:4].css'.chunkFilename: '[id].[fullhash:4].css',})],}module.exports = webpackConfBase;
Copy the code
- webpack.dev.js
const path = require('path');
const webpack = require('webpack');
const { merge } = require('webpack-merge');
const webpackConfigBase = require('./webpack.base.config');
// open browser-webpack4-plugin // Open browser-webpack4-plugin // Open browser-webpack4-plugin // Open browser-webpack4-plugin
const OpenBrowserPlugin = require('open-browser-webpack4-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const PORT = 8888;
function concatPath(relatedPath) {
return path.join(__dirname, relatedPath);
}
const webpackConfigDev = {
plugins: [
// Define the environment variable as the development environment
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development'),
IS_DEVELOPMETN: true,}).// Inject the packaged resources into an HTML file
new HtmlWebpackPlugin({
inject: 'body'.title: 'React APP'.filename: 'index.html'.template: concatPath('.. /app/index.html')}),new OpenBrowserPlugin({
url: `http://localhost:${PORT}`,})],devtool: 'source-map'.devServer: {
contentBase: concatPath('.. /app'),
historyApiFallback: false.hot: false.host: '0.0.0.0'.port: PORT,
},
}
module.exports = merge(webpackConfigBase, webpackConfigDev);
Copy the code
- webpack.prod.js
const webpack = require('webpack');
const path = require('path');
const { merge } = require('webpack-merge');
const webpackConfigBase = require('./webpack.base.config');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
// Used to clear the last packed file in the packing directory
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
function concatPath(relatedPath) {
return path.join(__dirname, relatedPath)
}
const webpackConfigProd = {
mode: "production".// Extract common modules shared between chunks
optimization: {
runtimeChunk: {
name: 'manifest'
},
minimizer: [].// [new UglifyJsPlugin({...})]
splitChunks: {chunks: 'async'.minSize: 30000.minChunks: 1.maxAsyncRequests: 5.maxInitialRequests: 3.name: false.cacheGroups: {
vendor: {
name: 'vendor'.chunks: 'initial'.priority: -10.reuseExistingChunk: false.test: /node_modules\/(.*)\.js/
},
styles: {
name: 'styles'.test: /\.(scss|css)$/,
chunks: 'all'.minChunks: 1.reuseExistingChunk: true.enforce: true}}}},plugins: [
// Define the environment variable as the development environment
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
IS_DEVELOPMETN: false,}).// Inject the packaged resources into an HTML file
new HtmlWebpackPlugin({
inject: 'body'.title: 'React APP'.filename: 'index.html'.template: concatPath('.. /app/index.html')}),// Parse the code
new BundleAnalyzerPlugin({ analyzerPort: 3011 }),
new CleanWebpackPlugin({
protectWebpackAssets: true,})],}module.exports = merge(webpackConfigBase, webpackConfigProd)
Copy the code
- create
.babelrc
File to configure Babel
{
"compact": false."presets": [
"@babel/preset-env".// Babel starts the plug-in
"@babel/preset-react" // Compile the React syntax plugin]."plugins": [
"@babel/transform-runtime"]}Copy the code
Add scripts command
"scripts": {
"dev": "webpack-dev-server --config webpack.dev.js"."build": "webpack --config webpack.prod.js"
}
Copy the code
In front of the blackboard, underline
The babel-loader version does not contain the following information: The default installation is Babel 8.x, This version is compatible with @babel/core @babel/preset-env @babel/preset-react and the previous versions of Babel 7.x are able-core and babel-preset-env, etc.