健忘的秃头青年,记录一下平时遇到的跳坑&爬坑
求生环境: vue+electron
UI
在vue中引入jsoneditor
npm install jsoneditor --save
npm install
在main.js中
import jsoneditor from 'jsoneditor'
Vue.prototype.$jsoneditor = jsoneditor
以上是各网站给的导入方法,但是页面上会变成:
所以一定要引入css文件
import 'jsoneditor/dist/jsoneditor.css'
但这时候可能svg不兼容,出现错误Error: No mime type for file with extension svgsupported,所以在webpack.base.conf.js中需要加入
{
test: /\.svg$/,
loader: 'file-loader',
}
vue-material
md-select使用时报错
[MdOption] Cannot read property 'trim' of undefined
当md-option内包含element而非字符串时,将报错
"TypeError: Cannot read property 'trim' of undefined"
在VUE文件中,当不得不在md-option中加element时,可以采用增加 的方法来work aroud。
当配合vue-form-json-schema时,则需要增加一个children在element之前:
mdSelectChildren.push({
component: 'md-option',
children: ['add an empty element to avoid trim() error', {
component: 'span',
fieldOptions: {
domProps: { innerHTML: _value }
}
}],
fieldOptions: {
props: { value: _value }
}
})
但是!这时候可能会导致,第一次获取ui schema的时候,value的值未绑定!
如上图,可以看到,当把值显示到label时,其实值是正确的(蓝圈内),但值并没有被正确绑定,所以该域显示为空。一旦再次获取ui schema,将绑定。
- workaround:
在opened中,重复一次
process.nextTick(() => {
this.updateUISchema()
})
JS
class中method之间互相调用
直接用this
class A{
B(){
this.C();
}
C(){
}
}
将object转换为带换行的json
JSON.stringify()方法可以传三个参数。(value[, replacer[, space]])
JSON.stringify(obj, null, 2);
http
got+FormData
- vue有自带FormData:
但是使用got发送时,必须使用npm的FormData:
const FormData = require('form-data');
- header 设置为formData.getHeaders()
let formHeaders = uploadData.getHeaders();
let options = {
headers: {
...formHeaders,
},
body: uploadData
};
- 增加上传的附件
uploadData.append('keyForJson', JSON.stringify(data));
uploadData.append('keyForFile', fs.createReadStream(filePath));
got 拦截已发送的request
let request = got(requestUrl, options);
request.then((res)=>{
resolve(res);
},(err) => {
if (request.isCanceled){
err = 'User canceled...'
}
reject(err)
});
在其他funtion中
request.cancel();
正则
判断字符串是否全英文
if (/[^ -~]+/.test(string)) {
// Contains non-English letters
}
if (/[ -~]+/.test(string)) {
// All English letters
}
分解文件名及后缀
fileName = "test.json".match(/(.*)\.[^.]+/)[1];
fileName[0]: "test.json"
fileName[1]: "test"
截取指定字符串中间的内容(数字)
let err = error.match(/(?<=statusCode *)\d+/);
statusCode 502 bad gateway -> 502
截取<li></li>中间的内容
bulletsReg = /[^><]+(?=<\/li>)/g
获取<a>里面的href
linkReg = /(?<=href=" *).+?(?=")/g
配置
vue-electron with cli2
antd-vue
配置主题色
// webpack.config.js
module.exports = {
rules: [{
test: /\.less$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader', // translates CSS into CommonJS
}, {
loader: 'less-loader', // compiles Less to CSS
options: { // using less-loader@5
modifyVars: {
'primary-color': '#1DA57A',
'link-color': '#1DA57A'
},
javascriptEnabled: true,
}
}],
// ...other rules
}],
// ...other config
}
不生效,需要将引入的antd样式改为Less格式
ant-design-vue/dist/antd.less
此时报错
Error evaluating function `unit`: the first argument to unit must be a number......
修改less的版本到3以下"less": "^2.7.3"
build
即使在管理员模式下,依然permission denied
报错:
Error: EPERM: operation not permitted, open 'C:\...\build\builder-effective-config.yaml'
在文件夹内找到该文件,修改Read-only unchecked!
打包好后无法运行
报错:
A JavaScript error occurred in the main process
确认package.json中
"pack": "npm run pack:main && npm run pack:renderer",
"pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js",
"pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js",
所以正确的顺序是先运行npm run pack,生成main.js和render.js和index.html之后,再运行npm run build。
在package.json中配置:
"main": "dist/electron/main.js"
pack失败卡住
报错:
92% chunk asset optimization BabelMinifyPlugin
反正app不打算外传,取消这个压缩plugin
在webpack.renderer.config.js里,注释掉
// const MinifyPlugin = require("babel-minify-webpack-plugin")
// new MinifyPlugin({
// parallel: false
// }),
build开始时会清除dist下的main.js文件
报错:
Error: Application entry file "dist\electron\main.js" in the "C:\...\build\win-unpacked\resources\app.asar" does not exist. Seems like a wrong configuration.
修改build.js中的
del.sync(['dist/electron/*', '!.gitkeep'])
改为
del.sync(['!.gitkeep'])
unit test
vue + jest
circular reference error
Test suite failed to run
...
SyntaxError: Unexpected token '.'
...
350 | import stringUtils from '../utils/stringUtils.js'
看起来就像没有配置babel一样,但实际上只是error message相同,root cause不同。 这里的root cause是因为在vuex的.js文件中,import了router,进行了route的修改。这是不正确的。 应该直接在.vue文件中使用this.$route
测试vuex的情况
import Vuex from 'vuex'
import { cloneDeep } from 'lodash'
const localVue = createLocalVue()
localVue.use(Vuex)
const store = new Vuex.Store({
modules: {
DBdata: {
...cloneDeep(DBdata), namespaced: true
}
}
})
wrapper = mount(VUEfile, { store, localVue })
测试带module的vuex
预设mock的store
getters = {
titleLocal: () => 'title local',
}
报错:[vuex] unknown getter: schemaUI/titleLocal
应该使用:
'schemaUI/titleLocal': () => 'title local',
测试vue-router的变化情况
如果不需要测试变化,只需要取值,可以采用mock方法 如果需要测试变化,则需要引入router
import VueRouter from 'vue-router'
const localVue = createLocalVue()
localVue.use(VueRouter)
const router = new VueRouter()
wrapper = mount(VUEfile, { localVue, router })
测试页面初始route:
在beforeAll()中加入:
router.push({
query: {
product: 'switch'
}
})
断言中途route情况:
expect(router.history.current.query.tab).toBe('components')
测试window.bus
main.js
...
window.bus = new Vue()
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
xx.test.js
beforeAll (() => {
...
window.bus = new Vue()
...
wrapper = shallowMount(products, { store, localVue, router })
}
eslint
创建自定义规则
因为项目中期才加入vuex的strict mode,所以出现了很多error。如在mutation以外的地方修改了state,且只有run time的时候才会检查出来。这导致在开发过程在经常被这个error闪退。
现在需要加入一个eslint规则,帮助筛查出所有mutation以外修改state的地方。
需要以下几个步骤:
-
创建自定义规则插件
参考# Writing your own ESLint Plugins
在Main的父目录,创建文件夹/customEslintRule
2. 编写自定义规则
借助AST,编写rule。
官网:规则结构
辅助工具:AST Explorer
我瞎写了一个,但这个只能静态检查在actions里头是否有修改state变量,可用场景非常局限。
create: function(context) {
return {
VariableDeclarator(node) {
if (node.id.name === 'actions') {
node.init.properties.forEach((fnNode) => {
const findAssignmentExpression = function(node) {
if (node.body && Array.isArray(node.body)) {
node.body.forEach((bodyNode) => findAssignmentExpression(bodyNode))
}
if (node.type === 'ExpressionStatement') {
const expressNode = node.expression
if (expressNode && expressNode.left &&
expressNode.left.type === 'MemberExpression' &&
expressNode.left.object.name === 'state') {
context.report({
node: expressNode,
message: `Do not mutate Vuex store state outside mutation handlers.`,
});
}
}
}
return findAssignmentExpression(fnNode.value.body)
});
}
}
};
},
3. 链接本地插件
在/customEslintRule文件夹下,运行`sudo npm link`
在/Main文件夹下,运行`sudo npm link eslint-plugin-vuex-mutation`
4. 配置eslint文件
在.eslintrc.js文件里,加入:
'plugins': [vuex-mutation]' -> plugin ID
'rules': {
'vuex-mutation/vuex-mutation-id': 2 -> plugin ID / rule ID
}
5. 运行 npm run lint