uni-app vue2+webpack -> vue3+vite 相关问题汇总(有感而发)

vue2+webpack -> vue3+vite 小记

前述大坑:

一. 所有编译时的 包引入(包括第三方包引入:miniprogram-sm-crypto等)都要由module.exports + require,改为 import + export,不然报错到怀疑人生。

二. 环境变量文件 .env .env.prod 变量须以 VITE_ 开头, 且import.meta.env.VITE_ 来使用

三. 生成的路由地址文件需存入pages.json中(之前都放到了 app.json中),且生成路由文件属于node脚本运行,可采用require。
“dev:weixin”: “(npm run build:router) & (uni -p mp-weixin --minify)”
所有运行文件,先运行router生成,再编译小程序

四. store
模块化引入:
import.meta.globEager(‘./modules/*.js’)

采用 usestore()后使用,    
使用方式:
const store = useStore()
store.commit('resource/setNoticeList', noticeList.value)
const noticeList = computed(() => store.state.resource.noticeList)

五. 生命周期等通过 import { onShow, onHide, onLoad } from ‘@dcloudio/uni-app’ 引入

六. f is not a function,可能是watch的时候,处理函数在声明之前定义了导致。

详细迁移指南

  1. .env .env.prod 文件切换后,需参考https://cn.vitejs.dev/guide/env-and-mode.html#env-files

VITE_SOME_KEY=123
DB_PASSWORD=foobar

只有 VITE_SOME_KEY 会被暴露为 import.meta.env.VITE_SOME_KEY 提供给客户端源码,而 DB_PASSWORD 则不会。

console.log(import.meta.env.VITE_SOME_KEY) // 123
console.log(import.meta.env.DB_PASSWORD) // undefined

① 需携带前缀 VITE_
② process.env.XXX 需改为 import.meta.env.XXX

  1. 由于vue3中 变量都是const定义,所以要尽量避免全局变量跟局部变量之间重名的可能性

  2. 只支持使用 ES6 模块规范
    commonJS 需改为 ES6 模块规范

    # 模块导入
    // 之前 - Vue 2, 使用 commonJS
    var utils = require("../../../common/util.js");
    
    // 之后 - Vue 3, 只支持 ES6 模块
    import utils from "../../../common/util.js";
    
    # 模块导出
    // 之前 - Vue 2, 依赖如使用 commonJS 方式导出
    module.exports.X = X;
    
    // 之后 - Vue 3, 只支持 ES6 模块
    export default { X };
    
  3. uni-app的pages.json的模块化,依然采用 require 的方式引入配置信息文件,这是因为他们是编译前处理文件,并不打包入最后的文件中,因而不影响 上述模块规范。
    如:notice的PageConfig.js中,

const { HOST_RADAR } = require('../../config/hostKey')
const { radar_api_key } = require('../../config/apiKey')

因此如果配置文件多处使用,写两份处理,
一份 配置 module.exporrs 用于api生成静态文件使用
一份 export default 用于代码打包时使用

注意:配置类文件,可使用json文件代替,解决同一份配置文件,既可以require 又可以 import

  1. vue3+vite 版本的 vuex
    ① 去中心化采用

     const modulesFiles = import.meta.globEager('./modules/*.js')
     const modules = {}
     Object.keys(modulesFiles).forEach(item => {
       const moduleName = item.replace(/^\.\/modules\/(.*)\.\w+$/, '$1')
       const value = modulesFiles[item]
       modules[moduleName] = value.default
     })
    

    ② 目前使用原始操作,

    import { useStore, mapMutations } from 'vuex';
    ...
    setup() {
         const store = useStore()
         store.commit('resource/setNoticeList', noticeList.value)
    
         const noticeList = computed(() => store.state.resource.noticeList)
    }
    

    另注意:好多地方你不用.value,他不报错,所以谨记复制过来的代码,this去掉 换成.value

  2. 修改了httpRequest的部分配置文件引入,统一改为import引入,防止vite报错。

开发建议:

setup中,虽无代码顺序书写规定,但为了方便阅读,最好定一个书写顺序,方便后续阅读和其他人修改

待查阅问题:
一、
xxx does not provide an export named ‘xxx’
大部分第三方包都是 cjs 导出的,也就是只有一个导出口,比如 axios 、jquery、lodash等,他们的导出方式类似下面这样
module.exports = require(‘./xxx’);
复制代码
显然,这并不能被 Vite 识别,因为 Vite 只支持 ESM 的导出方式,这部分第三方包需要做个兼容。
好在现在Vite有一个预编译功能,会把这些第三方包预编译一遍,转换为ES Module,放置在node_modules/.vite文件夹下。类似下面

所以对于这些第三方包,如果是commonjs的规范,我们不用管Vite默认会帮我们处理

链接:https://juejin.cn/post/7044887611273379870

```js
strem = execSync('node -e "const config = require(\\"./.unidevtools.js\\"); console.log(JSON.stringify(config))"', { cwd: getrootPath, encoding: 'utf-8' })
// 下面这句mac可以,windows不可以
// strem = execSync('node -e \'const config = require("./.unidevtools.js"); console.log(JSON.stringify(config))\'', { cwd: getrootPath, encoding: 'utf-8' })
```

一般需引入项:

<l-show-toast></l-show-toast>

import { showToast } from '@/util'

const showTo = (title) => {
  showToast(title, ctx)
}

import globalData from '@/config'
import { useStore } from 'vuex';
import { ref, computed, watch, getCurrentInstance } from 'vue'
import { onShow, onHide, onLoad } from '@dcloudio/uni-app'

export default {
  setup() {
    const store = useStore()
    const { ctx } = getCurrentInstance()
    const cdnImageUrl = ref(globalData.middleground.cdnImageUrl)
    
    return {
      cdnImageUrl
    }
  }
}

你可能感兴趣的:(webpack,uni-app,前端)