首页 > 解决方案 > 如何通知 browserify 转换模块中的额外依赖项?

问题描述

我创建了一个 browserify 转换来将.pug文件转换为预解析的 Ractive JSON 对象。该操作需要将 Pug 文件转换为 HTML,然后传递给Ractive.parse()函数。

初始构建后不起作用的是,当我更改相对 Pug 文件时,browserify 不会重新编译父文件,因此更改不会反映到捆绑文件中。我watchify用来观察文件的变化。

考虑以下hello.js文件:

var x = require('./index.pug')
...

index.pug文件:

b hello 
include ./a.pug

我可以["/path/to/index.pug", "/path/to/a.pug"]在我的转换函数中获得。我如何将它传递给 browserify 以使其相关缓存在转换函数中index.puga.pug已更改时失效?

我的变换函数如下:

var through2 = require('through2')

preparsePug = function(file, contents){
  // returns {
  //     dependencies (Array), 
  //     parsed (String)
  //  }
  ...
}

function isTemplate(file){
  return /.*\.(pug)$/.test(file);
}
exports.ractivePreparserify = function(file){
  var contents, write, flush;
  if (!isTemplate(file)) {
    return through();
  }
  contents = '';
  write = function(chunk, enc, next){
    contents += chunk.toString('utf-8');
    next();
  };
  flush = function(cb){
    try {
      var x = preparsePug(file, contents);
      this.push("module.exports = " + JSON.stringify(x.parsed));
      return cb();
    } catch (err) {
      console.error("Preparserify error: ", err);
      return this.emit('error', err);
    }
  };
  return through2.obj(write, flush);
};

标签: gulpdependenciesbrowserifythrough2

解决方案


它是watchify在构建之间进行实际缓存的模块。watchify在后台使用browserify的内部缓存,但我们仍然发送信号以watchify使 browserify 在依赖项更改时重建。

从源代码中可以看出this.emit('file', dependency),transform 通过 watchify 通过信号通知它的 browserify 实例关于它的依赖关系。

上面ractivePreparserify的函数应该是:

through = require('through');

ractivePreparserify = function(file){
  var contents, write, end;
  if (!isTemplate(file)) {
    return through();
  }
  contents = '';
  write = function(chunk){
    contents += chunk.toString('utf-8');
  };
  end = function(){
    var x, i$, x$, ref$, len$, e;
    try {
      var x = preparsePug(file, contents);
      for (var i = 0; i < x.dependencies.length; i++) {
        this.emit('file', x.dependencies[i]); // <----- Informs browserify about dependencies.
      }
      this.queue("module.exports = " + JSON.stringify(x.parsed));
    } catch (e$) {
      e = e$;
      console.error("Preparserify error: ", e);
      this.emit('error', e);
    }
    return this.queue(null);
  };
  return through(write, end);
};

为了使其正常工作,browserify 应该完全按照此处的说明进行配置。


推荐阅读