Browserify的自定义依赖项名称不起作用

我正在尝试使用内存stream来浏览browserify的自定义依赖项名称。 我使用内存stream的原因是因为此代码注定要在将接收多个“文件”作为input的AWS Lambda内部运行,并且不会通过文件系统提供给lambda。

根据https://github.com/substack/node-browserify的文档,似乎这应该是可能的:

b.require(文件,select)

文件也可以是一个stream,但你也应该使用opts.basedir,以便相对的要求将是可parsing的。

使用opts的expose属性来指定一个自定义的依赖项名称。 require('./ vendor / angular / angular.js',{expose:'angular'})启用require('angular')

码:

const browserify = require('browserify') const path = require('path') const File = require('vinyl') const jsIndex = new File({ file: path.resolve('index.js'), contents: new Buffer('var two = require("./two")')}) const jsTwo = new File({ file: path.resolve('two.js'), contents: new Buffer('console.log("Hello from two.js")')}) browserify({ entries: [ jsIndex ], require: [ jsTwo ], basedir: path.resolve('.') }) .bundle((err, res) => { if (err) console.log(err.message) }) .pipe(process.stdout) 

错误:

Cannot find module './two' from '...'

编辑:

另一个人在node-browserify github页面上发布了类似的问题: https : //github.com/substack/node-browserify/issues/1622

       

网上收集的解决方案 "Browserify的自定义依赖项名称不起作用"

Browserify大量使用文件系统,因为它实现了自己的模块分辨率,使用与Node require相同的algorithm。 为了让Browserify使用内存中的源文件进行绑定,一种解决scheme是猴子修补文件系统 – 类似于对testing有用的mock-fs模块。

但是,您真的只想为源文件执行此操作。 Browserify将其模块parsing用于捆绑包中包含的其他文件,并将这些文件添加到内存中的文件系统将是单调乏味的。 补丁文件系统函数应该检查涉及内存源文件的调用,并相应地处理它们,并将其他调用转发给原始实现。 ( mock-fs做了类似的事情,它检测在require中发生的文件系统调用,并将这些调用转发给原始实现。)

 'use strict'; const fs = require('fs'); const path = require('path'); const toStream = require('string-to-stream'); // Create an object hash that contains the source file contents as strings, // keyed using the resolved file names. The patched fs methods will look in // this map for source files before falling back to the original // implementations. const files = {}; files[path.resolve('one.js')] = 'console.log("Hello from one.js");' + 'var two = require("./two");' + 'exports.one = 1;'; files[path.resolve('two.js')] = 'console.log("Hello from two.js");' + 'exports.two = 2;'; // The three fs methods that need to be patched take a file name as the // first parameter - so the patch mechanism is the same for all three. function patch(method, replacement) { var original = fs[method]; fs[method] = function (...args) { var name = path.resolve(args[0]); if (files[name]) { args[0] = name; return replacement.apply(null, args); } else { return original.apply(fs, args); } }; } patch('createReadStream', function (name) { return toStream(files[name]); }); patch('lstat', function (...args) { args[args.length - 1](null, { isDirectory: function () { return false; }, isFile: function () { return true; }, isSymbolicLink: function () { return false; } }); }); patch('stat', function (...args) { args[args.length - 1](null, { isDirectory: function () { return false; }, isFile: function () { return true; } }); }); // With the fs module patched, browserify can be required and the bundle // can be built. const browserify = require('browserify'); browserify() .require(path.resolve('one.js'), { entry: true, expose: 'one' }) .require(path.resolve('two.js'), { expose: 'two' }) .bundle() .pipe(process.stdout); 

requireexpose

在你的问题中,你提到了exposeone.jstwo.js模块使用require捆绑在一起,因此可以在浏览器中使用在expose选项中指定的名称。 如果这不是你想要的,你可以使用add来代替它们,它们将是bundle内部的模块。

 <!doctype html> <html> <head> <title>so-39397429</title> </head> <body> <script src="./bundle.js"></script> <script> // At this point, the bundle will have loaded and the entry // point(s) will have been executed. Exposed modules can be // required in scripts, like this: console.log(require('one')); console.log(require('two')); </script> </body> </html> 

在调查这个tsify问题时,我花了一些时间来研究Browserify的requireexpose选项。 这些选项方便了从bundle之外的模块的需求,但是我不能确定它们对bundle中模块之间的需求有什么影响(这是你需要的)。 另外,它们的实现有点令人困惑 – 尤其是在这个部分中,暴露的名字有时会有一个斜杠。

乙烯stream

在你的问题中,你使用vinyl 。 但是,我不能使用vinyl读取stream。 虽然它实现了pipe ,但它不是事件发布器,似乎也不实现基于on -stream的前Streams 2 API–这是Browserify对createReadStream结果的期望。