Browserify的自定义依赖项名称不起作用 [英] Browserify's custom dependency name is not working

查看:101
本文介绍了Browserify的自定义依赖项名称不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使browserify的自定义依赖项名称与内存流一起使用。我之所以使用内存流,是因为此代码注定要在AWS Lambda内运行,该Lambda将接收多个文件作为输入,并且无法通过文件系统用于lambda。

I am trying to get browserify's custom dependency name working with memory streams. The reason I am using a memory stream is because this code is destined to run inside an AWS Lambda that will be receiving multiple "files" as inputs and will not be available to the lambda via the file system.

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

According to the documentation at https://github.com/substack/node-browserify, it seems like this should be possible:


b.require(file,opts)

b.require(file, opts)

文件也可以是流,但是您还应该使用opts.basedir,以便可以解决相对要求。

file can also be a stream, but you should also use opts.basedir so that relative requires will be resolvable.

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

Use the expose property of opts to specify a custom dependency name. require('./vendor/angular/angular.js', {expose: 'angular'}) enables 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)

错误:

无法从'...'中找到模块'./two'

编辑:

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

Another individual has posted a similar issue on the node-browserify github page here: https://github.com/substack/node-browserify/issues/1622

推荐答案

Browserify大量使用了文件系统,因为它实现自己的模块解析,该解析使用与Node的 require 相同的算法。为了使Browserify使用内存中的源文件进行捆绑,一种解决方案是对文件系统进行猴子补丁-类似于 mock-fs 模块,对测试非常有用。

Browserify makes heavy use of the file system, as it implements its own module resolution that uses the same algorithm as Node's require. To get Browserify to bundle using in-memory source files, one solution would be to monkey patch the file system - in a manner similar to the mock-fs module that's useful for testing.

但是,您确实只想对源文件执行此操作。 Browserify将其模块分辨率用于捆绑包中包含的其他文件,因此必须将这些文件添加到内存中的文件系统中比较繁琐。修补的文件系统功能应检查涉及内存中源文件的调用,进行相应处理,并将其他调用转发到原始实现。 ( mock-fs 的作用类似,它可以检测到 require 内发生的文件系统调用,并将这些调用转发给

However, you really only want to do this for the source files. Browserify uses its module resolution for other files that are included in the bundle and having to add those to the in-memory file system would be tedious. The patched file system functions should check for calls that involve in-memory source files, handle them accordingly and forward other calls to the original implementations. (mock-fs does something similar in that it detects file system calls that occur within require and forwards those calls to the original implementations.)

'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);



需要暴露



在您的问题中,您提到了暴露 one.js two.js 模块使用 require ,因此可以在浏览器中使用 expose 选项中指定的名称来使用它们。如果这不是您想要的,则可以使用 add 代替,它们将成为捆绑软件内部的模块。

require and expose

In your question, you mentioned expose. The one.js and two.js modules were bundled using require, so they can be required in the browser using the name specified in the expose options. If that's not what you want, you can just use add instead and they will be modules internal to the 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>

我花了一些时间浏览Browserify的 require 和调查此tsify问题时的暴露选项。这些选项有助于从捆绑软件外部需求模块,但是我不确定它们对捆绑软件内部模块之间的需求有什么影响(这是您所需要的)。另外,它们的实现有些混乱-特别是

I spent some time looking into Browserify's require and expose options when investigating this tsify question. The options facilitate the requiring of modules from outside the bundle, but I'm not at all sure they have any influence on requires between modules within the bundle (which is what you need). Also, their implementation is a little confusing - particularly this part in which the exposed name sometimes has a slash prepended.

在您的问题是使用乙烯基。但是,我无法将乙烯基用于读取流。尽管它确实实现了 pipe ,但它不是事件发射器,并且似乎也没有实现基于 -Streams 2 API-这是Browserify从 createReadStream 结果中期望的结果。

In your question, you used vinyl. However, I wasn't able to use vinyl for the read streams. Although it does implement pipe, it's not an event emitter and doesn't seem to implement the on-based the pre-Streams 2 API - which is what Browserify expects from a createReadStream result.

这篇关于Browserify的自定义依赖项名称不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆