El nombre de dependencia personalizado de Browserify no funciona

Estoy tratando de obtener el nombre de dependencia personalizado de browserify trabajando con flujos de memoria. La razón por la que estoy usando un flujo de memoria es porque este código está destinado a ejecutarse dentro de un AWS Lambda que recibirá múltiples “archivos” como entradas y no estará disponible para la lambda a través del sistema de archivos.

De acuerdo con la documentación en https://github.com/substack/node-browserify , parece que esto debería ser posible:

b.require (archivo, opta)

El archivo también puede ser una secuencia, pero también debe usar opts.basedir para que los requisitos relativos puedan resolverse.

Use la propiedad expose de opts para especificar un nombre de dependencia personalizado. require (‘./ vendor / angular / angular.js’, {expose: ‘angular’}) habilita require (‘angular’)

Código:

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) 

Error:

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

Editar:

Otra persona ha publicado un problema similar en la página de github de node-browserify aquí: https://github.com/substack/node-browserify/issues/1622

Browserify hace un uso intensivo del sistema de archivos, ya que implementa su propia resolución de módulo que utiliza el mismo algoritmo que require Node. Para lograr que Browserify se agrupe utilizando archivos de origen en memoria, una solución sería parchear el sistema de archivos de una manera similar al módulo de mock-fs que es útil para las pruebas.

Sin embargo, realmente solo desea hacer esto para los archivos de origen. Browserify usa la resolución de su módulo para otros archivos que están incluidos en el paquete y tener que agregarlos al sistema de archivos en memoria sería tedioso. Las funciones del sistema de archivos parcheados deben verificar las llamadas que involucran archivos de origen en la memoria, manejarlas en consecuencia y reenviar otras llamadas a las implementaciones originales. ( mock-fs hace algo similar en cuanto detecta las llamadas al sistema de archivos que ocurren dentro de las require y las reenvía a las implementaciones originales).

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

require y expose

En tu pregunta, mencionaste expose . Los módulos one.js y two.js fueron agrupados usando require , por lo que pueden ser requeridos en el navegador usando el nombre especificado en las opciones expose . Si eso no es lo que desea, puede usar add lugar y serán módulos internos del paquete.

    so-39397429       

Pasé un tiempo investigando las opciones de Exponer y expose Browserify al investigar esta pregunta de tsify . Las opciones facilitan la necesidad de módulos fuera del paquete, pero no estoy seguro de que tengan alguna influencia sobre los requisitos entre los módulos dentro del paquete (que es lo que necesita). Además, su implementación es un poco confusa, especialmente en esta parte en la que el nombre expuesto a veces tiene una barra inclinada.

Corrientes de vinilo

En tu pregunta, usaste vinyl . Sin embargo, no pude usar vinyl para las secuencias de lectura. Aunque implementa la pipe , no es un emisor de eventos y no parece implementar la API pre-Streams 2 basada on base, que es lo que Browserify espera de un resultado de createReadStream .