从零开始搭建antd4.x + react16 + redux4 + webpack4 + react-router5基础框架解析
这个框架,使用了几个月,也丰富了很多内容。回头看,重点是:
- 搭建框架顺序,先干什么后干什么,这个弄反了,各种报错都来了
- 依赖的平衡,不可能所有都用最新的依赖,因为依赖之间版本有关联,需要不断调整从中间找平衡。
- webpack配置,根据文档,按需配置
- 业务层面,layout,service拦截器,路由,store,换肤,组件复用等
一、webpack配置重点
Entry
入口起点(entry point)指示webpack应该使用哪个模块,来作为构建其内部依赖图的开始。
进入入口起点后,webpack会找出有哪些模块和库是入口起点(直接和间接)依赖的。
每个依赖项随即被处理,最后输出到称之为 bundles 的文件中。
Output
output属性告诉webpack在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。
基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。
Module
模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
Chunk
代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
Loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript),模块转换器,用于把模块原内容按照需求转换成新内容。
loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
Plugin
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。
插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
webpack启动流程
Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程 :
- 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数。
- 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译。
- 确定入口:根据配置中的 entry 找出所有的入口文件。
- 编译模块:从入口文件出发,调用所有配置的 Loader 。
- 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理。
- 完成模块编译:在经过第 4 步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系。
- 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会。
- 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。

二、配置webpack
1、安装create-react-app
装npm,用npm init可以初始化生成package.json
我这里用的creact-react-app生成基本模块
create-react-app 中文文档:https://www.html.cn/create-react-app/docs/getting-started/
2、配置webpack.config.js
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const dev = require('./webpack.dev');
const prod = require('./webpack.prod');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const isDev = process.env.NODE_ENV === 'development';
const base = {
entry: path.resolve(__dirname, '../src/index.js'), // 入口
module: {
rules: [{ // 对.js、.jsx的处理
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
}, { // 对.css的处理
test: /\.css$/,
use: [
!isDev && MiniCssExtractPlugin.loader, // 生产环境下样式抽离
isDev && 'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1 // 引入的文件调用后面的loader处理
}
},
{ // 智能添加样式前缀
loader: "postcss-loader",
options:{
plugins:[require('autoprefixer')]
}
},
].filter(Boolean)
}, {
test: /\.scss$/, // css预处理器scss的处理
use: [
!isDev && MiniCssExtractPlugin.loader, // 生产环境下抽离样式
isDev && 'style-loader',
"css-loader",
"sass-loader"
].filter(Boolean)
}, {
test: /\.less$/, // css预处理器less的处理
use: "less-loader",
}, {
test: /\.stylus$/, // css预处理器stylus的处理
use: "stylus-loader",
}, {
test: /\.(jpe?g|png|svg|gif)$/, // 对图片的处理
loader: "file-loader",
options: {
name: "image/[contentHash].[ext]"
},
}, {
test: /\.(woff|ttf|eot|otf|ico)$/, // 对字体图标的处理
loader: "file-loader",
options: {
name: "image/[name].[ext]"
},
}]
},
output: { // 出口
filename: 'scripts/[name].bundle.js',
path: path.resolve(__dirname, '../dist')
},
resolve: { // 引入js、jsx文件时,无需添加后缀
extensions: ['.js', '.jsx'],
},
plugins: [
!isDev && new MiniCssExtractPlugin({ // css样式抽离
filename: 'css/[name].[contentHash].css'
}),
new HtmlWebpackPlugin({ // 配置入口html
filename: 'index.html',
template: path.resolve(__dirname, '../public/index.html'),
hash: true,
inject: true,
favicon: path.resolve(__dirname, '../public/favicon.ico'),
minify: !isDev && {
removeAttributeQuotes: true, // 去掉属性双引号
collapseWhitespace: true, // 将html文件折叠成一行
}
}),
new webpack.HotModuleReplacementPlugin(),
].filter(Boolean),
devServer: { // 配置服务
hot:true, // 热更新
port: 3000, // 端口号
compress: true, // 提升页面返回速度
open: true, // 启动服务后自动启动浏览器
contentBase: path.resolve(__dirname, '../dist'), // webpack启动服务会在dist目录下
}
}
module.exports = () => { // 根据环境合并webpack
if (isDev) {
return merge(base, dev);
} else {
return merge(base, prod);
}
}
3.proxy代理
我使用了webpack-dev-server来启动服务,script/start.js,以下是介绍:
webpack-dev-server是webpack官方提供的一个小型Express服务器。使用它可以为webpack打包生成的资源文件提供web服务。
webpack-dev-server 主要提供两个功能:
1.为静态文件提供web服务
2.自动刷新和热替换(HMR)
自动刷新指当修改代码时webpack会进行自动编译,更新网页内容
热替换指运行时更新各种模块,即局部刷新
具体配置方法,见官方文档:https://www.webpackjs.com/configuration/dev-server/#devserver
4.路由配置
app.js里面进行配置和测试,这里要注意,用的是react-router-dom,而不是react-router
开始我用的react-router,调试了很久,才弄好。另外还需要注意hashrouter和browserrouter的区别
react-router-dom官方文档:https://reactrouter.com/web/guides/quick-start
5.layout和redux同步进行
国际化用antd的:https://ant.design/docs/react/i18n-cn
redux主要是configureStore的配置,以下代码里面分别说明
//app.js
import React, { Component } from 'react';
import { Switch, Route, HashRouter as Router,Redirect} from 'react-router-dom';
import { Provider } from 'react-redux'
import {PersistGate} from 'redux-persist/lib/integration/react';
import { ConfigProvider } from 'antd';
import zhCN from 'antd/lib/locale-provider/zh_CN';//直接用antd的国际化就可以了,后来同组的人改成之前的了
import Error from '@/components/Exception/error'; //错误页面,用react自带getDerivedStateFromError判断,如果错误就调404页面
import { addLocaleData, IntlProvider } from 'react-intl';
//import { fetchToken } from '@/service/xhr/fetch'
import configureStore from "./stores/configureStore"; //redux 配置
import postcssFlexbugsFixes from 'postcss-flexbugs-fixes'; import BasicLayout from '@/layouts/BasicLayout'
import Login from '@/pages/login';//login测试使用,正式开发可去除 const {store, persistor } = configureStore(); class App extends Component {
constructor(props){
super(props)
this.state = {
isError: false
};
// 只在开发环境获取 token
// if(process.env.NODE_ENV === "development"){
// fetchToken()
// }
} static getDerivedStateFromError(error) {
return {
isError: true
}
} render() {
// const routers = getLayoutData();
if(this.state.isError){
return <Error />
}
return (
<Provider store={store} >
<PersistGate loading={null} persistor={persistor}>
<Router>
<ConfigProvider locale={zhCN}>
<IntlProvider locale={zhCN} messages={zhCN}>
<Switch>
<Route path='/portal/login' component={Login} />
<Route path='/portal' component={BasicLayout} />
<Redirect to='/portal/login' />
</Switch>
</IntlProvider> </ConfigProvider>
</Router> </PersistGate>
</Provider>
);
}
} export default App;
//layout.js本来想放上来的,发现由于UI设计,写了很多样式判断
//关键点就是router循环渲染出menu,没有什么特别高深的
//redux配置
import { createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk' //中间件
import createLogger from 'redux-logger' //开发环境,打印出dispatch action方便调试
import rootReducer from '@/models/rootReducer'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2'
export default function configureStore() {
const persistConfig = {
key: 'root',
storage,
stateReconciler: autoMergeLevel2,
// whitelist: ['fetchDatacenter','getConfig','fetchVirtualDatacenterList',]
whitelist: []
};
const persistedReducer = persistReducer(persistConfig, rootReducer)
let middleware = [thunk];
if(process.env.NODE_ENV !== 'production'){
middleware.push(createLogger)
}
const store = createStore(
persistedReducer,
undefined,
applyMiddleware(...middleware),
);
let persistor = persistStore(store)
return {
store,
persistor
}
}
6.公共方法
- table公共组件,白同学写的,直接调用可以生成table
- 换肤,将theme写在redux里面,根据获取的theme渲染不同的样式
- login,权限,角色等常规业务
以上就是全部内容了,框架在我们公司git上,也可以按照我之前的文件脚手架下载,看代码了解。
【完】
参考
webpack配置:https://www.runoob.com/w3cnote/webpack-tutorial.html
antd4.x与3.x的不同 https://ant.design/docs/react/migration-v4-cn
redux的store配置官方文档:http://cn.redux.js.org/docs/recipes/ConfiguringYourStore.html
redux-logger:https://github.com/LogRocket/redux-logger
webpack优化:https://juejin.cn/post/6844904093463347208
从零开始搭建antd4.x + react16 + redux4 + webpack4 + react-router5基础框架解析的更多相关文章
- 从零开始搭建口袋妖怪管理系统(4)-借助webpack4.6工程化项目(上)
"手动是不可能手动的了,这辈子都不可能手动的了." 一.目标 上一章我们借助ngRoute,完成了口袋妖怪SPA系统的多模块导航开发,但是现在引用的东西越来越多,项目文件目录开始变 ...
- 亲手搭建一个基于Asp.Net WebApi的项目基础框架1
目标:教大家搭建一个简易的前后端分离的项目框架. 目录: 1:关于项目架构的概念 2:前后端分离的开发模式 3:搭建框架的各个部分 这段时间比较闲,所以想把之前项目里用到的一些技术写到博客里来,分享给 ...
- 亲手搭建一个基于Asp.Net WebApi的项目基础框架4
实现目的:配置website端与服务端对接 1:配置好各项配置文件 2:server端编写接口客户端调用 1.1首先配置文件有log4的配置文件,有config的配置文件,还有服务列表的配置文件 首先 ...
- 亲手搭建一个基于Asp.Net WebApi的项目基础框架3
1:使用Framework工具类封装http请求 接上第二篇的步骤,现在在站点中使用封装好的组件,将framework编译好之后把dll提取出来,然后放到lib当中 在website中引用dll 接下 ...
- 亲手搭建一个基于Asp.Net WebApi的项目基础框架2
本篇目的:封装一些抽象类 1::封装日志相关类 2:封装一个Service操作类 3:封装缓存操作类 4:封装其他一些常用Helper 1.1在Framework项目里面建立好相关操作类文件夹,以便于 ...
- Linux编程之从零开始搭建RPC分布式系统
我一毕业进公司就接触到了RPC,主要是使用前辈们搭建好的RPC框架以及封装好的RPC函数进行业务开发,虽说使用RPC框架开发已经近半年了,但一直想知道如何从零开始搭建起这么一个好用的分布式通信系统框架 ...
- 【webpack系列】从零搭建 webpack4+react 脚手架(二)
html文件如何也同步到dist目录?bundle.js文件修改了,万一被浏览器缓存了怎么办?如何为导出的文件加md5?如何把js引用自动添加到html?非业务代码和业务代码如何分开打包?如何搭建开发 ...
- 【webpack系列】从零搭建 webpack4+react 脚手架(一)
搭建一个React工程的方式有很多,官方也有自己的脚手架,如果你和我一样,喜欢刨根究底,从零开始自己一行一行代码创建一个React脚手架项目,那你就来对地方了.本教程是针对React新手,以及对web ...
- 从零开始搭建一个react项目
Nav logo 120 发现 关注 消息 4 搜索 从零开始搭建一个react项目 96 瘦人假噜噜 2017.04.23 23:29* 字数 6330 阅读 32892评论 31喜欢 36 项目地 ...
- 从零开始搭建一个简单的基于webpack的vue开发环境
原文地址:https://segmentfault.com/a/1190000012789253?utm_source=tag-newest 从零开始搭建一个简单的基于webpack的react开发环 ...
随机推荐
- Starting Tomcat v8.0 Server at localhost has encountered a problem.
现有Tomcat文件夹配置有问题,安装新的tomcat从新启动就好了
- 【转载】老男孩读PCIe
目录 老男孩读PCIe之一:从PCIe速度说起 老男孩读PCIe之二:PCIe拓扑结构 老男孩读PCIe之三:PCIe分层结构 老男孩读PCIe之四:TLP类型 老男孩读PCIe之五:TLP结构 老男 ...
- 刷了一个月AI歌唱的视频 做一个大胆预测
现在的AI热点转到ChatAI和AI唱歌去了 很好理解(现在每天在看Neuro的切片 感慨这才是看V的初心 可惜Neuro这个形象在创立的时候只是一个ChatAI 和游戏用的GameBOT并不是同一个 ...
- MyBatis 常用工具类
SQL 类 MyBatis 提供了一个 SQL 工具类,使用这个工具类,我们可以很方便在 Java 代码动态构建 SQL 语句 String newSql = new SQL() ({ SELECT( ...
- CMDB 相关
CMDB 术语 CI(配置项) 配置管理解决方案(如CMDB)中的基本有形或无形实体. 为了交付IT服务而需要管理的任何组件. 通常包括IT服务.硬件.软件.架构.人员和正式文档(如流程文档和sla) ...
- 【技术实战】Vue技术实战【三】
需求实战一 效果展示 代码展示 <template> <div style="display: flex;"> <div style="di ...
- 预处理器 Less 的十个语法
Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量.混合(mixin).函数等功能,让 CSS 更易维护.方便制作主题.扩充. 不过浏览器只能识别 CSS 语言,所以 Les ...
- 让nodejs开启服务更简单--express篇
上一篇文章说到,nodejs获取客户端请求需要我们自己去处理请求参数.请求方式等,而在express框架内部集成了很多好用的方法,我们不需要从0开始编写各种处理逻辑,这样可以极大提高我们的开发效率~ ...
- 合宙ESP32C3使用PlatformIO开发点亮ST7735S
开发背景 模块使用的合宙的ESP32-C3(经典款) 购买连接 CORE ESP32核心板是基于乐鑫ESP32-C3进行设计的一款核心板,尺寸仅有21mm*51mm,板边采用邮票孔设计,方便开发者在不 ...
- 3、Mybatis之CURD
3.1.创建通用工具类 package org.rain.mybatis.utils; import org.apache.ibatis.io.Resources; import org.apache ...