juicer-loader.js 2.12 KB

const { resolve } = require("path");
const { Buffer } = require('buffer');
const through = require('through2');
const fs = require("fs");
const gutil = require('gulp-util');
const PluginError = gutil.PluginError;

// 常量
const PLUGIN_NAME = 'juicer-loader';

// 通过对js路径解析 得到juicer对象 path => juicer模板路径, mode => js模块名称
function toJuicer(settings, fpath) {
    const matches = settings.match(fpath);

    if(!matches) return null;

    const [mode, template] = matches;

    return {
        mode,
        template,
        path: resolve(settings.base, `${mode}.html`),
    };
}

// 对juicer模板进行AMD转换 默认模块名称为`${mode}_html`
function fmt(buff, template) {
    /**
     * 1. 对"进行处理
     * 2. 对回车进行处理
     * 3. 对换行进行多行处理
     */
    var content = `define("${template}", function() {
        return "${buff.toString().replace(/"/g, '\\"').replace(/\r/g, "").replace(/(?=\n)/g, "\\")}";
    });`;

    return new Buffer(content);
}

/**
 * loader 插件
 * @param {*} settings 
 * path: juicer模板的路径
 * match: 通过js文件路径匹配需要进行解析的js模块, 返回[模块名称, 模板名称]
 */
function juicerLoader(settings) {

    if (!settings) {
        throw new PluginError(PLUGIN_NAME, 'Missing settings!');
    }

    // 创建一个让每个文件通过的 stream 通道
    return through.obj(function (file, enc, cb) {
        if (file.isNull()) {
            // 返回空文件
            cb(null, file);
        }

        if(file.isStream()) {
            throw new PluginError(PLUGIN_NAME, 'Can not support Streaming!');
        }

        let juicer = toJuicer(settings, file.path);

        if(juicer && fs.existsSync(juicer.path)) {
            fs.createReadStream(juicer.path)
                .pipe(through.obj(function (buffer, e, c) {
                    file.contents = Buffer.concat([fmt(buffer, juicer.template), file.contents]);
                    cb(null, file);
                }));
        } else {
            cb(null, file);
        }
    });

};

// 暴露(export)插件主函数
module.exports = juicerLoader;