如何解决browserify(基于 Backbone.js 的应用程序)和require.js在同一页面上的冲突?

2fjabf4q  于 2022-11-10  发布在  其他
关注(0)|答案(4)|浏览(142)

我有一个 Backbone 应用程序正确启动和运行。它的目的是作为一个小部件在第三页使用。不幸的是,我刚刚意识到,其中一个页面已经加载了 Backbone /下划线。
我收到如下错误:

Uncaught TypeError: Cannot read property 'extend' of undefined

通常在以前未加载下划线时出现。
我的典型看法是这样的:(正常 Backbone.js 视图)
./view1.js

var Backbone = require('backbone')
var _ = require('underscore')
var $ = require('jquery')
Backbone.$ = $

module.exports = Backbone.View.extend({

  events: {

  },

  initialize: function () {

  },

  render: function () {

  }
})

那我就叫它:

var View1 = require('view1')
var view1Instance = new View1(...)

感谢您的帮助:)
调查后编辑:在调试器中运行时,Backbone变量似乎是一个空对象,而不是Backbone。
编辑2:似乎与该问题相关:https://github.com/substack/node-browserify/issues/790

brc7rcf0

brc7rcf01#

Backbone.js 和需求的问题(as indicated by thlorenz here

  • 在查找模块之前, Backbone.js 查找define。导出
  • requirejs使用全局变量,这不是一个好的做法,在这种情况下会导致问题,因为它会影响在同一个浏览器选项卡中运行的所有内容

他建议将所有内容都封装在一个作用域中,并隐藏define函数。他也有一个工具可以做到这一点。browserify-shim
然而,我没有使用它,而是使用了Browserify中的postBundleCB选项:(谢谢同事)。
在我的Gruntfile中:

browserify: {
  dist: {
    src: ['src/app/app.js'],
    dest: 'www/app.js',
    options: {
      postBundleCB: function (err, src, next) {
        return next(null, '(function () { var define = undefined; '+src+' })();')
      }
    }
  }
},

这解决了我的问题:)
我没有试过browserify-shim,所以我对它了解不多。

mcdcgff0

mcdcgff02#

如果有人使用gulp和官方的browserify(所以postBundleCB不可用),我使用gulp-wrap来 Package 'define'定义:

var wrap = require('gulp-wrap');

[...]

bundler.bundle()
  .on('error', swallowError)
  .pipe(source(file))
  .pipe(wrap('(function () { var define = undefined; <%=contents%> })();'))
  .pipe(rename(renameOptions))
  .pipe(gulp.dest(argv.output?argv.output:'./dist'));
91zkwejq

91zkwejq3#

另一种解决方法是使用如下自定义前奏:

// modules are defined as an array
// [ module function, map of requireuires ]
//
// map of requireuires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the requireuire for previous bundles

(function outer (modules, cache, entry) {
    // Save the require from previous bundle to this closure if any
    var previousRequire = typeof require == "function" && require;

    function newRequire(name, jumped){
        var oldDefine = window.define;
        window.define = undefined;
        if(!cache[name]) {
            if(!modules[name]) {
                // if we cannot find the the module within our internal map or
                // cache jump to the current global require ie. the last bundle
                // that was added to the page.
                var currentRequire = typeof require == "function" && require;
                if (!jumped && currentRequire) return currentRequire(name, true);

                // If there are other bundles on this page the require from the
                // previous one is saved to 'previousRequire'. Repeat this as
                // many times as there are bundles until the module is found or
                // we exhaust the require chain.
                if (previousRequire) return previousRequire(name, true);
                var err = new Error('Cannot find module \'' + name + '\'');
                err.code = 'MODULE_NOT_FOUND';
                throw err;
            }
            var m = cache[name] = {exports:{}};
            modules[name][0].call(m.exports, function(x){
                var id = modules[name][1][x];
                return newRequire(id ? id : x);
            },m,m.exports,outer,modules,cache,entry);
        }
        window.define = oldDefine;
        return cache[name].exports;
    }
    for(var i=0;i<entry.length;i++) newRequire(entry[i]);

    // Override the current require with this new one
    return newRequire;
})

您可以这样为browserify给予一个前奏:

browserify({
  prelude: fs.readFileSync(__dirname + '/src/js/prelude.js', 'utf-8'),
  ...
})
aamkag61

aamkag614#

这可能与某人有关,他在一个有requirejs的站点中使用browserify。一个临时的解决方案可以是,而不是:

`.pipe(wrap('(function () { var define = undefined; <%=contents%> })();'))`

对于直接使用browserify API的用户,可以在加载我们的包之前添加这段代码:

(function() {
if (typeof define === "function" && define.amd) {
    define.amd= false; 
}})();

这将允许继续我们的执行,而不破坏客户端上的代码。
我希望这是有用的。

相关问题