您当前的位置:首页 > 电脑百科 > 程序开发 > 移动端 > H5

京东快递H5项目接入vite实战

时间:2023-03-17 14:26:10  来源:今日头条  作者:东东程序猿

本文介绍了如何在开发阶段将vite应用于vue 2.x 工程,从而提高研发的开发体验与效率。主要涉及如何兼容process变量,如何处理 node-sass 与 dart-sass冲突,以及路径别名的兼容处理等。通过这篇文章可以为读者在vite接入过程中遇到的问题提供一些解决方案, 并帮助读者理清vue工程接入vite的具体思路。本文主要从整体介绍了新版会员徽章系统的设计方案以及未来规划,主要描述了等级模型的设计思路,读者可以通过本文对徽章系统的核心功能有初步的了解。

01前言

随着H5 项目迭代,项目的启动时长在慢慢增长,目前H5的首次启动时长约为 1分钟;且文件的更新也可能触发大范围的依赖重新打包。vite、snowpack等bundless类型的打包工具的出现就是为了解决这个问题。本文将结合实际项目(京东快递H5)实现 vite 打包工具的无痛接入。由于目前未考虑在正式环境中使用vite进行构建,因此接入过程中需要考虑与现有打包方式的兼容问题。

02徽章产品体系

首先解决vite 需要的项目依赖,主要需要添加的项目依赖如下列出:

  • vite
  • vite-plugin-vue2 :官方提供的vite插件,用于兼容 vue2打包
  • @vitejs/plugin-legacy: 用于配置需要适配的低版本浏览器
  • vite-plugin-html: "^2.0.7":用于在模板文件中注入代码,注意版本 高版本可能需要更改
  • vue-template-compiler:vue单文件组件编译插件,要跟 vue版本一致
  • @rollup/plugin-babel: babel 相关配置
  • sass:css预处理语言所需基础库

03模板文件index.html

1.相比 vue-cli构建的项目,模板文件的位置需要更改,为了同时兼容 vue-cli 打包与vite打包,因此需要在根目录下新增 index.html。

2.模板文件需要主动导入项目入口文件 mAIn.js/ts

【HTML/XML】
<script type="module" src="/src/main.js"></script>

04项目启动问题

1. vue 中 /deep/ 方式覆盖深层组件样式的方式不可用,需要替换为 ::v-deep;

2.所有的单文件组件导入必须包含 .vue 扩展;

3.style 中 通过 ~@ 方式书写的路径需要额外的通过 resolve.alias 设置路径别名。

JAVAscript】
     '~@': resolve(__dirname, 'src')

4.提示 global 不存在,需要做兼容处理,通过模板文件(index.html)在全局添加 global,当然也可以通过vite的插件(
vite-plugin-global-polyfill)实现 global 变量的兼容,使用方式可参考源代码库说明。

【HTML/XML】
     <script> global=globalThis </script>

5. 运行时提示 process 不存在,vite 中已经不通过 process 获取自定义的变量,需要使用 import.meta,但是考虑到 vite 仅用于开发阶段,不应对项目进行破坏性兼容,因此考虑在全局自定义 process。vite 通过 define 配置自定义全局变量。

JavaScript】
define: {
// 单独使用这种方式 并不能在运行时获取 env 中设置的变量,
    'process.env': process.env,
}

通过实现简单的命令行工具来根据当前运行环境读取配置文件来对 process 进行数据的补充:

【Javascript】
// env 类型文件读取const dotenv = require('dotenv')
// 扩展 process
   const { expand } = require('dotenv-expand')
// 命令行参数拆分
   const minimist = require('minimist');
// 获取环境变量
function loadEnv (mode) {
   const basePath = resolve(__dirname, `.env${mode ? `.${mode}` : ``}`)
   const localPath = `${basePath}.local`


   const load = envPath => {
// 根据 当前 命令行 mode 读取 env 中的参数配置
     const env = dotenv.config({ path: envPath, debug: process.env.DEBUG })
// 扩展 process
     expand(env)
  }


   load(localPath)
   load(basePath)
}
// 获取命令行中的 参数
   const parmas = minimist(process.argv.slice(2))
// 目前只考虑 mode
   loadEnv(parmas.mode)


// ...
  export default defineConfig({
     define: {
        'process.env': process.env,
})

6. rollup 中不支持动态require 打包编译,而由于H5 中多平台sdk 冲突问题,目前必须通过动态导入的方式避免 api 冲突,因此会导致浏览器报错。解决方案在模板文件中对sdk API 做兼容处理,防止报错。

另外有其它兼容思路,如通过 import 替换 require,但是 import 为异步导入,需要配合顶层await 方式才能比较优雅的实现sdk 的动态导入,但是vue-cli 中目前没有通过配置实现顶层await 的兼容。

【HTML/XML】
     <script>
       function require() {
        return {
          default: {
            init: () => {},
            scanCode: () => new Promise((resolve, reject) => {}),
            initVoice: () => {},
            startRecord: () => {},
            stopRecord: () => {},
            jumpPage: url => {
              window.location.href = url;
          },
          ready: () => Promise.resolve(),
          backPage: (delta = 1) => {
             window.history.go(-delta);
          },
          postMessage: () => {},
          getLocation: () => Promise.resolve({ lat: 0, lng: 0 })
        }
      }
    }
   </script>

7. @jd/pandora-mobile (京东物流内部组件库)组件兼容问题,组件库默认导出方式与 vite 打包不兼容(具体原因可以参考vite issue),解决方案是通过路径别名将 @jd/pandora-mobile路径指定为 commonjs 包,或者可以通过vite中 resolve.mainFields 配置调整包搜索的优先级顺序来解决。

【Javascript】
  resolve: {
    alias: {
       '@jd/pandora-mobile': resolve(__dirname, 'node_modules/@jd/pandora-mobile/dist/pandora-mobile.js'),
    },
   // mainFields: ['main', 'module', 'jsnext:main', 'jsnext']
}

a. @jd/pandora-mobile 组件库样式文件导入不生效,解决方案有两种,一种是通过配置 css 预处理插件配置(preprocessorOptions)将组件库样式添加为额外的全局样式,但是这种方案可能存在样式优先级的问题;第二种是方案是通过 vite 插件 vite-plugin-style-import,实现样式的按需导入。具体配置如下:

【Javascript】
     import { createStyleImportPlugin } from 'vite-plugin-style-import'
        createStyleImportPlugin({
          libs: [{
            libraryName: "@jd/pandora-mobile",
            esModule: true,
            resolveStyle: (name) => {
               return `@jd/pandora-mobile/es/components/${name}/style/index.css`
      },
    }]
   }),
  //css: {
  //  preprocessorOptions: {
  //    scss: {
  //      additionalData: `@import '${resolve(__dirname, 'node_modules/@jd/pandora-mobile/dist/pandora-mobile.css')}';`
  //    }
  //  }
  //},

8. sass-loader 中 node-sass 与 sass 兼容问题(与内部组件库pandora相关),vite中依赖sass(dart-sass),而原项目中依赖node-sass。当两个依赖包同时存在时,由于 @vue/cli-service(v3.8.4)中设置了 sass-loader 优先依赖 sass(dart-sass),从而导致node-sass依赖被屏蔽,在通过原有的webpack方式进行打包时会由于 pandora 组件库与 sass(dart-sass) 不兼容导致打包失败。解决方案是通过调整 vue.config 配置,将sass-loader 中对 node-sass 的依赖优先级提高,以防止安装 sass 后通过 vue-cli 打包报错。

【Javascript】
// vue-cli 3.8.4
defaultSassLoaderOptions.implementation = require('sass')


// 调整 vue.config
css: {
    // ...
    loaderOptions: {
       // ...
      // sass-loader 优先 使用 sass , pandora sass 兼容有问题
      implementation: require("node-sass"),
    }
}

 

05代码方面调整

常量的导入导出在文件之间存在循环依赖报错,需将常量统一导出处理。

06总结

两种项目启动结果对比如下图:

图1 vite 启动H5工程


图2 vue-cli 启动H5工程

1. 就结果来说 vite 在项目启动上确实速度很快,但是由于运行时打包的方式,首次页面交互体验卡顿明显;

2. sdk 兼容仍有待优化。

【Javascript】
import { defineConfig, ViteDevServer, PluginOption, createServer } from 'vite'import legacy from '@vitejs/plugin-legacy'
import { getBabelOutputPlugin } from '@rollup/plugin-babel'
import html from 'vite-plugin-html'
import { createVuePlugin } from 'vite-plugin-vue2'
import { createStyleImportPlugin } from 'vite-plugin-style-import'
import { envSwitchPlugin } from 'vite-plugin-env-switch';
import { globalPolyfill } from 'vite-plugin-global-polyfill'
import { green } from 'picocolors'


const dotenv = require('dotenv')
const minimist = require('minimist');
const { resolve } = require('path')
// 获取环境变量
function loadEnv (mode) {
  const basePath = resolve(__dirname, `.env${mode ? `.${mode}` : ``}`)
  const localPath = `${basePath}.local`


  const load = envPath => {
    const env = dotenv.config({ path: envPath, debug: process.env.DEBUG })
    process.env = Object.assign({...process.env}, env.parsed)
  }


  load(localPath)
  load(basePath)
}
const parmas = minimist(process.argv.slice(2))


loadEnv(parmas.mode)


export interface PluginConfig {
  envKey?: string,
  strGetter?: () => string
}


// https://vitejs.dev/config/
export default defineConfig({
  base: '/express-vite/',
  publicDir: 'public',
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src'),
      '~@': resolve(__dirname, 'src'),
      // https://Github.com/vitejs/vite/issues/1724#issuecomment-767619642
      // vite 读取的文件 跟 esbuild 读取的文件不一致, vite 读取的 是 commonjs,但是 esbuild 找到了 esm 类型的文件认为 不需要转换,所以导致导出没有做兼容
      // '@jd/pandora-mobile': resolve(__dirname, 'node_modules/@jd/pandora-mobile/dist/pandora-mobile.js'),
    },
    // 用于更改 包搜索的优先级 具体原理见 源码 resolvePackageEntry 方法
    // 等待新版本有 config.optimizeDeps?.needsInterop 配置,替换为该方案
    mainFields: ['main', 'module', 'jsnext:main', 'jsnext']
  },
  server: {
    host: 'xxx.jd.com',
    https: true,
    port: 443,
    open: true,
  },
  optimizeDeps: {
  },
  plugins: [
// 本地开发 通过页面按钮 动态切换 项目环境
// https://github.com/PengBoUESTC/vite-plugin-env-switch
    envSwitchPlugin({
      wsProtocol: 'vite-hmr',
      envs: ['prepare', 'development', 'production'],
      wsPath: 'wss://xxx.jd.com/express-vite/',
      root: __dirname,
      eventName: 'env-check'
    }),
    globalPolyfill(),
    createStyleImportPlugin({
      libs: [{
        libraryName: "@jd/pandora-mobile",
        esModule: true,
        resolveStyle: (name) => {
          return `@jd/pandora-mobile/es/components/${name}/style/index.css`
        },
      }]
    }),
    createVuePlugin({}),
    legacy({
      targets: ['defaults', 'not IE 11'],
    }),
    getBabelOutputPlugin({
      configFile: resolve(__dirname, 'babel.config.js'),
    }),
    html({
      inject: {
        injectData: {
          title: '京东快递',
        },
      },
      minify: true,
    }),
  ],
  css: {
    preprocessorOptions: {
      // scss: {
      //   additionalData: `@import '${resolve(__dirname, 'node_modules/@jd/pandora-mobile/dist/pandora-mobile.css')}';`
      // }
    }
  },


  build: {
    outDir: 'dist',
    target: 'es2015',
    minify: 'terser',
    rollupOptions: {
      plugins: [
      ],
    },
  },
  define: {
    'process.env': process.env,
  }
})

作者:杨博



Tags:H5   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
H5开发框架
跨平台移动应用开发框架允许开发者使用一套代码在多个操作系统上构建应用程序,从而节省时间和资源。以下是一些常见的跨平台移动应用开发框架以及它们的特点,希望对大家有所帮...【详细内容】
2023-08-11  Search: H5  点击:(252)  评论:(0)  加入收藏
一次弄懂H5原型图,轻松搞定H5活动开发
初入职场的新手产品经理或者设计师,很多都曾疑惑过,H5的设计需求是什么?其实H5还有一个比较易于理解的称呼,就是H5营销页面。在当今移动互联网的快速发展的数字化时代,H5页面活动...【详细内容】
2023-07-21  Search: H5  点击:(159)  评论:(0)  加入收藏
京东快递H5项目接入vite实战
本文介绍了如何在开发阶段将vite应用于vue 2.x 工程,从而提高研发的开发体验与效率。主要涉及如何兼容process变量,如何处理 node-sass 与 dart-sass冲突,以及路径别名的兼容处...【详细内容】
2023-03-17  Search: H5  点击:(231)  评论:(0)  加入收藏
H5直播技术起航
作者:京东科技 吴磊音视频基本概念视频格式就是通常所说的.mp4,.flv,.ogv,.webm等。简单来说,它其实就是一个盒子,用来将实际的视频流以一定的顺序放入,确保播放的有序和完整性...【详细内容】
2023-01-10  Search: H5  点击:(239)  评论:(0)  加入收藏
外部h5页面如何通过跳转引流到微信小程序
由于Html5来了,为了曾热点,所以都叫H5了。 而且,现在很多的APP开发,其实就是一个软件的壳,内部都是H5,但实际上外部也是h5,谈不上原生应用,至于H5有什么BUG,就是很多东西都无法解决的...【详细内容】
2023-01-05  Search: H5  点击:(269)  评论:(0)  加入收藏
怎样从微信公众号h5跳转小程序,难度大吗,具体是如何操作的?
微信公众号h5应该如何转跳到小程序,难度大吗?很多人心里会有这样的疑问也是正常的,认为只有“专业人员”才能够进行操作,其实不然,普通人也是能够进行操作的。实际上很简单,“专业...【详细内容】
2022-11-09  Search: H5  点击:(385)  评论:(0)  加入收藏
一看就能学会的H5视频推流方案
环境部署1、 配置、安装 Nginx;# ./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-pcre=/usr/loca...【详细内容】
2022-08-27  Search: H5  点击:(617)  评论:(0)  加入收藏
H5实时解码音频并播放
音视频的格式是一个有歧义的说法。我们熟知的诸如Flv、Mp4、Mov啥的都是包装格式,可以理解为一种容器,就像一个盒子。里面放到是经过编码的音视频数据,而这些音视频数据都有自...【详细内容】
2022-08-17  Search: H5  点击:(684)  评论:(0)  加入收藏
ElasticSearch5.5.1 单台服务器部署多个节点
在单台服务器上部署多个节点,一般主要针对的是学习阶段,正式环境一台服务器只会部署一个节点,以实现分布式效果。下面是在单台服务器部署两个节点的方法。1、将安装好的elastic...【详细内容】
2022-07-06  Search: H5  点击:(441)  评论:(0)  加入收藏
微信小程序跳转H5,配置业务域名教程
随着微信小程序的运营场景不断丰富,不少openinstall客户希望通过小程序拓展App落地页下载场景。但由于微信小程序本身的限制,企业主体的小程序必须配置业务域名,才能在web-view...【详细内容】
2022-07-01  Search: H5  点击:(918)  评论:(0)  加入收藏
▌简易百科推荐
京东快递H5项目接入vite实战
本文介绍了如何在开发阶段将vite应用于vue 2.x 工程,从而提高研发的开发体验与效率。主要涉及如何兼容process变量,如何处理 node-sass 与 dart-sass冲突,以及路径别名的兼容处...【详细内容】
2023-03-17  东东程序猿  今日头条  Tags:H5   点击:(231)  评论:(0)  加入收藏
什么是HTML5?HTML5的含义、元素和好处
译者 | 李睿审校 | 孙淑娟HTML5是超文本标记语言(HTML)的第五版,网络浏览器使用它来可视化代码。它在网站功能、网页内容开发等方面有一些改进。 ​HTML的发展 ​在万维网的...【详细内容】
2023-03-16  李睿  51CTO  Tags:HTML5   点击:(261)  评论:(0)  加入收藏
H5直播技术起航
作者:京东科技 吴磊音视频基本概念视频格式就是通常所说的.mp4,.flv,.ogv,.webm等。简单来说,它其实就是一个盒子,用来将实际的视频流以一定的顺序放入,确保播放的有序和完整性...【详细内容】
2023-01-10  京东云开发者  今日头条  Tags:H5   点击:(239)  评论:(0)  加入收藏
Canvas从入门到实战
1、什么是Canvas?HTML5 提供Canvas API,其本质上是一个DOM元素,可以看成是浏览器提供一块画布供我们在上面渲染2D或者3D图形。由于3D绘制上下文(webgl)目前在很多浏览器上兼...【详细内容】
2022-12-24  闪念基因  今日头条  Tags:Canvas   点击:(223)  评论:(0)  加入收藏
网站程序开发使用的html5你了解吗
首先可以肯定,html5(简称h5)将在很多年内成为互联网的主流。那到底什么是h5呢?想了解h5,先要了解它的前身html和被它终结的flash:2000年左右的前端静态网页格式是html的,仅支持ie,n...【详细内容】
2022-09-26  易企优     Tags:html5   点击:(498)  评论:(0)  加入收藏
使用 JavaScript 和 HTML5 Canvas 绘制图表
你将要创造什么在本教程中,我将向您展示如何使用 JavaScript 和画布以饼图和圆环图的形式显示数字信息。什么是饼图?图表是一种统计工具,用于以图形方式表示数值数据。饼图将...【详细内容】
2022-08-31  兴趣编程网  今日头条  Tags:   点击:(505)  评论:(0)  加入收藏
一看就能学会的H5视频推流方案
环境部署1、 配置、安装 Nginx;# ./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-pcre=/usr/loca...【详细内容】
2022-08-27  音视频开发老舅    Tags:H5   点击:(617)  评论:(0)  加入收藏
H5实时解码音频并播放
音视频的格式是一个有歧义的说法。我们熟知的诸如Flv、Mp4、Mov啥的都是包装格式,可以理解为一种容器,就像一个盒子。里面放到是经过编码的音视频数据,而这些音视频数据都有自...【详细内容】
2022-08-17  音视频开发老舅    Tags:音频   点击:(684)  评论:(0)  加入收藏
实战演示 H5 性能分析
W3C标准是浏览器标准,一般浏览器都支持W3C标准,它规定使用者可以通过api查询性能信息,可借用W3C协议完成自动化H5性能测试。 W3C官网: https://www.w3.org/TR/navigation-timing...【详细内容】
2022-06-06  CeshirenTester    Tags: H5   点击:(329)  评论:(0)  加入收藏
HTML5新特性
①语义化标签,可以让页面有更加完善的结构,让页面的元素有含义,同时利于被搜索引擎解析,有利于SEO,主要标签包括下面的标签:html5新的常用标签②增强型表单可以通过input的type属...【详细内容】
2022-05-07  Celinf    Tags:HTML5   点击:(414)  评论:(0)  加入收藏
站内最新
站内热门
站内头条