【问题标题】:Browserify-shim does not resolve dependenciesBrowserify-shim 不解决依赖关系
【发布时间】:2014-10-21 06:47:46
【问题描述】:

我想将 bootstrap.js 和 jquery.js(都与 npm 一起安装)合并到 vendor.js 文件中,但仍然可以通过调用 require('$') 来使用 jquery。 所以我创建了 gulp 任务:

'use strict';

var gulp = require('gulp'), 
helpers = require('./../utilities/gulp-helpers'),
source = require('vinyl-source-stream'),
plumber = require('gulp-plumber'),
browserifyShim = require('browserify-shim'),
browserify = require('browserify');

gulp.task('bulld-frontend:vendors', function(done) {
 var build = browserify({
  entries: [
  'jquery',
  'bootstrap'
  ]
});

 build
 .transform(browserifyShim)
 .require('jquery')
 .bundle()
 .pipe(source('vendors.js'))
 .pipe(gulp.dest('build/public/js'))
 .pipe(plumber({
  errorHandler: helpers.logError
}));

 done();
});

然后将配置添加到 package.json

"browser": {
    "bootstrap": "./node_modules/bootstrap/dist/js/bootstrap.js",
    "jquery": "./node_modules/jquery/dist/jquery.js"
  },
  "browserify-shim": "./gulp/utilities/shim-config.js",
}, 

最后在 gulp/utilities/shim-config.js

中配置我的 shim
'use strict';

module.exports = {
  'jquery'    :  '$',
  'bootstrap' :  { 'depends': { 'jquery': 'jQuery'} }
};

但在运行任务后我收到文件,引导程序在 jquery 之前,所以它抛出 Uncaught Error: Bootstrap's JavaScript requires jQuery

我加了

"browserify": {
    "transform": [
        "browserify-shim"
    ]
}

package.json 但它没有帮助。在我看来,browserify 从不应用这种转换,因为如果我用 .transform(function() { throw new Error("OLOLO"); }) 替换 .transform(browserifyShim) 任务仍然有效。

【问题讨论】:

    标签: jquery twitter-bootstrap browserify browserify-shim


    【解决方案1】:

    我以错误的方式使用了 browserify 和 shims。

    拳头,.transform(browserifyShim) 是不需要的,这是从代码调用转换的错误语法。

    其次,转换工作正常,我只需要创建 vendors.js 文件并在其中使用 require('bootstrap') 进行引导。然后指定 vendor.js 作为 bulld-frontend:vendors 任务的入口点:

    var build = browserify({
      basedir: 'sources/client/js'
      entries: [
      './vendors.js'
      ]
    });
    

    它正在工作。

    【讨论】:

      【解决方案2】:

      这对我有用,使用 browserify-shim 并在 package.json 文件中说明所有供应商库以及“browserify-shim”字段中的所有依赖项和导出。

      "browser": {
          "modernizr": "./app/assets/javascripts/vendor/modernizr.js",
          "jquery": "./bower_components/jquery/jquery.js",
      
          "angular": "./bower_components/angular/angular.min.js",
          "angular-touch": "./bower_components/angular-touch/angular-touch.js",
      },
      "browserify-shim": {
          "modernizr": {
            "exports": "Modernizr"
          },
          "jquery": "$",
          "angular": {
            "depends": "jquery", 
            "exports": "angular"
          },
          "angular-touch": {
            "depends": "angular",
            "exports": "angular.module('ngTouch')"
          }
      }
      

      然后在我的 gulpfile.js 上,我有以下函数来生成供应商包。

      // function to fetch the 'browserify-shim' json field from the package.json file
      function getNPMPackageBrowser() {
        // read package.json and get dependencies' package ids
        var packageManifest = {};
        try {
          packageManifest = require('./package.json');
        } catch (e) {
          // does not have a package.json manifest
        }
        return packageManifest['browserify-shim'] || {};
      }
      
      function vendor() {
        var deferred = q.defer(),
          b = browserify({ debug: true }).transform('browserify-shim'),
          libs = getNPMPackageBrowser(),
          lib;
      
        plugins.util.log('Rebuilding vendor JS bundle');
      
        // recursively add all of the vendor libraries as a --require or bundle.require() to browserify
        for (lib in libs) {
          if (libs.hasOwnProperty(lib)) {
            b.require(lib);
          }
        }
      
        b.bundle()
          //Pass desired output filename to vinyl-source-stream
          .pipe(source('vendor.js'))
          .pipe(gulp.dest(publicDir + '/assets/javascripts'))
          .on('end', deferred.resolve)
          .on('error', handleError);
      
        return deferred.promise;
      }
      

      【讨论】:

        【解决方案3】:

        尝试了 Torin 发布的内容。但没有运气。仍然抱怨 jQuery 未定义。

        只是有点咆哮。所有这些关于模块化需求的热潮,但工具令人困惑,可以说,前进 1 步然后后退 3 步。我们最终再次对脚本标签进行硬编码?

        好吧,废话不多说。这就是我让 jQuery 和任何 jQuery 插件工作的方式。

        第一件事 - jQuery 和任何相关的插件只需要一件事 - $ / jQuery 然后一切都会工作。那么为什么还要费心 require('jquery') 和 require('bootstrap') (如果你需要更多,你可以在你的 js 以及你的 package.json 中硬编码它们中的每一个 - 听起来很有趣?!?)

        我只是重复使用 bower 和旧的wiredep。

        我的 HTML:

        <head>
             <!-- bower:css -->
             <!-- endinject -->
             <!-- inject:css -->
             <!-- endinject -->
        </head>
        <body>
             <app></app>
             <!-- bower:js -->
             <!-- endinject -->
             <script src="bundle.js"></script>
        

        好的,这是经典的wiredep 设置。您只需要获取 gulp 文件即可观看 bower.json。每当您通过凉亭添加任何部门时。这将得到电线和服务。

        bundle.js 文件是从 gulpfile.js 中生成的

         gulp.task('bundle' , ['wiredep'] , function() 
         {
             browserify({debug: true})
                       .transform(
                            babelify.configure({stage: 0})
                       )
                       .transform(
                            stringify(['html'])
                       )
                       .require(
                            './app/index.js', {entry: true}
                       )
                       .bundle()
                       .on('error' , errorHandler)
                       .pipe(source('bundle.js')) // vinyl-source-stream
                       .pipe(buffer()) // vinyl-buffer
                       .pipe(sourcemaps.init({loadMaps: true})
                       .pipe(sourcemaps.write('./'))
                       .on('error' , errorHandler)
                       .pipe(gulp.dest('./dev'));
        
         });
        

        现在在我的 json 包中

         "browser": {
             "jquery": "./bower_components/jquery/dist/jquery.min.js",
             "bootstrap": "./bower_components/bootstrap/dist/jst/bootstrap.min.js",
             "mdbootstrap":"./bower_components/mdbootstrap/js/mdb.min.js"
         },
         "browserify": {
             "transform": ["browserfiy-shim"]
         },
         "browserify-shim": {
              "jquery": "global:$"
         }
        

        最后一部分是key `global:jQuery" or "global:$"

        然后在你的 js 文件中(我使用 Angular 和 ng-forward)

         'use strict';
         import 'bableify/polyfill';
         import 'reflect-metadata';
         import 'angular';
         import 'angular-ui-router';
         import {bootstrap} from 'ng-forward';
         import {App} from './components/app/app'; 
         import config from './config/config';
        
         // try to test if we get the bootstrap
         console.log($.fn.modal);
        
         bootstrap(App , ['ui.router',config.name]);
        

        您应该会看到控制台将向您显示引导模式代码。

        当然,(在 Angular 中)你真的应该只在你的指令中调用 $ (甚至在组件中也不行)。

        希望对您有所帮助。

        附:这将很快打包到一个 yeoman 生成器 (generator-ngf2) 中。查看我的网站http://panesjs.com 了解更多信息。

        【讨论】:

        • 感谢您澄清“global:”前缀,这正是我想要的。
        猜你喜欢
        • 2014-08-30
        • 1970-01-01
        • 1970-01-01
        • 2014-11-19
        • 2014-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-19
        相关资源
        最近更新 更多