代码之家  ›  专栏  ›  技术社区  ›  Grim

得到木偶。主干与webpack热模块替换一起工作

  •  1
  • Grim  · 技术社区  · 8 年前

    我使用了一个来自 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 调试输出。 当文件发生更改时,我可以看到它根据以下输出重新生成并将更新推送到客户端:

    [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合作?

    1 回复  |  直到 8 年前
        1
  •  5
  •   Mike M    8 年前

    这有点诡计,但你可以用脊梁骨来完成。博客文章是 here that explains it fairly well 。(免责声明,我写的)

    简而言之,您需要明确地告诉您的父视图您可以接受热重新加载,然后您就可以- require 新的热重新加载视图,关闭现有的子视图,然后重新渲染。下面的例子使用了Ampersand,但同样的基本原理也适用于Marionette或香草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;
        }
    });
    

    ```