Webpack4+Babel7+React16+Less Simple configuration notes
I. Project initialization
Create a new project, react-init
mkdir react-init
cd react-init
Copy the code
Initialize the
yarn init -y
# or
npm init -y
Copy the code
Install Webpack
Webpack 4 installation requires two installings, one is Webpack, the other is Webpack-CLI
yarn add webpack webpack-cli -D
# or
npm i webpack webpack-cli -D
Copy the code
3. Create webPack configuration file
Create the config directory under the project root directory and create 3 configuration files in this directory.
Webpack.base.conf.js – Common configuration
Webpack.dev.conf.js — Development environment configuration
Webpack.prod.conf.js — Production environment configuration
Because common configuration items are used, another library needs to be introduced in order to be able to use the common items. Install as follows:
yarn add webpack-merge -D
# or
npm i webpack-merge -D
Copy the code
In webpack.base.conf.js, write:
const path = require('path');
const DIST_PATH = path.resolve(__dirname, '.. /dist');
const APP_PATH = path.resolve(__dirname, '.. /src');
module.exports = {
entry: {
app: APP_PATH+'/index.js'
},
output: {
filename: "js/[name].[chunkhash].js".path: DIST_PATH
},
resolve: {
extensions: [".js".".jsx".".less"].alias: {
"@": APP_PATH
}
},
}
Copy the code
In webpack.dev.conf.js:
const path = require("path");
const merge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");
module.exports = merge(baseWebpackConfig, {
mode: "development".output: {
filename: "js/[name].[hash:16].js"
},
devtool: "inline-source-map"});Copy the code
In webpack.prod.conf.js:
const merge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");
module.exports = merge(baseWebpackConfig, {
mode: "production"});Copy the code
Create the SRC directory under the root directory, then create the index.js file as the entry file for the entire project, and create the app. JSX file as the root component of the React project.
Create the public directory under the root directory, and then create the index.html file as the template file for the entire one-page project.
Index.html reads as follows:
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<! -- <title><%= htmlWebpackPlugin.options.title %></title> -->
<title>React-Init</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Copy the code
In package.json, add the command line script:
"scripts": {
"build": "webpack --config config/webpack.prod.conf.js"
}
Copy the code
Install React
yarn add react react-dom
# or
npm i react react-dom -S
Copy the code
Modify the SRC/app. JSX file as follows:
import React, { Component } from "react";
class App extends Component {
render() {
return (
<h1>Hello React</h1>); }}export default App;
Copy the code
Modify the SRC /index.js file as follows:
import React from "react";
import ReactDom from "react-dom";
import App from "./App";
ReactDom.render(<App />, document.getElementById("root"));
Copy the code
Install Babel
In order for ES6 modularity to be supported and for browser-aware ES5 code to be translated into JSX format parsing, the corresponding Babel and Babel plug-ins must be introduced. The installation is as follows:
yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react -D
# or
npm i babel-loader @babel/core @babel/preset-env @babel/preset-react -D
Copy the code
Configure the Babel:
In webpack. Base. Conf. Js
module.exports = {
...
resolve: {
extensions: [".js".".jsx".".less"].alias: {
"@": APP_PATH
}
},
// Here are the additions
module: {
rules: [{test: /\.jsx? $/.use: 'babel-loader'.include: APP_PATH
},
]
}
}
Copy the code
Create a new. Babelrc file in the root directory with the following contents:
{
"presets": [
"@babel/preset-env"."@babel/preset-react"]}Copy the code
Add an Html template
Install htML-webpack-plugin:
yarn add html-webpack-plugin -D
# or
npm i html-webpack-plugin -D
Copy the code
This will automatically load the generated JS file into the HTML script tag, you can customize the HTML template, see the documentation on the NPM website.
Add the following configuration to webpack.prod.conf.js
. const HtmlWebpackPlugin =require("html-webpack-plugin");
module.exports = merge(baseWebpackConfig, {
mode: "production".plugins: [
new HtmlWebpackPlugin({
template: "public/index.html".minify: {
removeComments: true.collapseWhitespace: true.removeAttributeQuotes: true}})});Copy the code
Now you can build and run
yarn build
# or
npm run build
Copy the code
If no errors are reported and the dist directory is generated under the root directory, the previous configuration is basically correct
Webpack optimization
During production, you can use the clean-webpack-plugin to clean the DIST folder first:
yarn add clean-webpack-plugin -D
Copy the code
Then add the following content to webpack.prod.conf.js:
. const { CleanWebpackPlugin } =require("clean-webpack-plugin"); . plugins: [new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "public/index.html".minify: {
removeComments: true.collapseWhitespace: true.removeAttributeQuotes: true}})].Copy the code
Add hot loading development environment
yarn add webpack-dev-server -D
Copy the code
Add the following to webpack.dev.conf.js:
. const HtmlWebpackPlugin =require("html-webpack-plugin");
const webpack = require("webpack");
module.exports = merge(baseWebpackConfig, {
...
plugins: [
new HtmlWebpackPlugin({
template: "public/index.html".inject: "body".minify: {
html5: true
},
hash: false
}),
new webpack.HotModuleReplacementPlugin()
],
devServer: {
port: 3000.contentBase: path.join(__dirname, ".. /public"),
compress: true.historyApiFallback: true.hot: true.https: false.noInfo: true.open: true.proxy: {}}});Copy the code
Then in the package.json script:
"scripts": {
"build": "webpack --config config/webpack.prod.conf.js",
"dev": "webpack-dev-server --inline --progress --config config/webpack.dev.conf.js"
}
Copy the code
perform
yarn dev
# or
npm run dev
Copy the code
It can be accessed in an open browser at localhost:3000
8. Handle CSS and Less
With Webpack we can import CSS or less files in JS, but must use the corresponding loader to process.
yarn add css-loader mini-css-extract-plugin less less-loader postcss-loader autoprefixer -D
Copy the code
Add it to webpack.base.conf.js
. const MiniCssExtractPlugin =require("mini-css-extract-plugin"); . module.exports = { ... module: {rules: [{test: /\.jsx? $/.use: "babel-loader".include: APP_PATH
},
{
test: /\.css$/.use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader".options: {
modules: true // Enable support for CSS modules}}]}, {test: /\.less$/.exclude: /node_modules/.use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader".options: {
modules: true}}, {loader: "postcss-loader".options: {
plugins: [require("autoprefixer") (the)]}}, {loader: "less-loader".options: {
modifyVars: {
// The custom theme content is written here}}}]},]},plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].[hash].css".ignoreOrder: false}})];Copy the code
For Autoprefixer to work, you need to add the following to package.json:
"browserslist": [
"last 4 version",
"> 1%",
"maintained node versions",
"not dead"
]
Copy the code
Nine, the font and picture processing
Install the loader:
yarn add file-loader url-loader -D
Copy the code
Add this to webpack.base.conf.js:
module.exports = {
...
module: {
rules: [{...test: /\.(png|jpg|gif|jpeg|bmp|webp)$/.use: [{loader: "url-loader".options: {
publicPath: "/".name: "images/[name].[ext]".limit: 512}}]}, {test: /\.(woff|svg|eot|woff2|tff)$/.use: "file-loader".exclude: /node_modules/}}],... };Copy the code
At this point, almost all the required configuration is done, so the entire configuration file should look like this:
-
webpack.base.conf.js
const path = require("path"); const DIST_PATH = path.resolve(__dirname, ".. /dist"); const APP_PATH = path.resolve(__dirname, ".. /src"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: { app: APP_PATH + "/index.js" }, output: { filename: "js/[name].[chunkhash].js".path: DIST_PATH }, module: { rules: [{test: /\.jsx? $/.use: "babel-loader".include: APP_PATH }, { test: /\.css$/.use: [ MiniCssExtractPlugin.loader, { loader: "css-loader".options: { modules: true}}]}, {test: /\.less$/.exclude: /node_modules/.use: [ MiniCssExtractPlugin.loader, { loader: "css-loader".options: { modules: true}}, {loader: "postcss-loader".options: { plugins: [require("autoprefixer") (the)]}}, {loader: "less-loader".options: { modifyVars: { // The custom theme content is written here}}}]}, {test: /\.(png|jpg|gif|jpeg|bmp|webp)$/.use: [{loader: "url-loader".options: { publicPath: "/".name: "images/[name].[ext]".limit: 512}}]}, {test: /\.(woff|svg|eot|woff2|tff)$/.use: "file-loader".exclude: /node_modules/}},resolve: { extensions: [".js".".jsx".".less"].alias: { "@": APP_PATH } }, plugins: [ new MiniCssExtractPlugin({ filename: "css/[name].[hash].css".ignoreOrder: false}})];Copy the code
-
webpack.dev.conf.js
const path = require("path"); const merge = require("webpack-merge"); const baseWebpackConfig = require("./webpack.base.conf"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); module.exports = merge(baseWebpackConfig, { mode: "development".output: { filename: "js/[name].[hash:16].js" }, devtool: "inline-source-map".plugins: [ new HtmlWebpackPlugin({ template: "public/index.html".inject: "body".minify: { html5: true }, hash: false }), new webpack.HotModuleReplacementPlugin() ], devServer: { port: 3000.contentBase: path.join(__dirname, ".. /public"), compress: true.historyApiFallback: true.hot: true.https: false.noInfo: true.open: true.proxy: {}}});Copy the code
-
webpack.prod.conf.js
const merge = require("webpack-merge"); const baseWebpackConfig = require("./webpack.base.conf"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); module.exports = merge(baseWebpackConfig, { mode: "production".plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ template: "public/index.html".minify: { removeComments: true.collapseWhitespace: true.removeAttributeQuotes: true}})});Copy the code
-
.babelrc
{ "presets": ["@babel/preset-env"."@babel/preset-react"]}Copy the code
-
package.json
{ "name": "react-init"."version": "1.0.0"."main": "index.js"."license": "MIT"."scripts": { "build": "webpack --config config/webpack.prod.conf.js"."dev": "webpack-dev-server --inline --progress --config config/webpack.dev.conf.js" }, "devDependencies": { "@babel/core": "^ 7.5.5." "."@babel/plugin-transform-runtime": "^ 7.5.5." "."@babel/preset-env": "^ 7.5.5." "."@babel/preset-react": "^ 7.0.0." "."autoprefixer": "^ 9.6.1." "."babel-loader": "^ 8.0.6"."clean-webpack-plugin": "^ 3.0.0"."css-loader": "^ 3.2.0"."file-loader": "^ 4.2.0"."html-webpack-plugin": "^ 3.2.0"."less": "^ 3.9.0"."less-loader": "^ 5.0.0"."mini-css-extract-plugin": "^ 0.8.0"."postcss-loader": "^ 3.0.0"."url-loader": "^ 2.1.0." "."webpack": "^ 4.39.1"."webpack-cli": "^ 3.3.6." "."webpack-dev-server": "^ 3.7.2." "."webpack-merge": "^ 2" }, "dependencies": { "react": "^ 16.8.6"."react-dom": "^ 16.8.6" }, "browserslist": [ "last 4 version"."1%" >."maintained node versions"."not dead"]}Copy the code
The directory structure of the whole project is as follows:
The react - init ├ ─ ─ the config │ ├ ─ ─ webpack. Base. Conf., js │ ├ ─ ─ webpack. Dev. Conf., js │ └ ─ ─ webpack. Prod. Conf., js ├ ─ ─ public │ └ ─ ─ Index.html ├ ─ ─ the SRC │ ├ ─ ─ App. The JSX │ ├ ─ ─ App. Less │ ├ ─ ─ assets │ │ └ ─ ─ 01. Jpeg │ └ ─ ─ index. The js ├ ─ ─ the babelrc ├ ─ ─ Package. The json └ ─ ─ yarn. The lockCopy the code