javascript
# 项目
# 最大的挑战(难点)
# 坑 //
# 痛点与改进 //重构成单页加iframe,eslint编码规范
# 性能优化
封装什么组件?
javascript
低版本浏览器支持?. [].at()等新语法 vue.config.js babel.config.js (耗时半天)
升级core-js最新才支持array.at语法
vue.config.js 中的 transpileDependencies:[去包含'使用了新语法的依赖包']
verdaccio代理npm为什么配置淘宝镜像无效?(耗时1天)
从http请求源头(request库)追踪源码可知,是读取了store中央缓存目录的 包名/package.json 去请求获取包的,它是旧的,删了让它重新被生成即可
exports is not defined(耗时2天)
@antv/g6里的某个子包的语句import xx from '@babel/runtime/xxx'报错
原因: 使用了@babel/plugin-transform-modules-commonjs, webpack把某包作为esmodule去准备解析,
谁知解析的时候代码已经被babel这个插件转换为commonjs语法了
//参考https://github.com/natsu0728/blog/issues/22
解决: 某条import改为require()导入一遍,webpack就记住了
关闭浏览器则重新登录
sessionStorage只属于该标签,并且在浏览器关闭后消失,所以利用它存关闭标志,检测到关闭标志则跳转登录
利用SharedWorker在标签之间同步关闭标志,所有标签不断地向SharedWorker发同步标志(如果存在)
所有标签都接收SharedWorker转发的标志,这样让新打开的标签也同步到标志
https://github.com/CHENJIAMIAN/shared-worker.git
为什么babel的babel-plugin-lodash插件报Cannot read property 'has' of undefined?(耗时8h)
因为其依赖的glob更新后v7.2.0...v7.2.2, common.js加入了options.allowWindowsEscape = true/*始终将模式中的 \ 视为转义,而不是路径分隔符*/
用来匹配分割传入的pattern即 new Minimatch(pattern, options)就分割不到正确路径了
7.2.0
glob的self.minimatch=new Minimatch(pattern, options) //self.minimatch=(7)['D:', 'Desktop', 'bk-saas-frontend-template', 'node_modules', '_lodash@4.17.21@lodash', {…}, '']
options:{ignore: 'D:\\Desktop\\bk-saas-frontend-template\\node_modules\\_lodash@4.17.21@lodash\\node_modules\\**\\', nonegate: true, nocomment: true}
pattern:'D:\\Desktop\\bk-saas-frontend-template\\node_modules\\_lodash@4.17.21@lodash\\**\\'
7.2.2
glob的self.minimatch=new Minimatch(pattern, options) // self.minimatch=(1)[/^(?=.)D:Desktopasdfbk-saas-frontend-templatenode_modules_lodash\\@4\\.17\\.21\\@lodash\\*[^/]*?\\\\$/]
options:{ignore: 'D:\\Desktop\\asdf\\bk-saas-frontend-template\\nod…ules\\_lodash@4.17.21@lodash\\node_modules\\**\\', nonegate: true, nocomment: true, allowWindowsEscape: true}
pattern:'D:\\Desktop\\asdf\\bk-saas-frontend-template\\node_modules\\_lodash@4.17.21@lodash\\**\\'
获取不到node_modules的lodash下的目录了
为什么没有HMR自动刷新? (耗时2天) n
//bk-cli是否可以代替我改造bk的前端? (只有webpack4的版本,也就是多云前端正在用的)
//原生的master有吗? 是不是被我改坏了? (master也没有!)
// 禁用hot以启用liveReload也不行
自己搞一个webpack最精简版去调试,暂时找不出原因, 先手动刷新吧
resolve: { symlinks: false, }, //造成hot失败
//https://cli.vuejs.org/guide/troubleshooting.html#symbolic-links-in-node-modules
//Disabling resolve.symlinks may break hot module reloading if your dependencies are installed by third-party npm clients that utilized symbolic links, such ascnpm or pnpm.
axios 302 get 异步, 造成CORS没有成功跳转 2022年4月25日
深入源码, adapter的onerror发现注释
// 处理低级网络错误, 真正的错误被浏览器隐藏起来,只有浏览器网络错误时,onerror才应该触发
Ajax 不能处理 302 状态码的响应,这个行为是浏览器的默认行为, 改成401给我
table tag联动问题, 父子都维护自己的selected
子组件自己维护一个selected,它在显示的时候跟父传进来的同步, 关闭的时候一下更新父组件的selected
子组件自己内部tag跟table选择联动, 关闭tag跟点击取消选择联动, 统一让点击取消选择去处理
升级框架,改用webpack5,40s->10
lint-staged基于 husky,用来在 git 暂存文件上筛选运行命令, 如可筛选完运行格式化命令//husky能够让开发者使用 git hook 的操作。
//Husky 支持所有 Git 钩子. git支持17个hooks
husky 原理
npx husky install时
git config core.hooksPath 配置到 .husky,这样在 git commit 前就会触发 .husky/pre-commit,
从而执行里面的脚本(由npx husky add .husky/pre-commit "npx lint-staged"生成)
为了让其他人在此项目中安装依赖后也能自动创建.husky目录并指定该目录为 git hooks 所在的目录,
我们需要在 package.json 里面添加一条脚本"prepare": "husky install"
prepare 脚本会在 npm i或者其他yarn or yarn add 之后自动执行。也就是说当我们安装依赖后会自动执行 husky install 命令,从而自动创建.husky目录并指定该目录为 git hooks 所在的目录。
实现路由的自动注册
const requireComponent = require.context(目录,递归,正则)//获取路径们
requireComponent.keys()//获得路径们
requireComponent(路径).default //获取文件的模块导出
表单分步验证
表单验证方法回调用每个表单项自己的验证方法, 在rules加一个step标识, 复用重写表单validate方法,
for (const form-item实例 of 筛选后的form-item实例们)
form-item实例.validate()
两个radio-group互相影响:
radio以name相同的为一组,而组件源码里name根据时间戳生成,太快了可能会生成相同的时间戳
name: {
type: [String, Number],
default () {
let seed = 0; const now = Date.now(); return `bk_radio_${now}_${seed++}`;
}
}
深度监听对象属性, 新旧值相同
在变更(不是替换)对象或数组时,旧值将与新值相同,因为它们的引用指向同一 个对象/数组。Vue 不会保留变更之前值的副本。
解决: computed监听复制一份该对象, 再watch复制的对象即可,因为每次变化都会被复制一份,所以每次是不同的引用,能达到对比的目的
魔改组件库表组件以全局支持cell数据为空时, 自动默认值, 原理是改组件方法添加默认的formatter
bkMagicVue.bkTable.computed.columns = function () {
this.store.states.columns.forEach((i) => {
if (!i.formatter) {
i.formatter = (row, column, cellValue, index) => {
return [null, "", undefined].includes(cellValue) ? "--" : cellValue;
};
}
});
return this.store.states.columns;
};
Threejs 解决outlinepass边缘发光被遮挡, unrealbloom辉光效果变黑 的难题
1.outlinepass会被前面的机柜遮挡解决:
利用片段着色器原理, 这个自写一个片段着色器添加到ShaderPass来解决,
原理:黑色与黑色相叠加(相乘)什么都没有改变,所以要互不影响的物体如机柜/辉光等就都要变黑,
供ShaderPass使用的bloomComposer的renderToScreen要设为false不渲染到屏幕,
然后bloomComposer.render()一下, ShaderPass就可以从bloomComposer拿到它的bloomTexture
const finalPass = new ShaderPass(
new THREE.ShaderMaterial({
uniforms: {
baseTexture: { value: null },
bloomTexture: { value: bloomComposer.renderTarget2.texture, },
},
vertexShader: composer_topbloomtexture_vertex,
fragmentShader: composer_topbloomtexture_fragment,
//gl_FragColor = texture2D( baseTexture, vUv ) + texture2D( bloomTexture, vUv ) ;
defines: {},
}),
'baseTexture'
);
2.因为pass共存机柜变得更亮或特效发黑的问题
机柜变得更亮解决: outlinepass发光的物体本身也要变黑,不然亮*亮=更亮
特效发黑的解决: 使物体变黑时要排除特效物体, 排除前特效物体的黑*半透明 = 半透明带点黑, 排除后半透明*半透明=更炫酷
为什么push后嵌套路由的上一级组件会重载? 不是会复用的吗?
问题: 进入嵌套路由下的表格|列表-> 路由改变-> 父组件重载
正常应该会复用, 不要优先怀疑是vue的bug, 所以可能是我加了什么造成$route变,组件也变,最后发现是router-view上加了:key="route.path"
生成骨架屏, 自动根据页面的接口的isLoading的变化显示隐藏
DFS vm.$children
DFS vm._vnode.children
vnode.data?.directives找出bkloading的key名, vm[key名]取值, 只有大于0个true则loadingFLAG为true
axios取消请求, 自动取消上个类似请求(每个请求搞一个根据请求方法路径参数生成的id, 搞一个队列存放, 进来相似的就取消上一个)
1.最新:
axios.get('/user/12345', {
signal: controller.signal
}).catch((thrown)=>{ if (axios.isCancel(thrown)) });
controller.abort(); // the message parameter is not supported
2.或
axios.get('/user/12345', {
cancelToken: new axios.CancelToken((excutor) => {
cancelExcutor = excutor;
})
});
cancelExcutor()//取消
3.或
const source = axios.CancelToken.source()
axios.get('/user/12345', {
cancelToken: source.token,
});
source.cancel('Operation canceled by the user.');