用于记录在工作与学习的过程中,发现的各种开发技巧与解决方案,便于日后再遇到同类问题时能快速查阅到解决方案。
-
解决create-react-app 脚手架打包时,运行内存溢出问题的命令
set NODE_OPTIONS=--max_old_space_size=4096&&react-scripts build
-
缺少python2.7支持,可快速使用以下语句完成安装
npm install --global --production windows-build-tools
-
针对页面指定区域生成pdf文件的方法
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
import Canvg from 'canvg'
/*
利用Canvg导出页面指定区域为PDF格式
*/
export const getPdfByCanvg = (title, container) => {
return new Promise(async(resolve, reject)=>{
try {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
canvas.setAttribute('width', '8000px')
canvas.setAttribute('height', '1500px')
canvas.setAttribute('position', 'fixed')
canvas.setAttribute('top', '99999999px')
document.body.appendChild(canvas)
/*
由于canvg库不支持filter属性,如果加上,矩形和圆形的描边或者填充都失效,所以在转换之前先将filter去掉,使用stroke代替
*/
let rectArr = Array.from(container.getElementsByTagName('rect'))
rectArr.forEach(item=>{
item.setAttribute('stroke', '#ccc')
item.removeAttribute('filter')
})
let rootCircle = container.getElementsByTagName('circle')[0]
rootCircle.setAttribute('stroke', '#ccc')
rootCircle.removeAttribute('filter')
let v = await Canvg.from(ctx, `<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><rect fill="white" stroke="none" width="${container.clientWidth}" height="${container.clientHeight}" pointer-events="all"></rect>${container.innerHTML.trim()}</svg>`, {
offsetX: 3000
})
await v.render()
let a = document.createElement('a')
a.style.display = 'none'
let contentWidth = 8000
let contentHeight = 1500
let pageHeight = contentWidth / 592.28 * 841.89
let leftHeight = contentHeight
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/png', 1.0)
let PDF = new JsPDF('', 'pt', 'a4')
if (leftHeight < pageHeight) {
PDF.addImage(canvas, 'PNG', 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(canvas, 'PNG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
PDF.save(title + '.pdf')
document.body.removeChild(canvas)
resolve()
} catch (err){
reject(err)
} finally {
/*
还原矩形与圆形的样式
*/
let rectArr = Array.from(container.getElementsByTagName('rect'))
let rootCircle = container.getElementsByTagName('circle')[0]
rectArr.forEach(item=>{
item.setAttribute('stroke', 'none')
item.setAttribute('filter', 'drop-shadow(0px 5px 5px rgba(0,0,0,0.1))')
})
rootCircle.setAttribute('stroke', 'none')
rootCircle.setAttribute('filter', 'drop-shadow(0px 5px 5px rgba(0,0,0,0.1))')
}
})
}
/*
利用html2canvas导出页面指定区域为PDF格式
*/
export const getPdfByHtml2canvas = (title, container) => {
return html2Canvas(container, {
allowTaint: true,
width: 8000,
height: 1500,
x: 3000
}).then(canvas=>{
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 592.28 * 841.89
let leftHeight = contentHeight
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)
let PDF = new JsPDF('', 'pt', 'a4')
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
PDF.save(title + '.pdf')
})
}
-
Mac下最简单翻墙的方法,自动代理配置url:raw.githubusercontent.com/bannedbook/…,
-
linux 开启端口
/sbin/iptables -I INPUT -p http --dport 3000 -j ACCEPT
,查看linux端口状态netstat -anp
-
生成ssh秘钥:ssh-keygen -t rsa -C "any comment can be written here"
-
jenkins构建失败后自动重新进行构建的插件:Naginator
-
解决git拉取代码时报错
gnutls_handshake() failed: The TLS connection was non-properly terminated.
: 将代码仓库地址的协议更改为http -
node.js连接mysql出现错误:
ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
解决方案:
ALTER USER '用户名' IDENTIFIED WITH mysql_native_password BY '密码';
FLUSH PRIVILEGES;
- 生成rsa公钥与私钥
- 打开命令行工具,输入openssl,打开openssl
- 生成私钥:
genrsa -out rsa_private_key.pem 2048
- 生成公钥:
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
-
JSON.parse解析换行符\n会报错,需要对目标字符串中\n进行替换:
'目标字符串\n'.replace(/\n/g, '\\n')
-
cursor: url 注意事项
- 图片大小不能大于32*32
- 图片格式最好是.cur和.ico
-
用于RSA加密的npm包: jsencrypt
-
webpack构建输出bundle详细信息文件stats.json: 增加
--profile --json
参数 -
可以调整 creat-react-app 脚手架webpack配置项的npm包:@rescripts/cli
-
在设置webpack运行时publicPath时,报错
'__webpack_public_path__' is not defined no-undef
,原因是 ESLint规则警告有关使用未声明的变量,需要告诉ESLint __webpack_public_path__是全局变量。,解决方案有三种:
- 在使用 webpack_public_path 的地方加上注释:
/* global __webpack_public_path__:writable */
- 直接在使用 webpack_public_path 的地方加上注释: //eslint-disable-next-line 或 //eslint-disable-line
- 配置eslint
{
"globals": {
"__webpack_public_path__": "writable"
}
}
17. 客户端连接mysql服务的两种方式:
- mysql --host=localhost --user=myname --password=password mydb
- mysql -h localhost -u myname -ppassword mydb
需要注意如果明确指定了-p或者--password的值,那么-p或者--password和密码之间是不能有空格的,如果你使用了-p或者--password选项但是没有给出password值,客户端会提示输入密码
-
webpack报错
Uncaught TypeError: Cannot read property 'bind' of undefined
, 直接原因是webpack运行时代码里的webpackJsonp
的push
方法是undefined
导致的,根本原因是多个bundle使用了相同的output.jsonpFunction
的值,所以只需将其赋值为不一样的值就可以解决了,详见issue -
开发node的CLI工具的项目中,所有依赖项必须是dependencies。如果是devDependencies,那么在全局安装CLI工具时不会自动安装对应依赖
-
fatal: refusing to merge unrelated histories
解决方案:git merge master --allow-unrelated-histories
-
软件许可证图例
-
移动端视口配置
<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
,user-scalable设置为no可以解决移动端点击事件延迟问题 -
md文档一键转换为微信公众号文章:md.openwrite.cn/?from=didi
-
eslint删除无用导入的插件:eslint-plugin-unused-imports
-
关键字高亮处理方法:
const highlightKeyWord = (text, keyword) => {
return keyword
? text.split(new RegExp(`(${keyword})`, 'gi')).map((c, i) =>
c === keyword ? (
<span key={i} style={{ color: '#009ba5' }}>
{c}
</span>
) : (
c
)
)
: text;
};
- js复制文本方法
//方法1
await navigator.clipboard.writeText('some text');
//方法2
const input = document.createElement('input');
input.setAttribute('value','some text');
document.body.appendChild(input);
input.select();
document.execCommand('copy');
document.body.removeChild(input);
- 中英文加数字混合排序
export function mixSort(_a, _b) {
const reg = /[a-zA-Z0-9]/
// 比对仅针对字符串,数字参与对比会导致对比的字符串转为number类型,变成NaN
const a = _a.toString()
const b = _b.toString()
// 比对0号位的原因是字符串中有可能出现中英文混合的情况,这种仅按首位排序即可
if (reg.test(a[0]) || reg.test(b[0])) {
if (a > b) {
return 1
} else if (a < b) {
return -1
} else {
return 0
}
} else {
return a.localeCompare(b)
}
}
- 给图片添加水印
(async ()=>{
const genWaterMark = async (imgSrc: string) => {
const canvas = document.createElement('canvas');
// ① 图片路径转成canvas
await imgSrc2Canvas(canvas, imgSrc);
// ② canvas添加水印
addWatermark(canvas);
// ③ canvas转成img
return canvas.toDataURL('image/png');
};
const addWatermark = async canvas => {
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(100,100,100,0.2)'; // 字体颜色
ctx.font = `24px serif`;
ctx.translate(0, 0);
ctx.rotate((5 * Math.PI) / 180); // 旋转角度
const repeatX = Math.floor((canvas.width / 24) * 4); // 100 为每个水印的基本宽度
const repeatY = Math.floor((canvas.height / 24) * 4);
for (let i = 0; i < repeatX; i++) {
for (let j = 1; j < repeatY; j++) {
ctx.fillText(`哈哈哈哈`, 24 * 4 * i + 20, 24 * j + 20); // 控制水印的疏密
}
}
};
const imgSrc2Canvas = (cav: HTMLCanvasElement, imgSrc: string) => {
return new Promise(async resolve => {
const image = new Image();
image.src = imgSrc;
// ① 为图片设置crossOrigin属性,防止Failed to execute 'toDataURL' on 'HTMLCanvasElement'
image.setAttribute('crossOrigin', 'anonymous');
// ② 解决渲染图片为透明图层
await new Promise(resolve => (image.onload = resolve));
cav.width = image.width;
cav.height = image.height;
const ctx = cav.getContext('2d');
if (ctx) {
ctx.drawImage(image, 0, 0);
}
resolve(cav);
});
};
const link = document.createElement('a');
link.download = `pic.png`;
const url = await genWaterMark(dataUrl);
link.href = url;
link.click();
})()
-
当给“图片元素”添加mousemove事件时,需要设置draggable=false,否则会出现mousemove事件不触发的bug
-
禁用移动端手势返回
window.addEventListener('popstate', () => {
history.pushState(null, '', document.URL)
})