首页 > nodejs,想自己实现fis的inline功能,写出了以下代码,有没有更简洁的写法??

nodejs,想自己实现fis的inline功能,写出了以下代码,有没有更简洁的写法??

代码逻辑

  1. 创建两个文件

  2. 读入final_file并将其内容放入finaldata

  3. 将finaldata进行处理,将其引入的src_file文件抽出

  4. 读入src_file,并将其值赋给finaldata

  5. 再将finaldata写入final_file

    var fs = require('fs');
    var finalData;
    var arrayFile =[];
    var arrayStr=[];
        fs.writeFile('src_file.js', 'fsdfsdfwsffffffffffffffffffffffffffffff', function(err, fd) {
                   console.log('create newe new_file');
        });
    
        fs.writeFile('final_file.js', '__inline("src_file.js")', function(err, fd) {
                   console.log('create newe new_file');
        });
    fs.readFile('final_file.js', 'utf8', function(err, data) {
            var finalData = data;
            arrayFile = findInlineArray(data);
                for(var i in arrayFile){
                    fs.readFile(arrayFile[i],"utf8",function(err, fd) {
                                finalData = fd;
                                    fs.writeFile('final_file.js', finalData, function(err, fd) {
                                               console.log('success');
                                    });
                    });
                }
    
               function  findInlineArray(data) {
                       var arrayFile = [];
                    var patt = /(__inline\(['"]).*(?=['"]\))/;
                    //但是这样的写法只能匹配出现一个inline的情况,
                    //需要改进
                    var result = patt.exec(data)[0].replace(patt.exec(data)[1],'');
                    var tempReadFile;
                    arrayFile.push(result);
                       return arrayFile;
               }
        });

es7 async/await


最近刚好在学习nodeJS stream,所以借用楼上同学 @泡泡 的replace正则,用stream方式写了一个答案:

var fs = require('fs');
var replaceStream = require('replacestream')

fs.writeFileSync('src_file.js', 'This is src_file.js content');
fs.writeFileSync('final_file.js', '_inline("src_file.js")');

fs.createReadStream('final_file.js')
   .pipe(replaceStream(/_inline\(\s*["']([^"']+)["']\s*\)/g, function(str, script){
         if (fs.existsSync(script)) {
            try {
                return fs.readFileSync(script, 'utf8');
            } catch(err) {
                return str;
            }
         }

         return str;
      }))
   .pipe(fs.createWriteStream('final_file.js.tmp'));

或者自己实现一个transform的stream,这样自己就可以在stream中随意定制了。

补充,这显然不是一个最佳方法,最好是可以在_transform方法中分段替换后,进行push,但是牵扯到被替换的关键字有可能被分为两段,这是一个难点,正在想办法,当然你可以使用上面的replacestream去处理。 stream方式在处理大文件时,优势是很明显的。

var stream = require('stream'),
    util = require('util'),
    fs = require('fs');

var Transform = stream.Transform;

var Inline = function (options) {
  Transform.call(this, options);
  this._text = '';
};

util.inherits(Inline, Transform);

Inline.prototype._transform = function (chunk, encoding, callback) {
  var text = chunk.toString('utf8');
  this._text += text;
  callback();
};

Inline.prototype._flush = function (callback) {
  this._text = this._text.replace(/_inline\(\s*["']([^"']+)["']\s*\)/g, function(str,script) {
        if (fs.existsSync(script)) {
            try {
                return fs.readFileSync(script,'utf8')
            } catch(err) {
                return str
            }
        }
        return str
  });
  this.push(this._text, 'utf8');
  callback();
};

fs.writeFileSync('src_file.js', 'This is src_file.js content');
fs.writeFileSync('final_file.js', '_inline("src_file.js")');

fs.createReadStream('final_file.js')
   .pipe(new Inline()).pipe(fs.createWriteStream('final_file.js.tmp'));

不介意用同步的话可以这样。


const fs = require('fs')

fs.readFile('final_file.js',(err,content) => {
    content = content.toString()
    
    content = content.replace(/_inline\(\s*["']([^"']+)["']\s*\)/g, (str,script) => {
    
        if (fs.existsSync(script)) {
            try {         
                return fs.readFileSync(script,'utf8')
            } catch(err) {
                return str
            }
        }
        
        return str
    })
    
    fs.writeFile('final_file.js', content)
})

不喜欢同步的话,可以这样

const fs = require('fs')

var readFile = script => {
    return new Promise((resolve,reject) => {
        fs.readFile(script, (err,content) => {
            if (err) {
                return resolve(null)
            }
            
            resolve(content)
        })
    })
}

readFile('final_file.js')
    .then(content => {
        content = content.toString()
        
        var promises = []
        
        const INLINE_REG = /_inline\(\s*["']([^"']+)["']\s*\)/g
        
        content.replace(INLINE_REG , (str,script) => {
            promises.push(readFile(script))
        })
        
        return Promise.all(promises)
            .then(contents => {
                var i = 0
                content = content.replace(INLINE_REG , (str, script) => {              
                    return (contents[i++] || str).toString()
                })
                
                return content
            })        
    })
    .then(content => {
        fs.writeFile('final_file.dist.js', content)
    })    
【热门文章】
【热门文章】