[Оптимизация] не забудьте один раз уменьшить конфликт с помощью инструмента Git

внешний интерфейс
[Оптимизация] не забудьте один раз уменьшить конфликт с помощью инструмента Git

причина

По мере того, как наш проект становится все больше и больше,GitКонфликт — очень раздражающая вещь в командной работе, это не только пустая трата времени, но и решение проблем, когда возникают конфликты.

Что я могу придумать, так это подразделение модулей, и каждый отвечает за свои собственные связанные модули, чтобы код между разработчиками не влиял друг на друга, и не было конфликта кода. Но общие модули кода в совместных проектах с несколькими людьми необходимы, например, наши общие общедоступные файлы переменных.constant.js, и большинство конфликтов происходит из-за этого.

На основании,LeaderБыло предложено другое решение -Контролируйте порядок написания кода

Почему это важный заказ

Для этой проблемы мы должны сначала понять, почему возникает конфликт кода?

Потому что мы изменили одну и ту же строку кода в одном и том же файле.

Например, у нас есть следующие определения констант:

export const Employees = {
  Andy: 'I can sing',
  Oliver: 'I can run',
  Ivan: 'I can rap'
};

Мы с коллегой А собираемся пересесть наEmployeesЭта константа, добавляет онBrad: 'I am Brad', Я добавилPatrick: 'I am Patrick', мы все добавляем его в конец переменной, что вызовет конфликт, подобный следующему

@@@ -1,4 -1,4 +1,8 @@@
  Andy: 'I can sing',
  Oliver: 'I can run',
  Ivan: 'I can rap',
  <<<<<<< HEAD
 +Brad: 'I am Brad',
  =======
+ Patrick: I am Patrick,
  >>>>>>>

Но что, если бы мы оба были в порядке?

Во-первых, порядок файлов после настройки следующий:

export const Employees = {
  Andy: 'I can sing',
  Ivan: 'I can rap',
  Oliver: 'I can run'
};

Коллега А добавляет следующий код:

export const Employees = {
  Andy: 'I can sing',
+ Brad: 'I am Brad',
  Ivan: 'I can rap',
  Oliver: 'I can run'
};

Я добавляю код следующим образом:

export const Employees = {
  Andy: 'I can sing',
  Ivan: 'I can rap',
  Oliver: 'I can run',
+ Patrick: 'I am Patrick'
};

В это время, когда мы комбинируем код, нет конфликта

Сортировать по инструменту

Зная важность порядка для нас, чтобы избежать разрешения конфликтов, следующим шагом будет выполнение.Очевидно, что неразумно просить коллег всегда следовать порядку написания кода.Мы планируем использовать инструменты для выполнения.

Конкретные шаги заключаются в следующем:

vue-cliДемо

Сроки — предварительная фиксация:существуетgit commitПрежде чем вы сможете использоватьgit hooksсделай это

Добавьте следующий код в package.json, что означает, что вgit commitбудет выполнен раньшеnode ./auto-fix/index.jsтак же какgit addЗаказ

  "lint-staged": {
    "*.{js}": [
      "node ./auto-fix/index.js",
      "git add"
    ]
  },
  "gitHooks": {
    "pre-commit": "lint-staged"
  },

Если вы обнаружите, что триггера нет, вы можете увидеть, нет ли двух пакетовlint-stagedа такжеyorkie. Вы можете установить его следующим образом:

npm i lint-staged --save-dev
npm i yorkie --save-dev  

вyorkieДа ты да народhusky, у них одинаковая функция, оба генерируют некоторыеgit hooksфайл, читать в проектеpackage.json

: найти файлы в указанном каталоге (следующий примерsrc/constantдиректории), сопоставьте объекты в файле и отсортируйте объекты

Стратегия сортировки здесь заключается в том, чтобы сначалаvalueЗначения сортируются, еслиvalueТо же значение, то дляkeyПорядок значений

записывать: Запишите отсортированный файл обратно в исходный файл.

намекать: Индикация успеха или неудачи

Конкретные практики и коды, создание новых файловauto-fix/index.js, код показан ниже:

const fs = require('fs');
const path = require('path');
const chalk = require('chalk');

function resolve(p) {
  return path.join(__dirname, '..', p);
}

const objRegex = /\{[^}\/\/]*\}/g;

function fileDisplay(filePath) {
  let file = resolve(filePath);
  let fileList = fs.readdirSync(file, 'utf8');

  function compare() {
    return function ([key1, value1],[key2, value2]) {
      key1 = Number.isNaN(Number(key1)) ? key1.toLowerCase() : key1;
      key2 = Number.isNaN(Number(key2)) ? key2.toLowerCase() : key2;
      value1 = Number.isNaN(Number(value1)) ? value1.toLowerCase() : value1;
      value2 = Number.isNaN(Number(value2)) ? value2.toLowerCase() : value2;
      if (value1 === value2) {
        return key1 < key2 ? -1 : key1 > key2 ? 1 : 0; // 升序
      } else {
        return value1 < value2 ? -1 : value1 > value2 ? 1 : 0;
      }
    }
  }

  // 读取文件
  fileList.forEach(filename => {
    let fileDir = path.join(filePath, filename);
    console.log(chalk.cyan(`Auto fix ${fileDir}`))
    let fileContents = fs.readFileSync(fileDir, 'utf8');

    function sortObj(item) {
      item = item.replace(/(\S+):/g,"\"$1\":")
      .replace(/'/g, '"');

      let arr = [];
      item = JSON.parse(item);
      arr = Object.entries(item);
      // 排序
      arr = arr.sort(compare());
      let tempObj = {};
      // 将排序好的数组拼接成对象
      tempObj = arr.reduce((_sortedObj, [key, val]) => ({
        ..._sortedObj,
        [key]: val
      }), {});
      let tempStr = JSON.stringify(tempObj, null, 2);
      // 去掉 key 值的双引号
      tempStr = tempStr.replace(/"/g, "").replace(/\: /g,"\: \'").replace(/\,/g,"\'\,").replace(/\n\}/g,"\'\n\}");
      return tempStr;
    }

    // 匹配对象并排序并替换
    fileContents = fileContents.replace(objRegex, function(match) {
      return sortObj(match)
    });

    // 输出到文件中
    fs.writeFileSync(fileDir, fileContents, 'utf8');
  });

}
try {
  fileDisplay('src/constant');
  console.log(chalk.green(`Auto fix complete`))
} catch (e) {
  console.log(e);
  console.log(chalk.red(`Auto fix Error, You can check the the problem in the auto-fix/index.js directory`))
  throw new Error(`Auto fix Error, You can check the the problem in the auto-fix/index.js directory`)
}

результат

Gifgit commitон автоматически сортируется

Но на самом деле я понимаю, что это "неупорядоченное" относится к порядку, в котором атрибуты не расположены до и после.Сам обход атрибутов объекта имеет свой собственный набор правил.

можно экспериментировать

let obj = { [Symbol()]:0, b:0, 10:0, 2:0, a:0 };
// for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)
// 输出 2 10 b a
for (let key in obj) {
  console.log(key)
}
// Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
// [ '2', '10', 'b', 'a' ]
console.log(Object.keys(obj));

// Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
// [ '2', '10', 'b', 'a' ]
console.log(Object.getOwnPropertyNames(obj));

// Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
// [ Symbol() ]
console.log(Object.getOwnPropertySymbols(obj));

// Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
// [ '2', '10', 'b', 'a', Symbol() ]
console.log(Reflect.ownKeys(obj));

Из приведенных экспериментов вывод следующий:

  • Сначала переберите все числовые ключи и отсортируйте их в порядке возрастания.
  • Затем перебираем все строковые ключи и сортируем их в порядке возрастания по времени соединения.
  • Наконец, пройдите все ключи символов и отсортируйте их в порядке возрастания по времени соединения.

Ретроспективная реализация - аналогичная проблема

В приведенной выше реализации я сначала основывался на атрибутеvalueзначения сортируются, еслиvalueЗначения одинаковы тогдаkeyПорядок значений. После сортировки получается упорядоченный двумерный массив, подобный следующему:

[["Andy","I am Andy"],["Gopal","I am Gopal"],["Ivan","I am Ivan"],["Oliver","I am Oliver"],["Patrick","I am Patrick"]]

Потом пройтись по массиву и записать его в объект по очереди, так вроде проблем нет, и результат не проблема! Но если ключевое значениеnumberЧто насчет типа? Например что-то вроде этого:

export const Employees = {
  Andy: 'I am Andy',
  Gopal: 'I am Gopal',
  Ivan: 'I am Ivan',
  1: 'Z',
  2: 'A',
  3: 'J',
  Oliver: 'I am Oliver',
  Patrick: 'I am Patrick'
};

Как и ожидалось, отсортировав по значению, вы должны получить

export const Employees = {
  2: 'A',
  Andy: 'I am Andy',
  Gopal: 'I am Gopal',
  Ivan: 'I am Ivan',
  Oliver: 'I am Oliver',
  Patrick: 'I am Patrick'
  3: 'J',
  1: 'Z'
};

Но на самом деле мы получаем результаты, похожие на следующие:

export const Employees = {
  1: 'Z',
  2: 'A',
  3: 'J',
  Andy: 'I am Andy',
  Gopal: 'I am Gopal',
  Ivan: 'I am Ivan',
  Oliver: 'I am Oliver',
  Patrick: 'I am Patrick'
};

На самом деле это связано с правилами обхода атрибутов, о которых мы упоминали выше, потому что сначала обходят все числовые ключи в порядке возрастания номеров. Затем переберите все строковые ключи и отсортируйте их в порядке возрастания по времени соединения.

недостаток

В дополнение к упомянутой выше проблеме с порядком атрибутов [это на самом деле хорошо, он сортируется по определенным правилам], если вы внимательно прочитаете приведенный выше код, вы на самом деле обнаружите некоторые проблемы, которые можно рассматривать как некоторыеTODOПункт, если друг решает, пожалуйста, дайте мне предложениеpr

Функционально:

  • В настоящее время только полезные объекты для простых объектов, вложенные объекты недействительны

разное:

Суммировать

Используя запись бумагиgit hooksПрежде чем отправлять код в связанную сортировку кода, тем самым снижая конфликт, когда код вместе, но и немного изучитьJsПроблема обхода свойств свойств объектов, надеюсь, вдохновит всех.

ВовлеченныйdemoпомещатьGithub, есть идеи получшеPRкакие

Оригинальность не так проста, ставьте лайки и комментируйте~

Рекомендуемые отличные статьи в прошлом

Ссылаться на