【问题标题】:Getting marionette.backbone to work with webpack hot module replacement让 marionette.backbone 与 webpack 热模块替换一起工作
【发布时间】:2016-04-30 21:46:39
【问题描述】:

我使用来自 here 的示例项目来设置一个带有热模块替换的 webpack 项目。然后我设置了一个示例主干应用程序。

// main.js
import $ from 'jquery';
import Backbone from 'backbone';

import Router from './router';

window.app = window.app || {};

const app = new Backbone.Marionette.Application();
app.addRegions({content: '#content'});

app.on('start', () => {
    if (Backbone.history)
      Backbone.history.start({ pushState: true })
}

);

app.addInitializer(() => {
  return new Router();
});


$( () => { app.start() });

// HMR
if (module.hot) {
    module.hot.accept();
}

根据[HMR] connected 调试输出,我可以看到 HRM 正在正常加载。 当文件更改时,我可以看到它正在重建并将更新推送到基于以下输出的客户端:

[HMR] Updated modules:
process-update.js?e13e:77 [HMR]  - ./app/backbone/views/template.hbs
process-update.js?e13e:77 [HMR]  - ./app/backbone/views/hello.js
process-update.js?e13e:77 [HMR]  - ./app/backbone/router.js

但是屏幕不会重新加载。什么都没有发生。

知道如何让它工作吗?还是 HMR 应该只适用于 React?

【问题讨论】:

  • 似乎主干不支持开箱即用的 HMR,必须添加代码来处理重新加载视图,类似于 react-hot-loader 的工作方式

标签: backbone.js webpack webpack-dev-server webpack-hmr


【解决方案1】:

这有点棘手,但你可以让它与骨干一起工作。博客文章是here that explains it fairly well。 (免责声明,我写的)

简而言之,您需要明确告诉您的父视图您可以接受热重载,然后您重新require 那个新的热重载视图,关闭您现有的子视图,然后重新渲染它。下面的示例使用 & 符号,但相同的基本原理适用于 Marionette 或 vanilla Backbone

/* parent.view.js */
var ChildView = require('./child.view.js');
var ParentView = AmpersandView.extend({
    template : require('path/to/template.hbs')

    initialize: function(){
        var self = this;
        if(module.hot){
            module.hot.accept('./child.view.js', function(){
                // re-require your child view, this will give you the new hot-reloaded child view
                var NewChildView = require('./child.view.js');
                // Remove the old view.  In ampersand you just call 'remove'
                self.renderChildView(NewChildView);
            });
        }
    },

    renderChildView(View){
        if(this.child){
            this.child.remove();
        }
        // use passed in view
        var childView = new View({
            model: this.model
        });
        this.child = this.renderSubview(childView, this.query('.container'));
    } 

    render: function(){
        this.renderWithTemplate(this);
        renderChildView(ChildView);
        return this;
    }
});

```

【讨论】:

猜你喜欢
  • 2015-05-31
  • 2018-09-22
  • 1970-01-01
  • 2020-02-06
  • 2017-06-20
  • 2017-02-27
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
相关资源
最近更新 更多