【问题标题】:How to bundle multiple javascript libraries with browserify?如何将多个 javascript 库与 browserify 捆绑在一起?
【发布时间】:2015-12-19 16:29:07
【问题描述】:

我正在尝试在浏览器中使用 Browerifiy,如果我使用独立选项,它会公开一个模块。我不想这样做。 网站和文档似乎在我实际编译代码后所看到的所有地方都被切断了。 没有人说过如何实际使用浏览器属性中的代码。

我有一个繁重的任务:

browserify: {
      standalone: {
        src: [ '<%= yeoman.server %>/shared-components/**/*.js' ],
        dest: '<%= yeoman.client %>/app/js/browserifed-shared-code.js',
        /* Commented out, zero documentation on this. Can only expose one module it seems.
        options: {
          browserifyOptions: {
            standalone: 'Utility' //Unable to say '**/*' error :-/
          }
        }
        */
      },

这似乎可行,它会生成这样的文件:

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';

var UrlController = function(){};

UrlController.test = function () {
    return 'test';
};

module.exports = UrlController;

},{}],2:[function(require,module,exports){
'use strict';

var Utility = function(){};

Utility.isASCII = function (str) {
    return /^[\x00-\xFF]*$/.test(str);
};

Utility.isAlphaNumeric = function(str) {
    var code, i, len;
    for (i = 0, len = str.length; i < len; i++) {
        code = str.charCodeAt(i);
        if (!(code > 47 && code < 58) && // numeric (0-9)
        !(code > 64 && code < 91) && // upper alpha (A-Z)
        !(code > 96 && code < 123)) { // lower alpha (a-z)
            return false;
        }
    }
    return true;
};

module.exports = Utility;

},{}]},{},[1,2]);

我使用注入器自动包含它,其工作原理类似于:

<script src="app/js/browserifed-shared-code.js"></script>

现在我希望我可以打电话了

require('Utility');

但我明白了

Uncaught ReferenceError: require is not defined(…)

我不知道/无法在浏览器中加载这些模块。 :'-/

【问题讨论】:

  • 我对你想要做什么感到困惑。 Browserify 捆绑您的代码以实现高效的客户端交付,并且可以公开一个全局(通过standalone 选项),您可以通过它访问内部。它不会把客户端变成 Nodejs,所以它不会给你require,你只是得到一个匿名加载的库,或者使用单个全局访问变量,命名为standalone。然后,您不需要“要求”您浏览客户端的东西,您只需将Utility 用于Utility.whateverPropertyYouExposedUtility.whateverFunctionYouExposed() 等。
  • you simply get a library that either loads anonymously 解释一下,我匿名加载它并如何访问它? (下面我已经回答了我自己的问题,因为我仍然找不到对此的解释)
  • 如果它是匿名加载的,你以后不会“访问它”,你写的代码应该已经能够做它需要做的一切。如果您以后需要访问它,则使用--standalone 标志进行编译,然后确保入口点代码公开您需要访问的所有内容。

标签: javascript node.js gruntjs npm browserify


【解决方案1】:

这里有两个选择。要么你

解决方案 1

为您要在浏览器中访问的每个库创建一个独立的 browserify 模块。这已在您的另一篇文章中得到解答。基本上你会做多个 browserify 包。

.

browserify library1.js --standalone Library1 -o library1-bundle.js
browserify library2.js --standalone Library2 -o library2-bundle.js
browserify library3.js --standalone Library3 -o library3-bundle.js

 <script src="library1-bundle.js" type="text/javascript"/> 
 <script src="library2-bundle.js" type="text/javascript"/> 
 <script src="library3-bundle.js" type="text/javascript"/> 

因此,在您的构建工具中,您将拥有

browserify: {
      library1 : {
        src: [ '<%= yeoman.server %>/shared-components/library1.js' ],
        dest: '<%= yeoman.client %>/app/js/library1-bundled.js',
        bundleOptions : { standalone : 'Library1' }
      },
      library2 : {
        src: [ '<%= yeoman.server %>/shared-components/library2.js' ],
        dest: '<%= yeoman.client %>/app/js/library2-bundled.js',
        bundleOptions : { standalone : 'Library2' }
      },
      library3 : {
        src: [ '<%= yeoman.server %>/shared-components/library3.js' ],
        dest: '<%= yeoman.client %>/app/js/library3-bundled.js',
        bundleOptions : { standalone : 'Library3' }
      }
}

解决方案 2

或者,为所有模块创建一个主入口点。

// ---- main.js -----
module.exports.Library1 = require('./lib1');
module.exports.Library2 = require('./lib2');
module.exports.Library3 = require('./lib3');

然后,你使用 browserify

browserify main.js --standalone Library -o bundle.js

然后在你的浏览器中

<script src="bundle.js" type="text/javascript"/> 

在你的繁重任务中:

browserify: {
      standalone: {
        src: [ '<%= yeoman.server %>/shared-components/main.js' ],
        dest: '<%= yeoman.client %>/app/js/main-bundled.js',
        bundleOptions : { standalone : 'Library' }
      }}

关于模块加载器和 Browserify 的注意事项

然后,为了扩展我在您之前的帖子中所做的答案,browserify 会根据您环境中存在的模块管理器以不同的方式公开它的捆绑模块。

  • 如果你在node,是commonJS(sync)所以你可以使用require('');
  • 如果您使用的是 AMD(异步),则可以使用该 AMD 语法。
  • 如果您在浏览器中,您可以使用任一窗口。或全局。

Grunt 动态任务定义

为了自动化一点,你也可以传入一个配置:

bundledLibraries : [
    Library1 : {
        src : './../src/lib1.js',
        dest : './../src/lib1-bundled.js'
    },
    Library2 ...
]

然后你迭代将它们添加到 grunt 配置中(

查看这篇文章以动态创建它们http://www.integralist.co.uk/posts/dynamic-grunt-tasks.html

【讨论】:

  • 我可以不 foreach 以防万一添加了新的,因此可以动态添加它们吗?
  • 非常感谢。我要发布我所拥有的。我正在使用共享公共端点来动态访问其他类。我查看了 CommonJS,但文档太多,我没有时间 + 我认为这是我不需要的额外复杂性。
  • CommonJS 是一个带有依赖注入的模块加载器。基本上,您声明模块及其依赖项,并且它们是异步解析的,因此它更适合浏览器(响应更快)。但是,如果您有少量脚本,那没关系。另外,我认为你正在使用 Angular,所以坚持使用 Angular 风格的模块和 ocLazyLoader,它会让你的生活更轻松。
  • 我查看了这些文件,但它们有一页又一页的文档。看我的回答。是的,小脚本 :-) 我接受了你的回答,因为它让我完成了我的。
【解决方案2】:

我以自己的方式完成了这项工作,而没有用依赖项过多地混淆项目。

咕哝着我有

browserify: {
      standalone: {
        src: [ '<%= yeoman.server %>/shared-components/exposed-modules.js' ],
        dest: '<%= yeoman.client %>/app/js/browserifed-shared-code.js',
        options: {
          browserifyOptions: {
              standalone: 'Shared'
          }
        }
      },
    }

//In-completed example.
watch: {
      scripts: {
        files: ['<%= yeoman.server %>/shared-components/**/*.js'],
        tasks: ['browserify'],
        options: {
            spawn: false
        }
        },

然后我公开了我想要使用的模块:

'use strict';

//This is the main entry point for all shared libraries.

var Utility = require('./utility');
var UrlController = require('./url-controller');

var Shared = function(){};

//Added new client modules to be exposed here.
Shared.Utility = Utility;
Shared.UrlController = UrlController;

module.exports = Shared;

现在我可以在浏览器中调用

shared.Utility.isAscii('test'); //Working.

而任何我想重用的地方,我都只是在范围内分配,所以

//Some scope.
var Utility = shared.Utility;

【讨论】:

    猜你喜欢
    • 2019-06-07
    • 2017-05-12
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    相关资源
    最近更新 更多