hexo使用grunt實現(xiàn)自動化 | hexo

本文介紹hexo使用grunt實現(xiàn)一些自動化操作俩功。

開發(fā)過前端或者node.js的同學對grunt應該不陌生幻枉,如果對grunt不熟悉可略過本文。

開始使用hexo來處理靜態(tài)博客時我就遇到了問題诡蜓,我的文章已經(jīng)寫了很多篇了熬甫,都是markdown格式,而且托管在github上了蔓罚,然而hexo并不支持導入文章椿肩。

好在我發(fā)現(xiàn)只要把markdown文件拷貝到hexo里的source/_posts,hexo就會解析豺谈,我可以考慮直接把所有文章直接拷貝到這個目錄郑象。

但是另外一個問題又出現(xiàn)了,問題在于存在兩份一模一樣的源文件核无,一份我托管在github上扣唱,一份在source/_posts,后期文章改動的話团南,兩邊不同步噪沙,維護很費力。

后來想到的方法就是利用自動化工具來處理源文件的拷貝吐根,博客的部署等一些操作正歼。由于對grunt比較熟悉,所以使用了grunt拷橘。

如果對grunt不熟悉局义,可以前往grunt 網(wǎng)站

準備

  • 切換到hexo博客目錄
  • 執(zhí)行以下命令安裝grunt cli: npm install -g grunt-cli
  • 執(zhí)行以下命令安裝grunt: npm install grunt --save-dev
  • 執(zhí)行以下命令安裝插件:npm install --save-dev grunt-bg-shell grunt-contrib-clean grunt-contrib-copy grunt-contrib-watch grunt-rewrite grunt-zip grunt-shell load-grunt-tasks
  • 新建Gruntfile.js
  • 新建raw目錄

完成后,我的hexo博客里的目錄結(jié)構(gòu)是這樣子的:


image

grunt插件說明

以下為使用到的插件:

插件 作用
grunt-bg-shell 在后臺運行shell命令
grunt-contrib-clean 刪除文件和目錄
grunt-contrib-copy 拷貝文件和目錄
grunt-contrib-watch 監(jiān)測文件的新增冗疮、修改與刪除并運行對應的任務(wù)
grunt-rewrite 文件特定內(nèi)容的替換
grunt-shell 運行shell命令
grunt-zip zip壓縮
load-grunt-tasks 自動加載grunt插件

Gruntfile.js 編寫

新建Gruntfile.js萄唇,以下是我的Gruntfile.js的內(nèi)容:

// see: https://gruntjs.com/sample-gruntfile
module.exports = function(grunt) {
  
  var config = {
    pkg: grunt.file.readJSON('package.json'),
    pathConfig: {
      raw: 'raw',
      posts: 'source/_posts',
    },

    clean: {
      posts: {
        src: ['<%= pathConfig.posts %>/'],
      },
    },

    copy: {
      main: {
        files: [{
          expand: true,
          cwd: '<%= pathConfig.raw %>',
          src: '**/*.md',
          dest: '<%= pathConfig.posts %>',
          flatten: true,
          filter: function(filepath) {
            // var patterns = ['---\ntitle:'];
            var patterns = ['^---$'];
            var matchRegex = function(filepath, patterns) {
              var content = grunt.file.read(filepath);

              return patterns.some(function(pattern){
                var regex = new RegExp(pattern, 'm');
                // var regex = new RegExp(pattern);
                return regex.test(content);
              });
            };
            return matchRegex(filepath, patterns);
          },
        }],
      },
    },

    watch: {
      raw: {
        files: ['<%= pathConfig.raw %>/**/*.md'],
        tasks: ['copy:main'],
        options: {
          // spawn: false,
        },
      },
    },

    bgShell: {
      hexoServer: {
        cmd: 'hexo server',
        bg: true,
      },
      
    },

    shell: {
      gitClone: {
        command: 'git clone git@github.com:xxxxxxx/my_blog.git <%= pathConfig.raw %>/my_blog'
      },
      gitPullRaw: {
        command: 'cd ./raw/my_blog && git pull'
      },

      hexoGenerate: {
        command: 'hexo g',
      },
      hexoClean: {
        command: 'hexo clean',
      },
    },

    rewrite: {
      abbrlink: {
        src: '<%= pathConfig.raw %>/**/*.md',
        editor: function(contents, filepath){
          const crypto = require('crypto');
          const hash = crypto.createHash('sha256');

          hash.update(contents);
          var hashValue = hash.digest('hex');

          return contents.replace(/abbrlink: 3fb9c7a4f247726d/g, "abbrlink: " + hashValue.substring(0, 16));
        }
      },
    },

    zip: {
      dist: {
        src: [
          'public/**/*',
        ],
        dest: 'blog.zip'
      }
    }

  };

  grunt.initConfig(config);
  require('load-grunt-tasks')(grunt);

  // 運行g(shù)runt init 調(diào)用此任務(wù)
  grunt.registerTask('init', [
    'shell:gitClone'
  ]);

  grunt.registerTask('RawToPosts', [
    'shell:gitPullRaw',
    'rewrite:abbrlink',
    'copy:main',
  ]);

  // 運行 grunt 或者 grunt default 調(diào)用此任務(wù)
  grunt.registerTask('default', [
    'clean:posts',
    'RawToPosts',
    'bgShell:hexoServer',
    'watch',
  ]);

  // 運行g(shù)runt build調(diào)用此任務(wù)
  grunt.registerTask('build', [
    'clean:posts',
    'RawToPosts',
    'shell:hexoClean',
    'shell:hexoGenerate',
    'zip:dist'
  ]);

};

上述Gruntfile.js中有三個比較重要的任務(wù):

  • grunt init
  • grunt
  • grunt build

grunt init 任務(wù)是調(diào)用shell:gitClone 把我的博客源文件從github上拉取下來,放到raw/my_blog目錄术幔,這個命令只需要執(zhí)行一次另萤,后期不再需要。

grunt 任務(wù)用于日常本地寫博客诅挑,它的子任務(wù)分別是:

  • clean:posts: 刪除source/_posts下的所有文件
  • RawToPosts: 從github拉取更新到raw/my_blog四敞,并拷貝符合條件的文件到source/_posts
  • bgShell:hexoServer: 執(zhí)行hexo server,啟動hexo本地服務(wù)
  • watch: 監(jiān)測文件變化拔妥,輔助hexo server刷新

grunt build 任務(wù)用于發(fā)布博客忿危,它的子任務(wù)分別是:

  • clean:posts: 刪除source/_posts下的所有文件
  • RawToPosts: 從github拉取更新到raw/my_blog,并拷貝符合條件的文件到source/_posts
  • shell:hexoClean: 執(zhí)行hexo clean
  • shell:hexoGenerate: 執(zhí)行hexo genetate
  • zip:dist: 打包public成為blog.zip

通過上述grunt自動化腳本没龙,我保持了博客文件與hexo博客環(huán)境相分離的目標铺厨,我只需要運行grunt build缎玫,grunt會自動幫我拉取最新的博客文件并最終生成hexo目標文件。

這樣做的好處是以后不使用hexo時努释,我可以很方便轉(zhuǎn)移我的博客碘梢。

其他

如果是使用github pages來托管博客的同學,可以把grunt buildzip:dist換成自動部署博客的任務(wù)伐蒂,就能一鍵部署啦煞躬。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市逸邦,隨后出現(xiàn)的幾起案子恩沛,更是在濱河造成了極大的恐慌,老刑警劉巖缕减,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雷客,死亡現(xiàn)場離奇詭異,居然都是意外死亡桥狡,警方通過查閱死者的電腦和手機搅裙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裹芝,“玉大人部逮,你說我怎么就攤上這事∩┮祝” “怎么了兄朋?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長怜械。 經(jīng)常有香客問我颅和,道長,這世上最難降的妖魔是什么缕允? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任峡扩,我火速辦了婚禮,結(jié)果婚禮上障本,老公的妹妹穿的比我還像新娘教届。我一直安慰自己,他們只是感情好彼绷,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著茴迁,像睡著了一般寄悯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堕义,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天猜旬,我揣著相機與錄音脆栋,去河邊找鬼。 笑死洒擦,一個胖子當著我的面吹牛椿争,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播熟嫩,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼秦踪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掸茅?” 一聲冷哼從身側(cè)響起椅邓,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昧狮,沒想到半個月后景馁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡逗鸣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扛点。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡及刻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沪悲,到底是詐尸還是另有隱情获洲,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布殿如,位于F島的核電站贡珊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涉馁。R本人自食惡果不足惜门岔,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望烤送。 院中可真熱鬧寒随,春花似錦、人聲如沸帮坚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽试和。三九已至讯泣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阅悍,已是汗流浹背好渠。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工昨稼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人拳锚。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓假栓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親霍掺。 傳聞我的和親對象是個殘疾皇子匾荆,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容