Browserify + shim on jquery and signalR not working

左心房为你撑大大i 提交于 2019-12-11 13:18:00

问题


I'm using gulp + browserify to bundle my source but i got always the same error : jQuery was not found. Please ensure jQuery is referenced before the SignalR client JavaScript file. SignalR get $ = undefined...

I split my source into two bundle : vendor and app. Vendor bundle get lib's id from packages.json and the bundle require it. App bundle get main entry and i passe id's lib to this bundle with bundle.external.

Here my packages.json :

  "browser": {
    "angular-notify": "./node_modules/angular-notify/dist/angular-notify.js",
    "angular-i18n": "./node_modules/angular-i18n/angular-locale_fr.js",
    "jquery": "./node_modules/jquery/dist/jquery.js",
    "signalR": "./node_modules/ms-signalr-client/jquery.signalr-2.2.0.js",
    "moment": "./node_modules/moment/moment.js",
    "moment-business": "./Scripts/Vendor/js/moment-business.js"
  },
  "browserify": {
    "transform": [
      "browserify-shim"
    ]
  },
  "browserify-shim": {
    "jquery": "$",
    "signalR": {
      "depends": [
        "jquery:jQuery"
      ]
    },
    "moment": "moment"
  }

Here my gulp taks :

'use strict';

import gulp from 'gulp';
import gulpLoadPlugins from 'gulp-load-plugins';
import browserify from 'browserify';
import browserifyInc from 'browserify-incremental';
import ngHtml2Js from 'browserify-ng-html2js';
import shim from 'browserify-shim';
import xtend from 'xtend';
import tsify from 'tsify';
import babelify from 'babelify';
import minifyify from 'minifyify';
import source from 'vinyl-source-stream';
import buffer from 'vinyl-buffer';
import browserSync from 'browser-sync';
import packageJson from './package.json';

const $ = gulpLoadPlugins();
let bs = browserSync.create();

let dependenciesCss = [
  'bootstrap',
  'font-awesome',
  'animate.css'
];

let externalDependenciesjs = [
  'signalR',
  'moment-business'
];

let dependenciesJs = Object.keys(packageJson.dependencies).filter(
  key => (
    dependenciesCss.every(
      libCssName => (key.trim() !== libCssName)
    )
  )
);

dependenciesJs = dependenciesJs.concat(externalDependenciesjs);

/*************************************
 *          SCRIPTS (build)          *
 *************************************/

let extensions = ['.js', '.json', '.ts'];

let bundler = browserify(xtend(browserifyInc.args, {
    entries: 'Scripts/App/app.ts',
    debug: true,
    extensions,
    cache: {},
    packageCache: {},
    fullPaths: true
  }))
  .external(dependenciesJs)
  .plugin(tsify, {
    target: 'es6'
  })
  .transform(babelify.configure({
    extensions,
  }))
  .plugin(minifyify, {
    map: 'app.min.js.map',
    output: 'Scripts/Dist/app.min.js.map'
  });


function compile() {

  bundler.on('log', $.util.log);

  browserifyInc(bundler, {
    cacheFile: './.tmp/browserify-cache.json'
  });

  $.util.log('Bundling JS ...');

  return bundler.bundle()
    .pipe($.plumber({
      errorHandler: browserifyError
    }))
    .on('error', browserifyError)
    .pipe(source('app.min.js'))
    .pipe(buffer())
    .pipe($.size({
      title: 'scripts'
    }))
    .pipe(gulp.dest('Scripts/Dist'))
    .pipe($.if(bs.active, bs.stream({
      once: true
    })));
}

let bundlerVendor = browserify(xtend(browserifyInc.args, {
    debug: true,
    extensions,
    cache: {},
    packageCache: {},
    fullPaths: true
  }))
  .require(dependenciesJs)
  .plugin(minifyify, {
    map: 'vendor.min.js.map',
    output: 'Scripts/Dist/vendor.min.js.map'
  });

function compileVendor() {

  bundlerVendor.on('log', $.util.log);

  browserifyInc(bundlerVendor, {
    cacheFile: './.tmp/browserify-vendor-cache.json'
  });

  $.util.log('Bundling vendor JS ...');

  return bundlerVendor.bundle()
    .pipe($.plumber({
      errorHandler: browserifyError
    }))
    .on('error', browserifyError)
    .pipe(source('vendor.min.js'))
    .pipe(buffer())
    .pipe($.size({
      title: 'scripts vendor'
    }))
    .pipe(gulp.dest('Scripts/Dist'))
    .pipe($.if(bs.active, bs.stream({
      once: true
    })));
}

function browserifyError(err) {
  error(err);
  this.end();
}

Vendor bundle haven't entry point, it only require lib. Here my app bundle entry :

/// <reference path="_references.ts" />

import 'signalR';
import 'moment';
import 'moment-business';
import 'moment-range';
import 'angular';
import 'angular-messages';
import 'angular-mocks';
import 'angular-animate';
import 'angular-file-upload';
import 'angular-notify';
import 'angular-i18n';
import 'angular-ui-bootstrap';
import 'angular-ui-router';
import 'angular-vs-repeat';
import 'postal';

import Route from './route';
import * as Configuration from './config';
import register from './registerModule';
import {camelize} from './tools';

let modules: Array<string> = [
  appName + '.Controllers',
  appName + '.Directives',
  appName + '.Filters',
  appName + '.Services',
  appName + '.Factory',
  appName + '.Constant'];
modules.forEach((moduleName: string): ng.IModule => angular.module(moduleName, []));

register();

modules.push('templates'); 
modules.push('ui.router');
modules.push('ui.bootstrap'); 
modules.push('angularFileUpload'); 
modules.push('ngAnimate'); 
modules.push('ngMessages'); 
modules.push('cgNotify'); 
modules.push('vs-repeat'); 

angular.module(appName, modules);

angular.module(appName)
  .config(
  ['$stateProvider', '$urlRouterProvider', '$locationProvider',
    ($stateProvider: ng.ui.IStateProvider,
      $urlRouterProvider: ng.ui.IUrlRouterProvider,
      $locationProvider: ng.ILocationProvider): Route => (
        new Route($stateProvider, $urlRouterProvider, $locationProvider)
        )
  ]);

angular.module(appName)
  .config(['$logProvider', ($logProvider: ng.ILogProvider): void => {
  $logProvider.debugEnabled(Configuration.ENABLED_CONSOLE_DEBUG);
}
]);

angular.module(appName)
  .config(
  ['$provide', ($provide: ng.auto.IProvideService): void => {
    /* tslint:disable:no-any */
    $provide.decorator('$exceptionHandler', ['$delegate', '$window', ($delegate: Function, $window: ng.IWindowService): any => {
      return (exception: any, cause: string): any => {
        /* tslint:enable:no-any */
        // utilisation du service $delegate pour formatter le message à afficher dans la console
        $delegate(exception, cause);
      };
    }]);
  }
  ]);

angular.module(appName)
  .config(
  ['$provide', '$httpProvider', ($provide: ng.auto.IProvideService, $httpProvider: ng.IHttpProvider): void => {
    $provide.factory('customHttpInterceptor', ['$q', ($q: ng.IQService) => {
      return {
        /* tslint:disable:no-any */
        'response': (response: any): any=> (camelize(response))
        /* tslint:enable:no-any */
      };
    }]);
    $httpProvider.interceptors.push('customHttpInterceptor');
  }]);

angular.module(appName).run(runAngular);

runAngular.$inject = ['$rootScope', '$location', '$log'];

function runAngular($rootScope: ng.IRootScopeService,
  $location: ng.ILocationService,
  $log: ng.ILogService): void {

  'use strict';

  $log.debug('Démarrage de l\'application : ', appName);
}

I already try to use browserify-shim transform with option global but this not work too.


回答1:


You still have to import jQuery into your code. The depends section of browserify-shim just tells it that jQuery comes before SignalR in the bundle. It doesn't say that any time you import SignalR that it will automatically import jQuery first.

The exact solution depends on whether SignalR is expecting jQuery to simply be present in the bundle, whether it expects jQuery to be present on the window object, or whether SignalR is a jQuery plugin that could potentially need attaching manually to the $ object.

The first solution I'd try is to simply import jQuery before you import SignalR:

/// <reference path="_references.ts" />

import $ from 'jquery';
import 'signalR';
// Rest of app.js........


来源:https://stackoverflow.com/questions/34794595/browserify-shim-on-jquery-and-signalr-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!