错误收集
vscode 控制台执行不了 node 命令
node : 无法将“node”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
原因:没有下载 node。nvm 没有执行 nvm use xx.xx.xx。
Promise 无法捕获 setTimeout 里的异常错误
把 throw new Error 语句放延时函数里,只会报错,不执行 reject 函数或者 catch 函数。
var promise = new Promise((resolve, reject) => {
setTimeout(() => {
throw new Error('nono') //这里主动抛出错误
}, 500);
})
.then(()=>{},(err)=>{
console.log(1) //这里是 reject 时应该调用的函数,但是这里并没有执行,只会在控制台报错
console.log(err) //根本不执行这里
})
.catch((err)=>{
console.log(2) //这里 catch 都不执行
console.log(err)
})而我不把 throw new Error 语句放延时函数里,就能在 reject 函数里执行。
var promise = new Promise((resolve, reject) => {
throw new Error('nono') //这里直接抛出错误,就能被后面的 reject 函数执行到
})
.then(()=>{},(err)=>{
console.log(1) //这里就执行了
console.log(err)
})
.catch((err)=>{
console.log(2)
console.log(err)
})解决异步错误怎么办呢?答案是 try catch。
setTimeout(() => {
try {
throw new Error('出错了')
} catch (e) {
console.log(e)//代码执行的时候,这里就能捕获到上面抛出的异常错误了
}
}, 400)下载依赖使用哪个包管理器
ValidationError: Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema. - options has an unknown property 'data'. These properties are valid: object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }解决:
下载依赖时应该使用包管理器 yarn,而不是 npm。
为什么在 npm 下载依赖失败后不尝试使用 yarn 呢?因为 *.lock 文件被忽略了,项目没有出现 yarn.lock 文件。我哪知道必须要用 yarn 来下载呢。
严格模式
ReferenceError: MP is not defined at xxxxxx解决:
MP 是通过 cdn 引入的一个全局对象。有时候网络不佳可能获取不到。然后我们就可能这样判断:
if (!MP || !MP?.MGS) {
console.warn('MGS sdk init fail');
return;
}但实际上代码走不到 if 判断里。因为 webpack 项目打包时默认为 js 代码开启了严格模式,当变量没有显式声明时,使用该变量会直接抛出错误。
当 CDN 脚本违背同源策略
给 script 脚本添加属性 crossorigin="anonymous"。
<script
src="https://xxx"
crossorigin="anonymous"
></script>如果项目基于 vue-cli 创建,还可以在 vue.config.js 文件中配置 crossorigin 属性。
某些依赖的 es6 代码未被转为 es5 代码
这导致在低版本浏览器出现白屏问题。如果是 vue-cli 项目,可以在 vue.config.js 文件中配置 transpileDependencies 属性。

volta 不能启动使用 yarn 下载依赖的项目
Internal Error: mpaas-uniapp-tutorial@workspace:.: This package doesn't seem to be present in your lockfile; run "yarn install" to update the lockfile at Yb.getCandidates (C:\Users\lukecheng\AppData\Local\Volta\tools\image\yarn\4.0.0-rc.43\bin\yarn.js:199:8150) at xd.getCandidates (C:\Users\lukecheng\AppData\Local\Volta\tools\image\yarn\4.0.0-rc.43\bin\yarn.js:135:1311) at C:\Users\lukecheng\AppData\Local\Volta\tools\image\yarn\4.0.0-rc.43\bin\yarn.js:204:8096 at Vy (C:\Users\lukecheng\AppData\Local\Volta\tools\image\yarn\4.0.0-rc.43\bin\yarn.js:134:53714) at de (C:\Users\lukecheng\AppData\Local\Volta\tools\image\yarn\4.0.0-rc.43\bin\yarn.js:204:8076)
问题原因是没有指定 yarn 版本。volta 默认使用最新版的 yarn 来启动项目,导致失败。

解决:
在 package.json 中指定 node 版本的同时,也指定 yarn 版本。
"volta": {
"node": "14.17.0",
"yarn": "1.22.17"
}IOS 不支持的正则表达式
ios 不支持该正则表达式:
productNo.replace(/(?<=.{3}).(?=.{4})/g, '*');否则会报错:
强缓存与协商缓存问题
端外生活缴费应用打包时,会使用 webpack 插件 copy-webpack-plugin 将 node_modules/@bestpay/mpaas-mgs-sdk/mpaas-mgs-sdk 目录下的 gwcli1-1-4.wasm、mgssdk.min.js 文件复制到打包后的 dist/static/mpaas-mgs-sdk 目录下。
在 public/index.html 文件中,添加 script 标签并设置 src 将 mgssdk.min.js 引入:<script type="text/javascript" src="static/mpaas-mgs-sdk/mgssdk.min.js"></script>。
这样进入生活缴费应用时,会去请求资源 mgssdk.min.js。
问题复现:
请求 mgssdk.min.js 时,返回的响应头设置了 Cache-Control: public,must-revalidate,max-age=1296000,这代表该资源会缓存 15 天。这导致上线时,用户浏览器请求 mgssdk.min.js 资源时如果缓存没有过期直接取缓存,而不会去请求服务器获取最新的 mgssdk.min.js。
然后最近依赖包 @bestpay/mpaas-mgs-sdk 进行了升级。升级前的 mgssdk.min.js 引用 gwcli1-2-5.wasm 文件,升级后引用 gwcli1-1-4.wasm 文件。
请求 .wasm 后缀文件资源时,返回的响应头设置了 Cache-Control:must-revalidate,max-age=3600,这代表该资源会缓存 1 小时。
昨晚 10 点发版后,用户访问应用,请求的 mgssdk.min.js 命中缓存,然后去请求 gwcli1-2-5.wasm 文件也命中缓存。此时功能验证无误。1 小时后,gwcli1-2-5.wasm 的缓存失效,去请求服务器。但服务器上只有 gwcli1-1-4.wasm 文件,请求 404,导致 mgs 接口无法调通。
问题解决
在引入 mgssdk.min.js 的资源路径中加入时间戳,这样每次发版后,用户都会请求服务器,拿到最新版本 mgssdk.min.js。
在 vue.config.js 中:
const notCacheDir = `cache-${dateNow()}`
module.exports = {
// ...
configureWebpack: {
plugins: [
new HtmlWebpackPlugin({
env: ENV,
// ============
notCacheDir,
// ============
template: 'public/index.html',
inject: true,
minify: {
caseSensitive: true, //是否大小写敏感
collapseWhitespace: true, //是否去除空格
removeComments: true, //去注释
removeAttributeQuotes: false // 去掉属性引用
}
}),
]
},
chainWebpack: (config) => {
config.resolve.symlinks(true);
config.plugin('copy').use(require('copy-webpack-plugin'), [
[
{
from: 'node_modules/@bestpay/mpaas-mgs-sdk/mpaas-mgs-sdk',
to: path.resolve(__dirname, `./dist/static/${notCacheDir}/mpaas-mgs-sdk`),
ignore: ['.*']
}
]
]);
}
// ...
}然后改造 public/index.html 文件,使用 ejs 语法将 notCacheDir 变量加入到请求 mgssdk.min.js 的资源路径中。
<script type="text/javascript" src="static/<%= htmlWebpackPlugin.options.notCacheDir %>/mpaas-mgs-sdk/mgssdk.min.js"></script>volta 全局下载依赖失败
解决办法:以管理员身份启动 vscode 或命令行窗口。
Promise 捕获不到错误
你觉得高亮行的代码会打印输出吗?答案是不会的。
因为在返回 promise 之前,程序就终止执行了!
function mgsHttp(api, params, options = {}) {
// ...
const { method, operationType } = api;
if (!operationType) {
console.warn('operationType undefined');
return;
}
// ...
// 假设在下面这行出错了
throw new Error('出了某些错误')
return new Promise((resolve) => {
// xxx
// 发请求
});
}
mgsHttp(api, params, options).then(response => {
}).catch(error => {
console.log(error)
})Slot invoked outside of the render function - 解决使用 slot 时遇到的问题
Slot "default" invoked outside of the render function: this will not track dependencies used in the slot. Invoke the slot function inside the render function instead.
最后发现了问题所在:useSlots 返回的 slots 是一个代理对象。
如果像一开始那样写,只是给 isShowIcon 赋了一个初始值。
想要具有响应式,需要放在 computed 计算属性里。
<script setup lang="ts">
import { computed, useSlots } from 'vue';
/** 获取插槽 */
const slots = useSlots()
- // const isShowIcon = !(slots.default && slots.default() && slots.default()[0].children)
+ const isShowIcon = computed(() => {
+ return !(slots.default && slots.default() && slots.default()[0].children)
+ })
</script>
<template>
<button>
<span v-show="isShowIcon">🤩</span>
<slot />
</button>
</template>
<style lang="scss" scoped>
</style>