本文档是基于webpack5、node10进行搭建的,确保你的电脑里已经安装了node开发环境
1、初始化react项目
在桌面新建react-demo,同时运行npm init -y,这时可以看到项目的根目录下有package.json这个文件,这个文件类似于maven的pom.xml,用来管理前端项目中的所有依赖及其它基本信息。
2、安装webpack、webpack-cli、webpack-dev-server
npm i webpack webpack-cli webpack-dev-server -D
这三个依赖是项目基于webpack开发、打包的必要依赖。安装完之后,在根目录下新建build目录,这里我是沿用了vue-cli2的目录结构。同时在build目录下新建webpack.base.config.js文件。webpack.base.config.js的内容如下:
const path = require('path');
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.export = (env) => {
return {
entry: {
"app": path.resolve(__dirname, "../src/index.js");
},
output: {
path: path.resolve(__dirname, '../dist')
},
module: {
rules: [{
test: /\.(j|t)s$/,
use: [
{
loader: "babel-loader"
}
]
}, {
test: /\.(sc|c)ss$/,
use: [
"loader": "style-loader",
"loader": "css-loader",
"loader": "postcss-loader",
"loader": "scss-loader"
]
}]
},
plugins: [
new HtmlWebPackPlugin({
template: path.resolve(__dirname, "../index.html"),
filename: path.resolve(__dirname, "../dist/index.html")
})
]
}
}
在根目录下新建index.html,内容如下:
<!DOCTYPE html>
<html>
<head>
<title>index</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
</head>
<body>
<div id="root"></div>
</body>
</html>
在webpack.base.config.js文件中,我们看到入口文件为src目录下的index.js文件,所以在根目录下新建src目录,在src目录下新建index.js文件,文件内容如下:
import App from './App';
import ReactDom from 'react-dom';
import React from 'react';
ReactDom.render(
<App />,
document.getElementById('root'));
在根目录下新建App.js,它是页面。内容如下:
import React from 'react';
class App extends React.Component {
render() {
return (<div>APP 页面</div>)
}
}
写完上述项目基本内容之后,发现好多关键依赖没装,项目此时还跑不起来。
3、安装react、react-dom
npm i react react-dom -S
react-dom官方文档
4、安装html-webpack-plugin、@babel/core、babel-loader、@babel/preset-env、@babel/preset-react、style-loader、css-loader、autoprefixer、node-sass、sass-loader、postcss-normalize、postcss-loader
这些插件我不一一介绍,不知道的可以百度。postcss需要配置,在根目录下新建postcss.config.js,内容如下:
const postcssNormalize = require('postcss-normalize');
module.exports = {
plugins: [
[
"postcss-preset-env",
{
autoprefixer: {
flexbox: "no-2009",
},
stage: 3,
}
],
postcssNormalize(),
require('autoprefixer') ({
overrideBrowserslist: ['last 2 version', '>1%', 'ios 7']
})
],
};
在根目录下新建babel.config.js,内容如下:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
在package.json中添加运行脚本:
"dev": "webpack serve --progress --config ./build/webpack.base.config.js",
"build": "webpack --progress --config ./build/webpack.base.config.js"
接下来可以运行项目了
5、配置文件分离
实际开发中不希望生产环境配置和开发环境配置混在一起,所以要做环境分离。安装插件webpack-merge,同时在build目录下新建webpack.dev.config.js、webpack.prod.config.js,内容分别如下:
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.base.config");
module.exports = (env) => {
return merge(baseConfig, {
mode: "development",
output: {
filename: "js/index.bundle[hash*7].js"
},
devServer: {
host: '0.0.0.0',
port: 8080,
hot: true
},
optimization: {
moduleIds: "deterministic",
},
cache: {
type: 'filesystem',
// 可选配置
buildDependencies: {
config: [__filename], // 当构建依赖的config文件(通过 require 依赖)内容发生变化时,缓存失效
},
name: 'development-cache',
}
})
}
const path = require("path");
const { merge } = require('webpack-merge');
const baseConfig = require('./webpack.base.config.js');
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = env => {
return merge(baseConfig, {
mode: 'production',
output: {
filename: "js/[name].bundle[contenthash][hash*7].js"
},
plugins: [
// 打包之前清空打包目录
new CleanWebpackPlugin(),
// 打包分析
new BundleAnalyzerPlugin(),
// 生成 manifest.json
new WebpackManifestPlugin(),
// 将 css 从 js 中分离
new MiniCssExtractPlugin({
filename: "css/[name].[contenthash][hash*7].css",
}),
],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
new CssMinimizerPlugin(),
],
splitChunks: {
chunks: 'async'
},
},
});
}
修改webpack.base.config.js:
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
entry: path.resolve(__dirname, '../src/index.js'),
output: {
path: path.resolve(__dirname, '../dist')
},
resolve: {
extensions: [".js"],
},
module: {
rules: [
{
test: /\.js?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
test: /\.(c|sc)ss?$/,
exclude: /node_modules/,
use: {
loader: "style-loader",
loader: "css-loader",
loader: "postcss-loader",
loader: "sass-loader"
}
},
{
test: /\.(jpe?g|png|gif|svg|woff|woff2|eot|ttf|otf)$/i,
type: "asset/resource",
},
]
},
plugins: [
new HtmlWebPackPlugin({
template: path.resolve(__dirname, "../index.html"),
filename: path.resolve(__dirname, "../dist/index.html")
})
]
}
写在最后
附上项目的最终结构:
.react-demo
│ .babelrc
│ dir.md
│ index.html
│ package-lock.json
│ package.json
│ postcss.config.js
│
├─build
│ webpack.base.config.js
│ webpack.dev.config.js
│ webpack.prod.config.js
│
└─src
│ App.js
│ index.js
│
└─redux
│ index.js
│
├─actions
│ index.js
│
├─reducers
│ index.js
│
└─sagas
index.js