リファクタリングコード


ソー!過去数週間、コース内の他の学生の助けを借りて、私の静的サイトジェネレータプログラムは非常に機能的になっているが、それはまた、サイズで成長しており、私は間違いなく“技術的な負債”であった.コードベースをリファクタリングするのに時間がかかった.
私はたくさんのカバーを持っているので

コードリファクタリング

以下は、私が私の「技術的な負債」を返済するために取ったステップです

ファイルパス処理を' path 'モジュールに変更する
どんなファイルパスに関連している私の操作の大部分は、例えば正規表現や文字列関数を使って行われました.
else if(stat.isFile() && filePath.split('.').pop() == "txt") {
    createHtmlFiles(filePath, "txt");
//... 
const fullFilePath = `${outputPath}/${filePath.match(/([^\/]+$)/g)[0].split('.')[0]}.html`; 
彼らは非常に読みやすい、特にすべての正規表現を見ていない.他のコードを操作した後、私は以前にも使っていた' path 'モジュールを使用していることがわかりました.下記の変更の一部は、彼らは何を達成しようとしているかを理解することが容易になった
else if (stat.isFile() && path.extname(filePath) == ".txt") {
    this.createHTMLFile(filePath, ".txt");
}
//...
const fullOutputPath = path.join(this.outputPath, `${path.basename(filePath, fileType)}.html`)

変数名の変更
すべての関数や変数名が意味をなさなかった.マイ関数createHTMLFiles() time =>createHTMLFile() , マイ変数fullFilePath 「hhhm」という質問を残しました.FullfilePathは完全な出力パスです.fullOutputPath .
より多くの変更が行われた
  • fileToHtml => fileToHtmlCreator この変数はhtmlcreatorオブジェクトです
  • paragraphObj => bodyObj 名前は時代遅れだったので、それは'段落オブジェクト'だった.TXTファイルですが、' HTML body object 'のようになりました

  • 機能の抽出
    私は、このコードがHTMLファイルを出力フォルダに書くのと同じ方法で2回使われたことに気づいた.line 80 , line 168
    fs.writeFile(fullFilePath, fileToHtml.renderHTML().replace(/<html>/, `<html lang="${option.lang ? option.lang : defaultLang}">`), (err) => {
          if(err) 
            return console.error(`Unable to create file ${fullFilePath}`);
          console.log(`${fullFilePath} is created`);
        });
    
    その後、重複したコードを減らすために同じ仕事をする別々の機能を書きました
    writeHTMLFile = (fullOutputPath, fileToHtmlCreator) => {
            fs.writeFile(
                fullOutputPath,
                fileToHtmlCreator
                    .renderHTML()
                    .replace(/<html>/, `<html lang="${this.lang}">`),
                (err) => {
                    if (err)
                        return errorToConsole(`Unable to create file ${fullOutputPath}`);
                    else console.log("\x1b[36m", `${fullOutputPath} is created`, "\x1b[0m");
                }
            );
        };
    

    キャッチする方法のリファクタリング
    私はプログラムの扱い方に満足していなかった--config オプションのため、コードのほとんどを書き直しました.私のアプローチは--config オプション.json 他のオプションの前に最初にoption を返します.--input が指定されていない
    if(option.config){
      try {
        let configData = fs.readFileSync(option.config);
        let configOptions = JSON.parse(configData); 
        for(const [key, value] of Object.entries(configOptions)) {
          value || value.length > 0 ? option[`${key}`] = `${value}` : option[`${key}`] = undefined;
        }
        if(!option.input) {
          console.error('\x1B[31m', `error: input <file or directory> is not specified in config file ${option.config}`, '\x1B[0m');
          process.exit(-1);
        }
      } catch(error) {
      console.error('\x1B[31m', `Can't read or parse config file ${option.config}\n ${error}`, '\x1B[0m');
      process.exit(-1);
      }
    }
    
    これにより線数が大幅に減少した.

    クラスの抽出
    リファクタリング後index.js ファイルは、グローバル変数を取り除くことを望んだので、私は、新しいファイルにクラス/モジュールを作成する決定に来たssg.js それはすべてのファイル処理index.js コマンドラインに注意してください.したがって、私はすべてのグローバル変数をSSG クラスとすべての関数をSSG クラス、私もクラスの構文に合うように少し微調整します.
    これは明らかに明確になり、将来のデバッグも楽になります.
    if(option.input) {
      var ssg = new SSG(option.input, option.output, option.lang);
      ssg.processInput(option.input);
    }
    

    すべてをコミットする
    コードベースの各段階のリファクタリングは1つ以上のコミットでした.通常、プロセスについて実際には終了しない結果を気にするので、変更の箇条書きで構成されるクリアメッセージでコミットをすべてコミットするのが良いです.手順は次のとおりです.
    git rebase main -i
    
    どのコミットメッセージを1つに変更するかを指定します.
    git commit --amend
    
    最後に、私はGithubに変更を押して、それはかなりの作品だった!
    チェックアウトTHE COMMIT