如何在Gulp中使用Browserify库别名模块?

9
浏览器化(Browserify)的自述文件描述了如何创建外部依赖,方法如下: $ browserify -r through -r duplexer -r ./my-file.js:my-module > bundle.js 然后在你的页面中可以这样做:
<script src="bundle.js"></script>
<script>
  var through = require('through');
  var duplexer = require('duplexer');
  var myModule = require('my-module');
  /* ... */
</script>

这段代码适用于命令行,但我想在gulpfile中使用Browserify。但是,在示例中似乎没有添加模块名称的方法,例如./myfile-js:my-module。如果有选项,我还没找到。唯一的方法就是按照他们描述的方式使用require(3)来要求我的模块,因为Browserify似乎会给模块分配数字,但这些数字会改变,显然这是不可取的。
编辑:我的当前解决方案是这样的:
var shell = require('gulp-shell');

gulp.task('browserify', shell.task([
  'browserify -r ./src/bundle.js:bundle > ./build/bundle.js'
]))

这是一种解决方法,如果我想充分利用Gulp管道,则并不是最佳选择。我想知道是否可以在没有命令行的情况下完成此操作,如果不能,为什么只能通过CLI完成?

3个回答

8

b.require()expose选项相关。

function bundle () {
  browserify()
  .require("./myfile-js", {expose: "my-module"})
  .require("through")
  .require("duplexer")
  .bundle()
  /* ... */
}

gulp.task("browserify", bundle);

Browserify-Gulp集成

其他的答案建议在此处使用vinyl-source-stream,但这并不一定是必须的。您没有说明如何集成Browserify和Gulp。如果您只是在Gulp任务中包装一个Browserify捆绑操作(人们通常会这样做),而没有进行任何Browserify和Gulp之间的集成,例如在捆绑输出上运行Gulp插件,那么您只需要使用Browserify就可以了。例如,您可以这样做:

var fs = require("fs");

gulp.task("browserify", function () {
  return browserify(/* ... */)
    /* ... */
    .bundle()
    // But if you're doing something with Gulp here you should use
    // `vinyl-source-stream` and pipe to `gulp.dest()`.
    .pipe(fs.createWriteStream("./bundle.js", "utf8"));
});

我喜欢你将函数从任务配置中分离出来的方式,你的配置文件是否按照 gulp 任务分别存储在多个文件中? - vamsiampolu
1
你的意思是将任务函数定义在单独的文件中并将其导入到gulpfile中吗?我通常会像这里所示在同一个文件中编写它,但我之所以在这里这样做的主要原因是问题涉及Browserify API,与gulp没有任何关系,所以我甚至不想提到gulp,但为了帮助OP理解情况,我还是这样做了。 - JMM

1
以下是我能想到的几种方法来实现您想要的内容:
1. 使用 .bundle() 方法:
看起来 .bundle() 方法可能是您需要的。它已经预先构建在 browserify 中。尝试使用这段代码进行实验。它允许您使用 gulp 的 .pipe() 方法。
const browserify = require('browserify')
const gulp = require('gulp')
const source = require('vinyl-source-stream')

gulp.task('browserify', function (cb) {
  browserify('./src/bundle.js')
  .bundle() // <- This traverses the /node_modules/ tree to bundle everything ...
            // into 1 giant stream & eventually a single file.
  .pipe(source('bundle.js')) // Creates the "output source" file name,
                             // rather than being the "input source".
  .pipe(gulp.dest('./build/'))
  return cb()
})

那么你应该能够将这个文件链接: ./build/bundle.js 与像这样的 <script> 标签关联起来:<script src="./build/bundle.js"></script>

NPM 链接: vinyl-source-stream, browserify, gulp (你已经知道这些,但其他人可能还不清楚)。

2. 制作一个深度链接别名:

如果你想要制作一个别名,其可以深度链接到一个外部JS类(而不是CSS类),你需要尝试使用如下的 require() 方法调用:

const bundle = require('browserify').bundle

这相当于:

import {bundle} from "browserify"

那最后的两行假设一个JSON对象被从外部模块返回,该模块作为依赖项被要求/包含。在外部文件中,返回的对象应该类似于这样:
module.exports = {
    "default": SomeMainClass,
    "bundle": someExtraFunctionLikeBundle
}

潜在问题:“Gotchya”:如果外部依赖项未返回JSON对象,则.bundle将返回未定义。例如,这会阻止require('browserify').bundle中的.bundle工作:

module.exports = function() {...} // instead of module.exports = {JSON}

如果您在尝试第一个代码示例后需要额外的Gulp帮助,请告诉我。(它是如何将gulp.task()browserify().bundle().pipe()结合使用,以及您的代码混合在其中的。您应该能够在计算机上使其正常工作。)


0

使用 gulp 和 browserify 时,需要安装 vinyl-source-stream 模块。-r 标志将你的捆绑包内模块外部公开,然后可以使用 require 调用。

您可以配置多个入口并将配置移动到不同的文件中。如果只有一个入口文件,则可以将其传递给 browserify 并从选项中删除 entries。选项中的 debug:true 与命令行中的 -d 相同。

var b = browserify(./app/index.js');                         

现在,你可以在你的 gulp 配置文件中这样做:
  var gulp = require('gulp');                                                      
  var transform = require('vinyl-source-stream');                                  
  var browserify = require('browserify');                                          
  var b = browserify({                                                             
    entries:['./app/index.js'],                                                    
    debug:true                                                                     
  });                                                                              

  gulp.task('browserify',function(){                                               
    return b                                                                       
           .require('through')                                                     
           .require('duplexer')                                                    
           .require('./app/lib/my-module',{expose:'my-module'})                    
           .bundle()                                                               
           .pipe(transform('bundle.js'))                                           
           .pipe(gulp.dest('./app/build'))                                         
 });

如果您想使用expose选项将模块以不同的名称公开,以便与require一起使用。

看起来在使用非Commonjs模块或未正确设置module.exports的模块方面存在gotcha

如果您想要从另一个包中(假设您有多个包)使用您公开的模块作为requirable,则可以:

b
.external('thorugh')
.external('my-module')
.../*more config*/
.bundle()
.pipe(transform('bundle2.js'))
.pipe(gulp.dest('./app/build')

在这种情况下,每当你在bundle2中需要my-module时,你都是从bundle.jsrequire外部引用它。
如果你想允许多个文件通过单个require调用在bundle之外被引用,你可以将它们作为一个array传递进去。
gulp.task('browserify',function(){                                               
    return b                                                                       
           .require(['through','duplexer'],{expose:'stream-utils'})                                                                                                         
           .require('./app/lib/my-module',{expose:'my-module'})                    
           .bundle()                                                               
           .pipe(transform('bundle.js'))                                           
           .pipe(gulp.dest('./app/build'))                                         
 });

你可以查看Stefan Imhoff的gulp教程browserify API以获取更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接