• 解决半岛问题 中美对话合作必不可少 2019-03-21
  • 阳泉计划今年在全省率先整体脱贫 2019-03-21
  • 《王者荣耀》Switch版正式公布 今年秋季推出 2019-03-16
  • 十多次告病危 2岁高危白血病男童盼来“生命火种” 2019-03-16
  • 摄艳|本网摄影师赤壁、竹林创作人像尽显侠客风 2019-03-16
  • 我在吃饭,重点在那?重点在饭,难道我只能吃饭吗?看着就想笑 2019-03-10
  • 人民日报社习近平新闻思想理论研讨会发言摘编 2019-03-10
  • 建始白云草地音乐节:醉了游人,火了产业,牵动慈善 2019-03-01
  • “直播政务述职”是与民沟通良机 2019-02-22
  • 熊猫启航计划即将启动 让世界聆听大熊猫声音 2018-12-28
  • 三星侵犯一大学专利 被判支付罚金4亿美元 2018-12-04
  • 以政府拟严打“乱拍摄”以军行为 最高10年监禁 2018-12-04
  • 今天看啥
      热点:

        新疆35选7的开奖号 www.ts3ne.com

        Vue 类的项目开发中项目结构基本都是类似于 Vue-cli 生成的方式,这种方式开发中,最常用到的模式是开启代理进行 mock 调试或远程调试,也就是使用了 Vue-cli 设置的配置 proxyTable 或者直接使用 Webpack-dev-server提供的 proxy 选项。它是采用了 http-proxy 库,所以具体配置可查看:

        https://github.com/nodejitsu/node-http-proxy#options

        利用配置的这些参数我们可以做更为灵活的配置,达到更好的效果

        使用需求

        假设我们本地开发目前以下几种状态:

        • 本地开发,数据使用本地的 mock Server
        • 涉及权限接口使用本地 mock 数据,其他全部使用指定的一台远程机器
        • 涉及权限接口使用本地 mock 数据,其他数据分接口使用不同的远程机器
        • 所有接口使用同一台远程机器

        方案

        先看下经典的proxyTable 写法:

         
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        proxyTable: {
         '/authui/': {
          target: target,
          changeOrigin: true
         },
         '/vendor/': {
          target: target,
          changeOrigin: true
         }
        }

        其中用到了 changeOrigin 字段,主要是用于改变请求的 header。细化下需求:

        • 本地开发:target 指向 localhost 的某个端口即可。至于 host 的验证肯定是不需要的
        • 部分本地,其他固定的一台远程机器:需要配置 localhost 和远程的地址,远程地址多半是需要验证 host 的
        • 同二,但机器有多台:需要手动配置多台机器
        • 同一台远程机器,此时机器可能要严格验证,即 IP 也必须使用域名,配置好系统 host 才可使用

        说明:严格验证 host 和普通验证 host 区别主要在于严格验证时,请求的 url 必须是远程机器的域名,
        不能直接修改请求的 header 的 host 实现,即必须在系统 host 层面配置好域名。

        分析完成具体需求好,就开始准备实现的方式。原有开发方式是执行 npm run dev,如果我们需要在命令行层面添加配置,就需要设置为 npm run dev --param=paramvalue 的方式。对于使用 npm 的 script 脚本执行的命令,
        它参数的获取无法通过 process.env 获得,而且通过 process.env.npm_config_paramName 的方式获取,
        使用现成的命令行参数解析库也不是很方便,但为了省事,暂时还是使用 npm 自带的解析。

        请求发起过程中需要以下几个参数:

        • host: 发起请求需要指向的 host,可能每台机器验证并不相同
        • port: 代理转发的端口
        • receiver: 用于 push 的远程地址,内包含了 ip 地址,为了省事,没有单独列出 ip 地址

        然后定义代理请求自定义类型,用于配置:

        • local: 本地地址,即 localhost
        • remote: 指定的远程机器
        • 其他自定义类型:用于在配置文件中已经指定的其他类型
        • 原版本的请求,如 '//xxx' 或者 Object 类型的配置,此类代理永不处理

        根据需要,我们添加以下几个参数用于控制代理指向地址:

        1. rd: 远程机器的地址
        2. focus: 严格模式,所有自定义类型的代理转换为指定的 rd 机器,只在存在 rd 参数时可用
        3. allLocal:自定义类型代理全部指向本地
        4. host:请求发现是否使用 host,而不是 IP 地址

        总结一下(序号指向前面的需求):

        • 需要使用 host 进行访问的情形:4
        • 需要更改 host:除 localhost 外都需要更改
        • 需要对已有类型进行转换:1: 需要将所有自定义类型都转换为 local, 2和3:什么也不转换,4:所有的自定义类型全部转换为

        remote 类型

        这么一看,貌似 host 是不需要的,它的存在主要是针对某些 机器可能需要使用 host 的方式,所以还是保留一下。

        实现

        逻辑理清了就很简单了,配置文件设置为:

         
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        module.export = {
         rd1: {
          host: 'dev1.example.com',
          port: 8838,
          receiver: '//1.1.1.1:8888/receiver'
         },
         rd2: {
          host: 'dev2.example.com',
          port: 8838,
          receiver: '//1.1.1.1:8888/receiver'
         }
        }

        proxyTable 配置方式

         
        1
        2
        3
        4
        5
        6
        7
        8
        {
         proxyTable: {
          '/api1': 'remote',
          '/api2': 'rd2',
          '/auth/xx': 'local',
          '/other': '//example.com'
         }
        }

        获取 proxyTable 的代码:

         
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        59
        60
        61
        62
        63
        64
        65
        66
        67
        68
        69
        70
        71
        72
        73
        74
        75
        76
        77
        78
        79
        80
        81
        82
        83
        84
        85
        86
        87
        88
        89
        90
        91
        92
        93
        // 处理 proxyTable
        const releaseConfig = require('../config/release.conf.js')
        const rdConfig = releaseConfig[process.env.npm_config_rd]
        const isAllRemote = process.env.npm_config_focus
        const useHost = isAllRemote || process.env.npm_config_host
        // 是否本机开发,本机开发 remote 会指向 local
        const isAllLocal = process.env.npm_config_allLocal
        module.exports = function (proxy) {
         const localUrl = `http://localhost:${proxy.localProxyPort}`
         const defaultHost = proxy.defaultRdHost || 'dev-example.com'
         const localProxyPort = proxy.localProxyPort || 8787
         const finalConfig = formatReleaseConfig(releaseConfig)
         const remote = finalConfig.remote || {}
         if (process.env.npm_config_rd) {
          if (!rdConfig) {
           throw new TypeError('RD 机器名称不存在,请在 config/release.conf.js 中进行配置')
          }
          if (!remote.ip) {
           throw new Error('请配置 rd 机器的 receiver')
          }
         }
         if (isAllRemote && !rdConfig) {
          throw new TypeError('focus 只能在提供了 rd 名称后可设置')
         }
         function formatReleaseConfig (config) {
          const result = {}
          Object.keys(config).map((key) => {
           const value = config[key]
           const ipMatch = (value.receiver || '').match(/:\/\/(.*?):\d/)
           const ip = ipMatch && ipMatch[1]
           result[key] = {
            ip,
            host: value.host || defaultHost,
            port: value.port || '8391'
           }
          })
          // 设置 remote
          if (rdConfig) {
           const ipMatch = (rdConfig.receiver || '').match(/:\/\/(.*?):\d/)
           const ip = ipMatch && ipMatch[1]
           result.remote = {
            ip,
            host: rdConfig.host || defaultHost,
            port: rdConfig.port || '8391'
           }
          }
          // 设置 local
          result.local = {
           ip: 'localhost',
           host: 'localhost',
           port: localProxyPort
          }
          return result
         }
         function setProxy (proxyTable) {
          const result = {}
          Object.keys(proxyTable).forEach((api) => {
           let type = proxyTable[api]
           const isCustomType = typeof type === 'string' && !/^http/.test(type)
           if (isCustomType && type !== 'remote' && type !== 'local' && !finalConfig[type]) {
            throw new TypeError(`代理类型${type}不正确,请提供 http 或 https 类型的接口,或者指定正确的 release 机器名称`)
           }
           if (type === 'remote' && !finalConfig.remote) {
            type = 'local'
           }
           if (isCustomType) {
            if (isAllRemote && type !== 'remote') {
             type = 'remote'
            }
            if (isAllLocal && type !== 'local') {
             type = 'local'
            }
           }
           const targetConfig = finalConfig[type]
           let target = type
           if (targetConfig) {
            target = {
             target: `http://${useHost ? targetConfig.host : targetConfig.ip}:${targetConfig.port}`,
             // 使用 host 时需要转换,其他不需要转换
             headers: {
              host: `${targetConfig.host}:${targetConfig.port}`
             }
            }
           }
           result[api] = target
          })
          return result
         }
         return {
          proxyTable: setProxy(proxy.proxyTable),
          host: remote.host || defaultHost
         }
        }

        用法

        用法中需要配置两种指向:系统 host 和浏览器代理 Host。
        之所以要两种 host, 本质上是因为接口使用的域名
        和我们的本地访问的域名是相同的,同一域名无法指向两个地址,所以相当于对浏览器端进行了拦截。
        系统 host 推荐使用 switchHost 进行切换,浏览器推荐使用 whistle 进行切换。

        本地开发

        host 配置:无
        whistle 配置:默认的域名

        127.0.0.1 dev.example.com

        启动命令:

         
        1
        2
        npm run dev
        npm run dev --allLocal

        注: 此时 proxyTable 中配置的 remote 全部转换为 local,在 allLocal 参数时将所有自定义类型转换为 local

        本地 + 1 台远程

         
        1
        2
        3
        4
        host 配置:无
        whistle 配置:默认的域名
        127.0.0.1 dev1.example.com
        127.0.0.1 dev2.example.com

        启动命令:

         
        1
        2
        npm run dev --rd=rd1
        npm run dev --rd=rd1 --host

        注: --host 表示使用访问使用 host 而非 ip,使用时需要 host 地址

        本地 + n 台远程

        host 配置:无

        whistle 配置:默认的域名

        127.0.0.1 dev1.example.com

        127.0.0.1 dev2.example.com

         
        1
        2
        3
        4
        5
        6
        7
        8
        {
         proxyTable: {
          '/api1': 'rd1',
          '/api2': 'rd2',
          '/auth/xx': 'local',
          '/other': '//example.com'
         }
        }

        proxyTable 配置:

        启动命令:

         
        1
        npm run dev

        远程 1 台机器

        host 配置:

         
        1
        2
        1.1.1.1 dev1.example.com
        1.1.1.1 dev2.example.com

        whistle 配置:默认的域名

         
        1
        2
        127.0.0.1 dev1.example.com
        127.0.0.1 dev2.example.com

        启动命令:

         
        1
        npm run dev --rd=rd1 --focus

        组件优化

        vue 的组件化深受大家喜爱,到底组件拆到什么程度算是合理,还要因项目大小而异,小型项目可以简单几个组件搞定,甚至不用 vuex,axios 等等,如果规模较大就要细分组件,越细越好,包括布局的封装,按钮,表单,提示框,轮播等,推荐看下 Element 组件库的代码,没时间写这么详细可以直接用 Element 库,分几点进行优化

        •组件有明确含义,只处理类似的业务。复用性越高越好,配置性越强越好。

        •自己封装组件还是遵循配置 props 细化的规则。

        •组件分类,我习惯性的按照三类划分,page、page-item 和 layout,page 是路由控制的部分,page-item 属于 page 里各个布局块如 banner、side 等等,layout 里放置多个页面至少出现两次的组件,如 icon, scrollTop 等

        总结

        细挖需求,可能还有更简单的方式,在大部分情况下能够减少代码修改,是 webpack 配置型的实现吧。当然,方式并不完美,尤其在 mac 下,居然不能支持 --rd xx 这种形式,可以有类似的库吧,后续可以做为深入的内容。

        新疆35选7的开奖号 www.ts3ne.comtrue//www.ts3ne.com/Javascript/1316491.htmlTechArticleVue 类的项目开发中项目结构基本都是类似于 Vue-cli 生成的方式,这种方式开发中,最常用到的模式是开启代理进行 mock 调试或远程调试,也...

        相关文章

          暂无相关文章
        相关搜索:

        帮客评论

        视觉看点
      • 解决半岛问题 中美对话合作必不可少 2019-03-21
      • 阳泉计划今年在全省率先整体脱贫 2019-03-21
      • 《王者荣耀》Switch版正式公布 今年秋季推出 2019-03-16
      • 十多次告病危 2岁高危白血病男童盼来“生命火种” 2019-03-16
      • 摄艳|本网摄影师赤壁、竹林创作人像尽显侠客风 2019-03-16
      • 我在吃饭,重点在那?重点在饭,难道我只能吃饭吗?看着就想笑 2019-03-10
      • 人民日报社习近平新闻思想理论研讨会发言摘编 2019-03-10
      • 建始白云草地音乐节:醉了游人,火了产业,牵动慈善 2019-03-01
      • “直播政务述职”是与民沟通良机 2019-02-22
      • 熊猫启航计划即将启动 让世界聆听大熊猫声音 2018-12-28
      • 三星侵犯一大学专利 被判支付罚金4亿美元 2018-12-04
      • 以政府拟严打“乱拍摄”以军行为 最高10年监禁 2018-12-04