工作随笔🚀🚀🚀

42 阅读2分钟

image.png

用于记录在工作与学习的过程中,发现的各种开发技巧与解决方案,便于日后再遇到同类问题时能快速查阅到解决方案。

  1. 解决create-react-app 脚手架打包时,运行内存溢出问题的命令 set NODE_OPTIONS=--max_old_space_size=4096&&react-scripts build

  2. 缺少python2.7支持,可快速使用以下语句完成安装 npm install --global --production windows-build-tools

  3. 针对页面指定区域生成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')
  })
}
  1. Mac下最简单翻墙的方法,自动代理配置url:raw.githubusercontent.com/bannedbook/…,

  2. linux 开启端口 /sbin/iptables -I INPUT -p http --dport 3000 -j ACCEPT,查看linux端口状态 netstat -anp

  3. 生成ssh秘钥:ssh-keygen -t rsa -C "any comment can be written here"

  4. jenkins构建失败后自动重新进行构建的插件:Naginator

  5. 解决git拉取代码时报错 gnutls_handshake() failed: The TLS connection was non-properly terminated.: 将代码仓库地址的协议更改为http

  6. 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;
  1. 生成rsa公钥与私钥
  • 打开命令行工具,输入openssl,打开openssl
  • 生成私钥:genrsa -out rsa_private_key.pem 2048
  • 生成公钥: rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
  1. JSON.parse解析换行符\n会报错,需要对目标字符串中\n进行替换: '目标字符串\n'.replace(/\n/g, '\\n')

  2. cursor: url 注意事项

  • 图片大小不能大于32*32
  • 图片格式最好是.cur和.ico
  1. 用于RSA加密的npm包: jsencrypt

  2. webpack构建输出bundle详细信息文件stats.json: 增加--profile --json参数

  3. 可以调整 creat-react-app 脚手架webpack配置项的npm包:@rescripts/cli

  4. 在设置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值,客户端会提示输入密码

  1. webpack报错 Uncaught TypeError: Cannot read property 'bind' of undefined, 直接原因是webpack运行时代码里的webpackJsonppush方法是undefined导致的,根本原因是多个bundle使用了相同的output.jsonpFunction的值,所以只需将其赋值为不一样的值就可以解决了,详见issue

  2. 开发node的CLI工具的项目中,所有依赖项必须是dependencies。如果是devDependencies,那么在全局安装CLI工具时不会自动安装对应依赖

  3. fatal: refusing to merge unrelated histories解决方案: git merge master --allow-unrelated-histories

  4. 软件许可证图例 软件许可证图例

  5. 移动端视口配置 <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">,user-scalable设置为no可以解决移动端点击事件延迟问题

  6. md文档一键转换为微信公众号文章:md.openwrite.cn/?from=didi

  7. eslint删除无用导入的插件:eslint-plugin-unused-imports

  8. 关键字高亮处理方法:

    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;
    };
  1. 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);
  1. 中英文加数字混合排序
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)
  }
}
  1. 给图片添加水印
    (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();
    })()
  1. 当给“图片元素”添加mousemove事件时,需要设置draggable=false,否则会出现mousemove事件不触发的bug

  2. 禁用移动端手势返回

  window.addEventListener('popstate', () => {
    history.pushState(null, '', document.URL)
  })