jsx的花括号换行不友好

626 阅读1分钟

我在写个pre-commit hook,将不允许在jsx元素属性上写花括号换行的方法体
比如下面这种就非常影响阅读,一旦业务代码增多时,是不可接受的

<Button onClick={() => {
    // do something...
}}/>

应该把多行的方法声明在js区域
jsx的情况,让我想到了曾经jsp里的<=%%>

问题小计:
另外ts中的泛型后面也是很可能会跟花括号然后换行的
有一些对象声明确实想花括号换行\

开发两个月后:
我发现实际上类型推断丢失的问题不是很大,绝大多数情况下,方法的入参都应该先定义好,而不需要靠prop来自动提取\

update一下之前写的 还带行数颜色高亮 但上面两个小问题没解决 生产是不可能用的了

const { readdir, stat, readFile } = require('fs/promises');
const { exit } = require('process');
const colors = require( "colors")
const path = require('path');

const src = path.resolve('./src');
let errCount = 0;
let filesCount = 0;
checkTSX(src).then(() => { // 扫描src下所有tsx文件
  console.log(errCount ? 
    `❌ ${errCount} errors of ${filesCount} files: should not new line after '{' at not closed element` : 
    `✅ all files cleaned`);
  if (errCount) exit(1);
});

function checkTSX(dir) {
  return readdir(dir).then(files => {
    const filesPromise = files.map(fileName => {
      const fileDir = path.join(dir, fileName);
      return stat(fileDir).then(stats => {
        if (stats.isDirectory() && !fileName.startsWith('.')) {
          return checkTSX(fileDir);
        } else if (stats.isFile() && ['jsx', 'tsx'].find(type => fileName.endsWith(type))) {
          return readFile(fileDir).then(data => {
            const errLines = findErrLine(data.toString());
            errLines.length && ++filesCount && console.log(fileDir.blue, 
              `\nlines at: ${errLines.map(err => ++errCount && err.line)}`.yellow
            );
          });
        }
      });
    })
    return Promise.allSettled(filesPromise);
  })
}

/**
 * 未闭合的元素标签,禁止或括号换行
 * 忽略箭头函数=>的 '>'
 * 忽略props传入组件<Xxx/>时的换行
 * todo: 忽略注释 忽略泛型
 * @param {*} content 
 */
function findErrLine(content) {
  const lines = [...content.matchAll(/\n/g)]; // 获取文件行数信息
  // <之后不许出现>且忽略=> 匹配到{后发现换行 且忽略组件的<开头
  // 咳咳,过了两个月来看,感觉不怎么可靠的样子
  const errors = [...content.matchAll(/(?<=<([^>]|=>)*){[^\n{}]*\n(?!\s*<)/g)];
  errors.forEach(err => {
    lines.find((line, index) => line.index > err.index && (err.line = index + 1));
  });
  return errors;
}