Webpack4+Babel7+React16+Less简单配置笔记
一、项目初始化
新建一个项目react-init
mkdir react-init
cd react-init
复制代码
初始化
yarn init -y
# 或
npm init -y
复制代码
二、安装Webpack
webpack4的安装需要安装两个,一个是webpack,另外就是webpack-cli
yarn add webpack webpack-cli -D
# 或
npm i webpack webpack-cli -D
复制代码
三、建立webpack配置文件
在项目根目录下面创建config目录,并在该目录里面建3个配置文件,分别是:
webpack.base.conf.js —— 共有配置
webpack.dev.conf.js —— 开发环境配置
webpack.prod.conf.js —— 生产环境配置
因为使用了公共的配置项,所以为了能够使用公共项,需要引入另外一个库,安装如下:
yarn add webpack-merge -D
# 或
npm i webpack-merge -D
复制代码
在webpack.base.conf.js里面写入:
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
}
},
}
复制代码
在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",
});
复制代码
在webpack.prod.conf.js里面写入:
const merge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");
module.exports = merge(baseWebpackConfig, {
mode: "production",
});
复制代码
在根目录下面创建src目录,然后创建index.js文件,作为整个项目的入口文件,创建App.jsx文件,作为react项目的根组件;
在根目录下面创建public目录,然后创建index.html文件,作为整个单页项目的模板文件;
index.html内容如下:
<!DOCTYPE html>
<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>
复制代码
在package.json里面,添加命令行脚本:
"scripts": {
"build": "webpack --config config/webpack.prod.conf.js"
}
复制代码
四、安装React
yarn add react react-dom
# 或
npm i react react-dom -S
复制代码
修改src/App.jsx文件如下:
import React, { Component } from "react";
class App extends Component {
render() {
return (
<h1>Hello React</h1>
);
}
}
export default App;
复制代码
修改src/index.js文件如下:
import React from "react";
import ReactDom from "react-dom";
import App from "./App";
ReactDom.render(<App />, document.getElementById("root")); 复制代码
五、安***abel
为了使ES6的模块化被支持以及能够转为浏览器识别的ES5代码,和JSX格式解析,必须引入对应的babel和babel插件,安装如下:
yarn add babel-loader @babel/core @babel/preset-env @babel/preset-react -D
# 或
npm i babel-loader @babel/core @babel/preset-env @babel/preset-react -D
复制代码
配置babel:
在webpack.base.conf.js里面
module.exports = {
...
resolve: {
extensions: [".js", ".jsx", ".less"],
alias: {
"@": APP_PATH
}
},
// 以下是添加的内容
module: {
rules: [
{
test: /\.jsx?$/,
use: 'babel-loader',
include: APP_PATH
},
]
}
}
复制代码
然后在根目录新建.babelrc文件,内容如下:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
复制代码
六、添加Html模板
安装html-webpack-plugin插件:
yarn add html-webpack-plugin -D
# 或
npm i html-webpack-plugin -D
复制代码
这个可以将生成的JS文件自动加载到html的script标签内去,可以自定义html模板,具体看其在npm网站上的文档。
给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
}
})
]
});
复制代码
此时,可以进行build了,运行
yarn build
# 或
npm run build
复制代码
如果没有报错,且根目录下生成dist目录,则表示之前的配置基本上正确了
webpack优化
生产过程中,可以使用clean-webpack-plugin对dist文件夹先进行清理:
yarn add clean-webpack-plugin -D
复制代码
然后在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
}
})
]
...
复制代码
七、添加热加载开发环境
yarn add webpack-dev-server -D
复制代码
在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: {}
}
});
复制代码
然后在package.json的脚本里面:
"scripts": {
"build": "webpack --config config/webpack.prod.conf.js",
"dev": "webpack-dev-server --inline --progress --config config/webpack.dev.conf.js"
}
复制代码
执行
yarn dev
# 或
npm run dev
复制代码
即可在打开的浏览器里面进行访问,地址为localhost:3000
八、对CSS和Less处理
使用webpack我们可以在js里面导入css或less文件,但是必须使用相应的loader才能进行处理。
yarn add css-loader mini-css-extract-plugin less less-loader postcss-loader autoprefixer -D
复制代码
在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 // 使支持css modules
}
}
]
},
{
test: /\.less$/,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: true
}
},
{
loader: "postcss-loader",
options: {
plugins: [require("autoprefixer")()]
}
},
{
loader: "less-loader",
options: {
modifyVars: {
// 自定义的主题内容写在这里
}
}
}
]
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].[hash].css",
ignoreOrder: false
})
]
};
复制代码
为了使autoprefixer生效,需要在package.json里面添加如下内容:
"browserslist": [
"last 4 version",
"> 1%",
"maintained node versions",
"not dead"
]
复制代码
九、对字体和图片进行处理
安装loader:
yarn add file-loader url-loader -D
复制代码
在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/
}
]
},
...
};
复制代码
到这里,基本上所需要的配置都已经OK了,那么全部的配置文件内容如下所示:
-
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")()] } }, { loader: "less-loader", options: { modifyVars: { // 自定义的主题内容写在这里 } } } ] }, { 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 }) ] }; 复制代码
-
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: {} } }); 复制代码
-
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 } }) ] }); 复制代码
-
.babelrc
{ "presets": ["@babel/preset-env", "@babel/preset-react"] } 复制代码
-
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": "^4.2.1" }, "dependencies": { "react": "^16.8.6", "react-dom": "^16.8.6" }, "browserslist": [ "last 4 version", "> 1%", "maintained node versions", "not dead" ] } 复制代码
整个项目的目录结构为:
react-init
├── config
│ ├── webpack.base.conf.js
│ ├── webpack.dev.conf.js
│ └── webpack.prod.conf.js
├── public
│ └── index.html
├── src
│ ├── App.jsx
│ ├── app.less
│ ├── assets
│ │ └── 01.jpeg
│ └── index.js
├── .babelrc
├── package.json
└── yarn.lock
复制代码