您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
京东快递H5 项目接入vite实战
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
京东快递H5 项目接入vite实战
自猿其说Tech
2022-09-05
IP归属:未知
64240浏览
### 1 前言 随着H5 项目迭代,项目的启动时长在慢慢增长,目前H5的首次启动时长约为 1分钟。且文件的更新也可能触发大范围的依赖重新打包。vite、snowpack等bundless类型的打包工具的出现就是为了解决这个问题。本文将结合实际项目(京东快递H5)实现 vite 打包工具的无痛接入。具体实现如下 ### 2 相关依赖 首先解决vite 需要的项目依赖,主要需要添加的项目依赖如下列出 1. vite 2. vite-plugin-vue2 :官方提供的vite插件,用于兼容 vue2打包 3. @vitejs/plugin-legacy: 用于配置需要适配的低版本浏览器 4. vite-plugin-html: "^2.0.7": 用于在模板文件中注入代码,注意版本 高版本可能需要更改 5. vue-template-compiler: vue单文件组件编译插件,要跟 vue版本一致 6. @rollup/plugin-babel: babel 相关配置 7. sass: css预处理语言所需基础库 ### 3 模板文件index.html 相比 vue-cli构建的项目,模板文件的位置需要更改,为了同时兼容 vue-cli 打包与vite打包,因此需要在根目录下新增 index.html 模板文件需要主动导入项目入口文件 main.js/ts ```xml <script type="module" src="/src/main.js"></script> ``` ### 4 项目启动问题 1)vue 中 /deep/ 方式覆盖深层租价样式的方式不可用,需要替换为 ::v-deep 2)所有的单文件组件导入必须包含 .vue 扩展 3)style 中 通过 ~@ 方式书写的路径需要额外的通过 resolve.alias 设置路径别名 ```javascript '~@': resolve(__dirname, 'src') ``` 4)提示 global 不存在,需要做兼容处理,通过模板文件(index.html)在全局添加 global ```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 的兼容(了解的同学务必教教我) ```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 打包不兼容,解决方案是通过路径别名将 @jd/pandora-mobile路径替换为 commonjs 包 ```javascript resolve: { alias: { '@jd/pandora-mobile': resolve(__dirname, 'node_modules/@jd/pandora-mobile/dist/pandora-mobile.js'), } } ``` 8)@jd/pandora-mobile 组件库样式文件导入不生效,解决方案是通过配置 css 预处理插件配置,添加额外的全局样式 ```javascript css: { preprocessorOptions: { scss: { additionalData: `@import '${resolve(__dirname, 'node_modules/@jd/pandora-mobile/dist/pandora-mobile.css')}';` } } }, ``` 9)sass-loader 中 node-sass 与 sass 兼容问题(与pandora组件相关),原因是 vue-cli中设置了 sass-loader 优先依赖 sass,而 pandora 中的某些样式与 sass 不兼容,但是vite 需要依赖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"), } } ``` ### 5 代码方面调整 client 相关代码做出调整,常量的导入导出在文件之间存在循环依赖报错,将常量统一导出处理。 ### 6 总结 两种项目启动结果对比如下图 <center>![](//img1.jcloudcs.com/developer.jdcloud.com/d043ef7b-43a5-47ad-b384-7818d7f0ce7820220905163118.png) 图一: vite 启动H5工程 ![](//img1.jcloudcs.com/developer.jdcloud.com/bd91b35a-df4d-4e7d-8eb1-5b769f234bd420220905163124.png) 图二:vue-cli 启动H5工程</center> 1. 就结果来说 vite 在项目启动上确实速度很快,但是由于运行时打包的方式,首次页面交互体验卡顿明显! 2. sdk 兼容仍有待优化 3. pandora 组件兼容方式有待优化,不太优雅。 至此实现了 vite项目与 京东快递H5 项目的对接。具体 vite.config如下 ```javascript import { defineConfig } 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' const VERSION = require('./config/version.js'); const dotenv = require('dotenv') const { expand } = require('dotenv-expand') const minimist = require('minimist'); const { resolve } = require('path') const BTIME = new Date(); // 获取环境变量 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 }) expand(env) } load(localPath) load(basePath) } const parmas = minimist(process.argv.slice(2)) loadEnv(parmas.mode) // https://vitejs.dev/config/ export default defineConfig({ base: '/', publicDir: 'public', resolve: { alias: { '@': resolve(__dirname, 'src'), '~@': resolve(__dirname, 'src'), '@jd/pandora-mobile': resolve(__dirname, 'node_modules/@jd/pandora-mobile/dist/pandora-mobile.js'), }, }, server: { host: 'test.jd.com', https: true, port: 443, open: true, }, optimizeDeps: { }, plugins: [ createVuePlugin({}), legacy({ targets: ['defaults', 'not IE 11'], }), getBabelOutputPlugin({ configFile: resolve(__dirname, 'babel.config.js'), }), html({ inject: { data: { 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, JDEXP: JSON.stringify({ BUILD_VERSION: VERSION.stamp, ENV: process.env.VUE_APP_ENV, BUILD_TIME: `${BTIME.getDate()}.${BTIME.getHours()}.${BTIME.getMinutes()}`, VERSION, }), } }) ``` ------------ ###### 自猿其说Tech-JDL京东物流技术与数据智能部 ###### 作者:彭博
原创文章,需联系作者,授权转载
上一篇:Dive into TensorFlow系列(1)-静态图运行原理
下一篇:MySQL DDL执行方式-Online DDL介绍
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号