您现在的位置是:首页 >技术交流 >20230515----重返学习-webpack-构建React工程化项目网站首页技术交流

20230515----重返学习-webpack-构建React工程化项目

方朝端 2024-06-17 10:26:16
简介20230515----重返学习-webpack-构建React工程化项目

day-070-seventy-20230515-webpack-构建React工程化项目

webpack

webpack-dev-server

webpack-dev-server跨域代理原理

  1. 首先webpack会对代码进行打包。
    • 大概为:
      • index.html
      • index.jqijvcjnd22015445.css
      • index.kjj.js
  2. webpack-dev-server开始运行。
    1. 在客户端本地启动一个web服务。
      • 假设:
        • 域名: 127.0.0.1 localhost
        • 端口号:3000
    2. web服务会对webpack打包后的文件进行处理,放到webpack的web服务器中。
    3. 客户端浏览器打开。
      1. 输入网址,如 http://127.0.0.1:3000/index.html ;
      2. 向web服务器发起http请求。
      3. web服务器给浏览器一些资源。
  3. 后端服务器
    1. 接口地址:http://192.168.1.23:8000 ;
      • 接口路径,如:
        • /user/list
        • /user/info
    2. 与前端服务器是跨域的,所以客户端浏览器会给前端服务器发起一个请求。
    3. 前端服务器充当一个代理服务器,实现数据的跨域请求!proxy跨域代理的原理。
    4. 代理服务器向真正的后端发请求。
      • 因为后端与后端之间默认是没有跨域限制的。
      • 也可以在这里写一个临时后台。
    5. 后端服务器向代理服务器返回数据。
    6. 前端服务器把后端服务器返回的数据,转发给回客户端服务器。

webpack-dev-server跨域代理配置

  1. 先安装webpack-dev-server这个插件。
  2. 配置开发服务器。
  3. 用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或方法进行重写

构建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了。
  • web-vitals是用来做性能测试。

  • 默认可执行脚本

    • start 开发服务器运行
    • build 打包文件
    • test 单元测试
    • eject 暴露配置项
      • 一旦暴露出来,就能再隐藏回去了!
      • 基本上一定会暴露出来,只用默认的不太好。如跨域就得自己配置。

词法规范

  • 不能论是@vue/cli还是create-react-app等脚手架,创建好的项目中,基本上都包含 Eslint 的配置!
    • Eslint :词法检测「检测编写的代码是否符合既定的规范」
      • 浏览器本身在运行JS的时候,也会进行词法检测,只不过其只会检测语法是否符合ECMAScript的规范,不符合规范的,说明语法写错了,报SyntaxError
        • 但是 Eslint ,它不仅仅可以检测错误的语法,而且一些即便没有错(浏览器可以正常运行的),但是它只要认为这样写不好,也会检测成为错误的语法!

          let a = 12
          //如果后续都没有使用这个a,则会给出检测的警告错误:声明但是没有使用!
          
        • 如果格式化有问题,问公司中配置了那个规则的人要。

配置项

  • 不论是 create-react-app 还是 @vue/cli,都把webpack的配置项隐藏到了 node_modules 中了!
    • 如果发现,默认的配置项,没有完全符合我们的要求,此时我们要修改默认的配置项!
      1. @vue/cli

        • 在根目录下创建 vue.config.js ,按照官方要求去修改即可
        • 降低了开发者的学习门槛,即便webpack知识不咋地,也可以完成一些基础配置的更改;但凡webpack稍微好点,直接想改啥就改啥!!
      2. create-react-app

        • react作者是没有尤雨溪贴心的,他认为你连webpack都不会,你还做啥前端!

        • 所以如果我们想修改默认的配置项,create-react-app的处理办法:把默认的配置项给开发者暴露出来即可!!

          npm run eject    //-> 有个特点:一但暴露出来,就不能再隐藏回去了
          
          • 得先确认是否是暴露,输入yes按回车就好了。
            • 「如果项目有git仓库」我们刚才改了代码,暴露的结果是,会新增很多文件和文件夹,为了防止新增的这些东西,对我们自己写的代码有影响,需要我们提前把修改的东西,提交到git仓库的历史区!!

            • 之后就会在项目中多出一些东西,同时该命令还会

              • /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 语法编译和转换。
        • 如果需要改啥,直接去源码上改就好了「但是要求开发者需要掌握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/*这个目录下有什么文件。
      • imageInlineSizeLimit 把多大的图片处理成base64编码。
        • config/webpack.config.js中配置。
        • 图片base64是前端性能优化一个非常重要的手段!
          • 传统加载图片,是一件比较消耗性能和时间的事情,我们需要:
            1. 向服务器发送请求,获取图片资源。
            2. 浏览器编码。
            3. 渲染。
          • 采用base64,则直接渲染即可,大大加快了图片渲染的速度!
            • 但是图片的BASE64码很多,会增加原有html/css文件的体积,而且如果需要手动base64,是不方便我们开发和维护~!
              • 所以:base64不要滥用!
              • webpack中可以把指定大小的图片,进行base64。
                • 只针对于访问的是本地的静态资源图片。网络的图片不能进行。
        • CSS预编译语言的处理。
          • react脚手架的预编译语言是scss,但想要使用less。
            • scss的loader依旧是sass-loader。
            1. 移除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配置。

代码兼容解决

  • 浏览器的兼容处理
    • 2023年兼容处理主要方向
      1. CSS3的兼容
      2. ES6语法的兼容
      3. 部分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"
              ]
            }
          }
          
        1. CSS3的兼容
          • postcss-loader + autoprefixer + browserslist
        2. ES6语法的兼容
          • babel-loader + babel-preset-react-app + browserslist
          • 如果我们项目中,使用了一些如装饰器的特殊的语法,还需要一些额外的babel的插件来处理!
        3. 部分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"
            

跨域代理

  • 跨域地址
  • 开发环境下,我们可以基于 webpack-dev-server 实现跨域代理。
    • 等到项目部署到服务器端,需要看服务器端是如何部署的。
      • 如果是基于nginx部署,则需要配置nginx的反向代理。
  • 基于 webpack-dev-server 实现跨域代理。
    1. 方案一:查找 /package.json 中的 proxy 字段。
      - 弊端:只能设置成为字符串
      - 不推荐
      - /package.json

      {
        "proxy": "https://news-at.zhihu.com/api/4"
      }
      
    2. 方案二: 在 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
    • 设置方案
      1. 方案一:基于 cross-env 把MAC和Window操作系统的设置方式统一化。

        yarn add cross-env
        
        • 这种方式,需要在执行npm脚本命令的时候配置!
          • 配置开发服务器端口。
        • 默认打包的时候,我们导入的资源,都是从服务器的根目录下开始的,这就要求:我们需要把打包的内容,部署到服务器的根目录下才可以「否则从根目录下,是找不到这些资源的」”虽然我们一般都部署到根目录。
          • 当期望可以调整一下:把访问资源的前缀路径,从 ”/“ 改为 ”./“(从当前目录查找),或者是一个CDN的地址!
      2. 方案二:基于 .env 文件,设置需要的环境变量。

        • 创建三个本地文件,用于存放环境变量。
          • .env用于存放公共的环境变量。
          • .env.development用于存放开发环境development的环境变量。
          • .env.production用于存放生产环境production的环境变量。
      3. 在对应脚本文件的nodejs文件入口中直接用修改环境变量。

进阶参考

  1. webpack-dev-server – 配置中文文档
  2. webpack-dev-server – npm
  3. webpack 中,module,chunk 和 bundle 的区别是什么?
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。