知识点:
- webpack搭配react环境
- 实现适配
- 配置动态式路由
webpack搭配react环境
安装依赖
- npm init -y
- cnpm install react react-dom @types/react @types/react-dom react-router-dom @types/react-router-dom antd redux react-redux @types/react-redux react-thunk redux-logger @types/redux-logger redux-promise @types/redux-promise connected-react-router classnames @types/classnames react-transition-group @types/react-transition-group express express-session body-parser cors axios redux-persist immer redux-immer --save
cnpm i webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader typescript @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript babel-plugin-import style-loader css-loader postcss-loader less-loader less autoprefixer px2rem-loader lib-flexible eslint @types/eslint cross-env --save-dev - tsc --init
{
"compilerOptions": {
//模块解析规则
"moduleResolution": "Node",
//输出口
"outDir": "./dist",
//映射文件
"sourceMap": true,
//不能通过any隐藏值类型
"noImplicitAny": true,
// 编译目标
"target": "es5",
//模块类型
"module": "ESNext",
// react模式会生成React.createElement,在使用前不需要在继续进行转换操作了。
"jsx": "react",
// 模块转换器,支持esmodule和commonjs互相引用
"esModuleInterop": true
},
//需要转化的文件
"include": [
"./src/**/*"
]
}
改变package.json的scripts。NODE_ENV可以给process.env赋值。而webpack serve会默认通过webpack.config.js文件启动webpack
创建webpack.config.js文件
配置Mode模式,入口,出口,以及devtool。
devServer的设置,注意这里的contentBase在webpack5之后已经变成static,若是不设置,默认会从public文件中取。
配置别名以及扩展名。
配置模块,先配置转化react的,通过babel-loader以及一些预设,转化代码。通过plugins配置antd的按需加载,可以控制只编译哪里的代码。
less的处理,显示less-loader转化为css,然后同构px2rem-loader转化rem,再通过postcss-loader进行兼容,再通过css-loader处理,最后通过style-loader渲染在页面上。
静态资源处理,wbepack5之后不需要file-loader,url-loader了,通过asset就可以配置。
插件,这样简单的开发环境就好了,通过npm run dev
适配
接着继续看px转rem
- 如果有草稿纸,适配的转换规则就是:
屏幕真正的宽度/草稿纸的宽度就是比例。
比如屏幕500,草稿纸500,那么他们的比例就是1,草稿纸10px的东西就是屏幕10px大小。
如果屏幕1000,草稿纸500,那么他们的比例就是2,草稿纸10px的东西,到了屏幕就是20px大小,必须乘以2。
再加上我们的自己定义的倍数,比如10。那么
500/500 * 10 = 10px 将它作为当时的Html的fontSize大小,对应1rem。
监听屏幕resize事件,当真实宽度为1000的时候
1rem对应的就是 1000/500 * 10 = 20px,刚好是两倍。适配完毕,所以只要按这个规则,加上px2rem-loader插件,将所有px转化为rem,就可以实现适配。 - 如果没有草稿纸,就更容易了,直接用倍数。比如真实宽度100,倍数是10,1rem就是100/10 = 10px,将10px转化为1rem后,当屏幕放大到1000px的时候,1rem = 1000/10 = 100px,放大倍数一样。
- 然后开发的时候需要注意
这个的填写,比如在750px开发,草稿纸是350px,按照运算规则,750/350*10 = 20px ,1rem = 20px,那么这里就需要填写25px。这样如果草稿纸写了一个10px的东西,开发的时候就需要写20px。这样就会被正常转换。
import { useEffect } from "react";
class Px2Rem {
pWidth = 1285; //草稿宽度
cWidth = 1285; //屏幕宽度
pRem = 100; //转换倍数
constructor(pWidth: number, pRem: number) {
this.pWidth = pWidth;
this.pRem = pRem;
}
setRem = (): void => {
const html = document.getElementsByTagName("html")[0];
const realCwidth =
document.body.clientWidth || document.documentElement.clientWidth; //获得真正的宽度
this.cWidth = realCwidth > 750 ? 750 : realCwidth < 350 ? 350 : realCwidth;
//进行换算,规则为 真正的宽度/草稿纸的宽度 * 倍数 = 1rem
// 比如草稿纸 500px,在真正宽度500px下,10px的东西在真正宽度1000px下就是20px,他们的倍数就是1000/500 = 2
// pRem是倍数,方便计算的,比如10倍,真正宽度500px下,100px就会转为10rem,而到了1000px的时候,10rem = 10* 1000/500*10 = 200px,刚好2倍
html.style.fontSize = (this.cWidth / this.pWidth) * this.pRem + "px";
};
getRemToPx = (rem: number): number => {
return (this.cWidth / this.pWidth) * this.pRem * rem;
};
}
//草稿宽度 350
export const px2Rem = new Px2Rem(750, 10);
const setRem = () => {
px2Rem.setRem();
};
export const useSetRem = () => {
useEffect(() => {
//componentDidMount
setRem(); //初始化
window.addEventListener("resize", setRem);
return () => {
//componentWillUnMount
window.removeEventListener("resize", setRem);
};
}, []);
};
路由:
使用第六版本的react-router-dom
特性
1 useHistory => useNavigate
2 Route的component变成element
3新增路由useRoutes
4 Navigate代替Redirect
5 switch 变成 Routes
6 Route支持嵌套
7 使用Outlet类似vue的router-view
。。。。
具体可以看官网。
这里没有使用useRoutes,因为6.0.2好像跟Outlet搭配使用有死循环bug。所以还是采用自己封装的函数动态配置。如上,
使用这个将我们写的routes渲染成一个个Route,v6的好处就是Route可以嵌套,只要使用Outlet就可以。如
app下的三个组件,会被渲染在Outlet这里。