about 1 year ago

痛點是前進的動力

之前使用gulp時就覺得能夠自動化抓檔案->讀資料->改資料->輸出檔案或改檔名這整件事情很有趣,但因為沒有適合題目所以擱著沒實作;
但最近接手公司案子,前人是用Angular1,沒有額外的打包或是任務排程工具,最弔詭的是不知道藏身於哪的Cache機制,我在本地端試了很久都沒有變化OTZ 程式碼也抓不出設定在哪,一怒之下只好自己製作進版號工具,也算是個練習。
檔案目錄大概是這樣

/assets
    | --- build
            | --- public.min.js (統整所有angular1的js檔)
    | --- public 
            | --- app.js
            | --- controller.js
            | --- main
                    | --- app-v0.js (統整所有angular1的js檔)
                    | --- controller-v0.js (統整所有angular1的js檔)

之前模板引擎是用ejs,如果我修改了/public底下的contriller-v0.js(angular1繪製頁面的邏輯所在),就要更新public.min.js中require被修改的angular1 js檔案,public.min.js大概長這樣

//= require public/main/app-v0.js

//= require public/main/controller-v0.js

....

我整體的具體需求是

  1. 主動監看/assets/public底下controller-v{\d*}.js檔案變化
  2. 如有變化,增進版號
  3. 將public.min.js中的controller-v{\d*}.js也更新

以下是我的程式碼

function updatePublicMinFIle(fileName, version) {
    "use strict";

    // 先將路徑寫死

    let srcPath = '/assets/build/public.min.js';
    let filePath = path.join(__dirname + srcPath);
    console.log(filePath);
    fs.readFile(filePath, 'utf-8', function (error, content) {
        if (error) {
            console.log('updateIncludedFileVersion writeFile' + error);
        }
        // 加入版號

        fs.writeFile(filePath, content.replace(new RegExp( "(" + fileName+ ")((\\-v\\d+\\.js)|(z\\.js))/g"), "$1-v" + version + ".js"), function (error) {
            if (error) {
                console.log('updateIncludedFileVersion writeFile' + error);
            }
        });
    });
}

// 監看路徑下的所有檔案變化

function watchDir() {
    chokidar.watch(path.join(__dirname, '/assets/public'), {
        persistent: true
    }).on('change', function (dir) {
        "use strict";
        // 動態取出版號與名稱

        let getFIleVersionRegex = /v(\d*).js/;
        let fileVersion = +getFIleVersionRegex.exec(dir)[1] + 1 || 0;

        // 取出可辨識的路徑名,/assets/public/*

        let getFileDirRegex = /(public\/.*\/controller)|(public\/controller)/;
        let fileName = getFileDirRegex.exec(dir)[1];

        // 修正路徑

        let changedFilePath = dir.replace(/(controller)((\-v\d*\.js)|(\.js))/, "$1-v" + fileVersion + ".js");
        fs.rename(dir, changedFilePath, function (err) {
            if (err) {
                console.error('rename file"', err);
            }
            console.log("file change:", changedFilePath);
        });

        // 修正/assets/build/public.min.js

        updatePublicMinFIle(fileName, fileVersion);
    });
}

watchDir();

說難也不難,寫RegExp最難XD 但是善用regex101.com就輕鬆很多!

另外要注意的是監看檔案我是用chokidar而不是用NodeJS原生File API,主要原因是fs在OSX下watch和watchFile功能不夠完善,所以改用這個模組去處理。

自動化遞進版號輕鬆許多,但是找不出怪異的Cache還是十分惱人OTZ

← Sails generate auth源碼解析 JS30 - 17_sort_without_articles 挑戰 →
 
comments powered by Disqus