您现在的位置是:首页 >技术交流 >20230515----重返学习-webpack-构建React工程化项目网站首页技术交流
20230515----重返学习-webpack-构建React工程化项目
day-070-seventy-20230515-webpack-构建React工程化项目
webpack
webpack-dev-server
webpack-dev-server跨域代理原理
- 首先webpack会对代码进行打包。
- 大概为:
- index.html
- index.jqijvcjnd22015445.css
- index.kjj.js
- 大概为:
- webpack-dev-server开始运行。
- 在客户端本地启动一个web服务。
- 假设:
- 域名: 127.0.0.1 localhost
- 端口号:3000
- 假设:
- web服务会对webpack打包后的文件进行处理,放到webpack的web服务器中。
- 客户端浏览器打开。
- 输入网址,如 http://127.0.0.1:3000/index.html ;
- 向web服务器发起http请求。
- web服务器给浏览器一些资源。
- 在客户端本地启动一个web服务。
- 后端服务器
- 接口地址:http://192.168.1.23:8000 ;
- 接口路径,如:
- /user/list
- /user/info
- …
- 接口路径,如:
- 与前端服务器是跨域的,所以客户端浏览器会给前端服务器发起一个请求。
- 接口全路径如:
- http://127.0.0.1:3000/user/list
- 可简写:/user/list
- http://127.0.0.1:3000/user/list
- 接口全路径如:
- 前端服务器充当一个代理服务器,实现数据的跨域请求!proxy跨域代理的原理。
- 代理服务器向真正的后端发请求。
- 因为后端与后端之间默认是没有跨域限制的。
- 也可以在这里写一个临时后台。
- 后端服务器向代理服务器返回数据。
- 前端服务器把后端服务器返回的数据,转发给回客户端服务器。
- 接口地址:http://192.168.1.23:8000 ;
webpack-dev-server跨域代理配置
- 先安装webpack-dev-server这个插件。
- 配置开发服务器。
- 用webpack server启动webpack-dev-server服务。
- 可能会报错,可能就是一些配置项没有。
- 这主要是配置问题。
- 或者是webpack-dev-server版本不一致。
- 一般以1为单位降一个版本或升一个版本。
- 可能会报错,可能就是一些配置项没有。
多文件多入口
loader
- 使用loader
- 在module.rules数组中写,每个对象表示一类文件的处理。
- 如果使用很多loader,则处理顺序:从下到上,从右到左…。
- 默认对当前根目录下所有目录的文件都进行编译。
- include: 指定只对那些目录进行编译
webpack兼容问题
- 在前端项目中,需要考虑的兼容问题:
-
首先需要设置浏览器兼容列表:package.json
{ "browserslist": [ "> 1%", "last 2 versions", "not ie <= 9" ] }
-
webpack的设置
- css3样式的兼容
- 思路:设置前缀
- ES6语法的兼容
- 思路:转换为ES5
- ES6内置API的兼容
- 思路:
- 不使用这些内置API
- 对这些内置API或方法进行重写
- 思路:
- css3样式的兼容
-
构建React工程化项目
安装create-react-app
npm i create-react-app -g //「mac需要加sudo」
项目说明
-
vue框架,所有的核心都在vue库中,所以只要导入vue就行了
import Vue from 'vue'
- vue框架本身只能开发WebApp;但是我们可以在uni-app框架中,基于vue的语法,开发NativeApp!!
-
react框架不是类似于vue那样设计的,核心是分开的。
- import React from ‘react’ 语法核心
- react-dom 构建web页面,即webApp。用于构建浏览器相关页面的。
- WebApp:H5页面。用来构建DOM的。
- vue框架本身只能开发WebApp;但是我们可以在uni-app框架中,基于vue的语法,开发NativeApp!
- react-native 构建NativeApp的,相当于用js,可以创建出安卓与ios系统的DOM。
- 简称RN,也有人叫RN框架。
-
react框架的配置项。
- create-react-app 为了让创建的项目看起来更简单/整洁,把webpack的所有配置,全部都隐藏到了node_modules中
- react-scripts 是React内部自己封装的模块,属于对webpack的统一管理「对打包及预览的管理」
- @vue/cli脚手架也是这样干的,配置文件都放到vue.config.js了。
- react-scripts 是React内部自己封装的模块,属于对webpack的统一管理「对打包及预览的管理」
- create-react-app 为了让创建的项目看起来更简单/整洁,把webpack的所有配置,全部都隐藏到了node_modules中
-
web-vitals是用来做性能测试。
-
默认可执行脚本
- start 开发服务器运行
- build 打包文件
- test 单元测试
- eject 暴露配置项
- 一旦暴露出来,就能再隐藏回去了!
- 基本上一定会暴露出来,只用默认的不太好。如跨域就得自己配置。
词法规范
- 不能论是@vue/cli还是create-react-app等脚手架,创建好的项目中,基本上都包含 Eslint 的配置!
- Eslint :词法检测「检测编写的代码是否符合既定的规范」
- 浏览器本身在运行JS的时候,也会进行词法检测,只不过其只会检测语法是否符合ECMAScript的规范,不符合规范的,说明语法写错了,报SyntaxError
-
但是 Eslint ,它不仅仅可以检测错误的语法,而且一些即便没有错(浏览器可以正常运行的),但是它只要认为这样写不好,也会检测成为错误的语法!
let a = 12 //如果后续都没有使用这个a,则会给出检测的警告错误:声明但是没有使用!
-
如果格式化有问题,问公司中配置了那个规则的人要。
-
- 浏览器本身在运行JS的时候,也会进行词法检测,只不过其只会检测语法是否符合ECMAScript的规范,不符合规范的,说明语法写错了,报SyntaxError
- Eslint :词法检测「检测编写的代码是否符合既定的规范」
配置项
- 不论是 create-react-app 还是 @vue/cli,都把webpack的配置项隐藏到了 node_modules 中了!
- 如果发现,默认的配置项,没有完全符合我们的要求,此时我们要修改默认的配置项!
-
@vue/cli
- 在根目录下创建 vue.config.js ,按照官方要求去修改即可
- 降低了开发者的学习门槛,即便webpack知识不咋地,也可以完成一些基础配置的更改;但凡webpack稍微好点,直接想改啥就改啥!!
-
create-react-app
-
react作者是没有尤雨溪贴心的,他认为你连webpack都不会,你还做啥前端!
-
所以如果我们想修改默认的配置项,create-react-app的处理办法:把默认的配置项给开发者暴露出来即可!!
npm run eject //-> 有个特点:一但暴露出来,就不能再隐藏回去了
- 得先确认是否是暴露,输入yes按回车就好了。
-
「如果项目有git仓库」我们刚才改了代码,暴露的结果是,会新增很多文件和文件夹,为了防止新增的这些东西,对我们自己写的代码有影响,需要我们提前把修改的东西,提交到git仓库的历史区!!
-
git add . git commit -m "注释说明"
-
-
之后就会在项目中多出一些东西,同时该命令还会
/config/
/config/jest/
/config/jest/babelTransform.js
/config/jest/cssTransform.js
/config/jest/fileTransform.js
/config/webpack/
/config/webpack/persistentCache/
/config/webpack/persistentCache/createEnvironmentHash.js
/config/env.js
环境相关的。/config/getHttpsConfig.js
/config/modules.js
/config/paths.js
/config/webpack.config.js
webpack的配置项。/config/webpackDevServer.config.js
webpack-dev-server的配置项。
/scripts/
脚本文件,用nodejs来写的。/scripts/build.js
执行yarn build时执行的,里面有些参数可以调整。/scripts/start.js
执行yarn start时执行的,里面有些参数可以调整。/scripts/test.js
/package.json
- dependencies 中多了很多依赖。
- scripts 命名被必定了,少了eject命名。
- jest 单元调试。
- babel babel的配置。
- babel语法转换的语法包:@babel/preset-env
- react项目中,实现ES6转ES5的语法包:"babel-preset-react-app“ 对 @babel/preset-env 重写,目的是为了支持 JSX 语法编译和转换。
-
- 得先确认是否是暴露,输入yes按回车就好了。
-
如果需要改啥,直接去源码上改就好了「但是要求开发者需要掌握webpack」
-
-
- 如果发现,默认的配置项,没有完全符合我们的要求,此时我们要修改默认的配置项!
base编码
- 用src非base路径,会向服务器发起一个请求。
- 之后浏览器把图片编码成base格式。
- 之后图片会渲染到页面上。
- 用src里写base,可以减少请求。
- 不过去造成html文件变大。
- 同时会造成html标签结构变难看,一大块地方都是那img标签。
- 同时图片处理成base编码还比较难看。
react的webpack配置
- react的webpack配置分散在不同的文件的不同地方。
- 核心入口在
/package.json
中,通过npm run xxx
执行它内部的脚本。 - 之后在package.scripts脚本以nodejs来中运行
/scripts/start.js
或/scripts/build.js
。 /scripts/start.js
或/scripts/build.js
中引入了webpack及webpack的配置以及在这里调用了/config/
中的各个配置或nodejs函数。经过各种处理后返回一个webpack配置对象。- webpack依据
/scripts/start.js
或/scripts/build.js
中返回的webpack配置对象来进行编译,一般是从入口文件开始,入口文件默认配置为/src/index.js
,而从index.js开始,会以浏览器的模式来写及引入代码。特殊语法则是通过webpack的插件来补足,如jsx及less这一类的东西。- process.env.NODE_ENV 是开发环境还是生产环境。
- 在
/scripts/start.js
与/scripts/build.js
中修改。
- 在
- process.env.HOST 开发环境中,本地启动服务器的域名。
- 在
/scripts/start.js
中修改。
- 在
- process.env.PORT 开发环境中,本地启动服务器的端口号(默认3000)。
- 在
/scripts/start.js
中修改。
- 在
- process.env.HTTPS 开发环境中,本地启动服务器的协议是否使用https协议。
- 在
/scripts/start.js
中修改。
- 在
- WARN_AFTER_BUNDLE_GZIP_SIZE 在bundle压缩大小超过之后发出警告。
- 直接写出来的是 module,webpack 处理时是 chunk,最后生成浏览器可以直接运行的 bundle。
- 在
/scripts/build.js
中修改。
- WARN_AFTER_CHUNK_GZIP_SIZ 在chunk压缩大小超过之后发出警告。
- 在
/scripts/build.js
中修改。
- 在
/config/paths.js
中的各项常量dotenv: resolveApp('.env')
appPath: resolveApp('.')
appBuild: resolveApp(buildPath)
appPublic: resolveApp('public')
appHtml: resolveApp('public/index.html')
appIndexJs: resolveModule(resolveApp, 'src/index')
打包入口。appPackageJson: resolveApp('package.json')
appSrc: resolveApp('src')
appTsConfig: resolveApp('tsconfig.json')
appJsConfig: resolveApp('jsconfig.json')
yarnLockFile: resolveApp('yarn.lock')
testsSetup: resolveModule(resolveApp, 'src/setupTests')
proxySetup: resolveApp('src/setupProxy.js')
appNodeModules: resolveApp('node_modules')
appWebpackCache: resolveApp('node_modules/.cache')
appTsBuildInfoFile: resolveApp('node_modules/.cache/tsconfig.tsbuildinfo')
swSrc: resolveModule(resolveApp, 'src/service-worker')
publicUrlOrPath: publicUrlOrPath
- shouldUseSourceMap 是否使用source-map,用于取消生产环境下source-map调试文件的创建,以此来加快打包的速度。
- 在
config/webpack.config.js
中配置。
- 在
- drop_console与drop_debugger 去掉调试相关的代码。
- 在
config/webpack.config.js
中webpack配置项中optimization.minimizer中TerserPlugin插件配置项terserOptions.compress中配置。
- 在
- 配置@等路径别名
- 在
config/webpack.config.js
中webpack配置项中resolve.alias中配置。- 不过这个只是让webpack能够解析及编译"@/*"这类的路径,并不能让vscode等提示工具也能提示出对应路径的文件,需要在根目录配合jsconfig.json这个文件来进行处理。
-
/jsconfig.json
{ "compilerOptions": { "baseUrl": "./", "paths": { "@/*": [ "src/*" ] } } }
- 这个是让vscode等工具能够识别出"@/*"这类的路径,能在打出@这个符号之后提示在
/src/*
这个目录下有什么文件。
- 这个是让vscode等工具能够识别出"@/*"这类的路径,能在打出@这个符号之后提示在
-
- 不过这个只是让webpack能够解析及编译"@/*"这类的路径,并不能让vscode等提示工具也能提示出对应路径的文件,需要在根目录配合jsconfig.json这个文件来进行处理。
- 在
- imageInlineSizeLimit 把多大的图片处理成base64编码。
- 在
config/webpack.config.js
中配置。 - 图片base64是前端性能优化一个非常重要的手段!
- 传统加载图片,是一件比较消耗性能和时间的事情,我们需要:
- 向服务器发送请求,获取图片资源。
- 浏览器编码。
- 渲染。
- 采用base64,则直接渲染即可,大大加快了图片渲染的速度!
- 但是图片的BASE64码很多,会增加原有html/css文件的体积,而且如果需要手动base64,是不方便我们开发和维护~!
- 所以:base64不要滥用!
- webpack中可以把指定大小的图片,进行base64。
- 只针对于访问的是本地的静态资源图片。网络的图片不能进行。
- 但是图片的BASE64码很多,会增加原有html/css文件的体积,而且如果需要手动base64,是不方便我们开发和维护~!
- 传统加载图片,是一件比较消耗性能和时间的事情,我们需要:
- CSS预编译语言的处理。
- react脚手架的预编译语言是scss,但想要使用less。
- scss的loader依旧是sass-loader。
-
移除sass-loader,下载less与less-loader@8。
- less-loader最新版不太兼容react脚手架,最好用旧一点的版本,如8.0.0版本。
yarn remove sass-loader//移除sass-loader; yarn add less less-loader@8//下载less与less-loader@8.0.0;
- 在
config/webpack.config.js
中配置。- 移除scss与sass相关的配置,改成less配置。
- react脚手架的预编译语言是scss,但想要使用less。
- 在
- process.env.NODE_ENV 是开发环境还是生产环境。
- 核心入口在
代码兼容解决
- 浏览器的兼容处理
- 2023年兼容处理主要方向
- CSS3的兼容
- ES6语法的兼容
- 部分ES6+内置API的兼容
- 兼容步骤
-
先在
/package.json
中配置基础browserslist选项。-
/package.json
{ "browserslist": { "production": [ ">1%", "last 2 versions", "not ie < 10" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }
- CSS3的兼容
- postcss-loader + autoprefixer + browserslist
- ES6语法的兼容
- babel-loader + babel-preset-react-app + browserslist
- 如果我们项目中,使用了一些如装饰器的特殊的语法,还需要一些额外的babel的插件来处理!
- 部分ES6+内置API的兼容
-
安装react-app-polyfill插件。
- react-app-polyfill是react对@babel/polyfill的重写。
-
在入口文件
/src/index.js
中引入react-app-polyfill
的一些js文件,如react-app-polyfill/ie11
。import "react-app-polyfill/ie11"
-
-
-
- 2023年兼容处理主要方向
跨域代理
- 跨域地址
- 开发环境下,我们可以基于 webpack-dev-server 实现跨域代理。
- 等到项目部署到服务器端,需要看服务器端是如何部署的。
- 如果是基于nginx部署,则需要配置nginx的反向代理。
- 等到项目部署到服务器端,需要看服务器端是如何部署的。
- 基于 webpack-dev-server 实现跨域代理。
-
方案一:查找
/package.json
中的 proxy 字段。
- 弊端:只能设置成为字符串
- 不推荐
-/package.json
{ "proxy": "https://news-at.zhihu.com/api/4" }
-
方案二: 在 src 下新建 setupProxy.js 文件,基于 http-proxy-middleware 实现跨域代理
-
安装http-proxy-middleware插件。
yarn add http-proxy-middleware
-
新建
src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware'); module.exports = function (app) { app.use( createProxyMiddleware("/api", { target: "http://127.0.0.1:7100", changeOrigin: true, ws: true, pathRewrite: { "^/api": "" } }) ); };
-
-
设置环境变量
- 在react的webpack默认配置项中,有很多操作,是基于环境变量来处理的
- 常用环境变量
- process.env.NODE_ENV 是开发环境还是生产环境
- process.env.HOST 开发环境中,本地启动服务器的域名
- process.env.PORT 开发环境中,本地启动服务器的端口号(默认3000)
- process.env.HTTPS 开发环境中,本地启动服务器的协议是否使用https协议
- process.env.PUBLIC_URL 项目打包静态根目录。
- process.env.BUILD_PATH
- 设置方案
-
方案一:基于 cross-env 把MAC和Window操作系统的设置方式统一化。
yarn add cross-env
- 这种方式,需要在执行npm脚本命令的时候配置!
- 配置开发服务器端口。
- 默认打包的时候,我们导入的资源,都是从服务器的根目录下开始的,这就要求:我们需要把打包的内容,部署到服务器的根目录下才可以「否则从根目录下,是找不到这些资源的」”虽然我们一般都部署到根目录。
- 当期望可以调整一下:把访问资源的前缀路径,从 ”/“ 改为 ”./“(从当前目录查找),或者是一个CDN的地址!
- 这种方式,需要在执行npm脚本命令的时候配置!
-
方案二:基于 .env 文件,设置需要的环境变量。
- 创建三个本地文件,用于存放环境变量。
.env
用于存放公共的环境变量。.env.development
用于存放开发环境development的环境变量。.env.production
用于存放生产环境production的环境变量。
- 创建三个本地文件,用于存放环境变量。
-
在对应脚本文件的nodejs文件入口中直接用修改环境变量。
-
- 常用环境变量