如何在 Gulp 中使用 Browserify lib 为模块添加别名?

How to alias a module with Browserify lib in Gulp?

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 完成?

这里有几种我可以想到的方法来完成你正在寻找的东西:

1.使用 .bundle() 方法:

好像是.bundle() method may be what you need. It's pre-built into 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()
})

那么你应该能够 link 这个文件:./build/bundle.js 到一个 <script> 标签,像这样:<script src="./build/bundle.js"></script>.

NPM links: vinyl-source-stream, browserify, gulp(你已经知道了,但其他人可能还不知道。)

2。创建一个深 linked 别名:

如果你想创建一个别名,深入 link 到外部 JS class(不是 CSS class),你必须尝试使用这样的 require() 方法调用:

const bundle = require('browserify').bundle

相当于:

import {bundle} from "browserify"

最后两行假设 JSON 对象是从外部模块 return 编辑的,外部模块是 required/included 的依赖项。该外部文件中的 return 对象应如下所示:

module.exports = {
    "default": SomeMainClass,
    "bundle": someExtraFunctionLikeBundle
}

潜力 "Gotchya":如果外部依赖不return一个JSON对象,那么.bundle会return 未定义。例如,这会阻止 require('browserify').bundle 中的 .bundle 工作:

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

如果您在 Gulp 方面需要其他帮助,请在尝试第一个代码示例后告诉我。 (它混合了 gulp.task()browserify().bundle().pipe() 如何一起工作,以及您的代码混合到其中。您应该能够让它工作你的电脑。)

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。你只需要 vinyl-source-stream 如果你实际上在 Browserify 和 Gulp 之间做一些集成,而不仅仅是将 Browserify 捆绑操作包装在 Gulp 任务中(人们通常这样做),比如 运行 捆绑输出上的 Gulp 插件。例如,您可以这样做:

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"));
});

在browserify中使用gulp时,需要安装vinyl-source-stream模块。 -r 标志将你的包中的模块暴露在外部,然后它们可以使用 require.

调用这些模块

您可以配置多个条目并将您的配置移动到不同的文件,如果您只有一个条目文件,您可以将它传递给 browserify 并从选项中删除 entriesdebug: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'))                                         
 });

如果您想通过不同的名称公开您的模块以用于 require,请使用 expose 选项。

关于使用 non 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.js 中的 require 中外部请求它。

如果您希望通过单个 require 调用允许多个文件在包外被要求,您可以将它们作为 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's gulp tutorial and the browserify API 了解更多信息。