jjzjj

javascript - 热模块更换——更新但不重新渲染

coder 2024-05-14 原文

我正在运行一个快速服务器,它将充当我的 React 应用程序的 API,该应用程序由 webpack-dev-server 捆绑和提供服务。

我正在尝试让热模块替换正常工作,并且快完成了,当我更改我的文件时,我在控制台中得到了这个:

但除非手动刷新,否则应用永远不会重新呈现。不知道这是否相关,但是当我更新我的 .scss 文件时,它会在不手动执行的情况下进行刷新,并按我的预期进行更新。

版本:

"webpack": "2.1.0-beta.22"

"webpack-dev-server": "2.1.0-beta.8"

"react-hot-loader": "3.0.0-beta.5"

我尝试了最新的 webpack,但它给了我无法克服的验证错误。

我正在通过以下方式运行 webpack:"webpack": "webpack-dev-server --port 4000 --env.dev",我的 express 服务器正在 http://localhost:3000.

这是我的webpack.config.babel.js:

const webpack = require('webpack');
const { resolve, join } = require('path');
const { getIfUtils, removeEmpty } = require('webpack-config-utils')

const getEntry = (ifDev) => {
  let entry

  if (ifDev) {
    entry = {
      app: [
        'react-hot-loader/patch',
        'webpack/hot/dev-server',
        'webpack-dev-server/client?http://localhost:4000/',
        './js/index.js'
      ],
      vendor: ['react']
    }
  } else {
    entry = {
      bundle: './js/index.js',
      vendor: ['react']
    }
  }

  return entry
}

const config = env => {
  const { ifProd, ifDev } = getIfUtils(env)

  return {
    entry: getEntry(ifDev),
    output: {
      path: resolve('./public/dist/'),
      publicPath: 'http://localhost:4000/',
      filename: '[name].bundle.js',
    },
    context: resolve(__dirname, 'assets'),
    devtool: env.prod ? 'source-map' : 'eval',
    devServer: {
      contentBase: resolve('./public/dist/'),
      headers: { 'Access-Control-Allow-Origin': '*' },
      publicPath: 'http://localhost:4000/',
      hot: true,
      noInfo: true,
      inline: true
    },
    bail: env.prod,
    module: {
      loaders: [
        { test: /\.scss$/, loaders: [ 'style', 'css', 'sass' ], exclude: /node_modules|lib/ },
        { test: /\.(js|jsx)$/, exclude: /node_modules/, loaders: [ 'babel-loader' ] },
        { test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, loader: 'file-loader' }
      ]
    },
    resolve: {
      extensions: ['.js', '.jsx']
    },
    plugins: removeEmpty([
      ifDev(new webpack.NoErrorsPlugin()),
      ifDev(new webpack.NamedModulesPlugin()),
      ifDev(new webpack.HotModuleReplacementPlugin()),

      new webpack.DefinePlugin({
        'process.env': { NODE_ENV: JSON.stringify((env.prod) ? 'production' : 'development') }
      }),
      new webpack.optimize.CommonsChunkPlugin({
        name: 'vendor',
        minChunks: Infinity,
        filename: 'vendor.bundle.js'
      }),

      ifProd(new webpack.LoaderOptionsPlugin({
        minimize: true,
        debug: false
      })),
      ifProd(new webpack.optimize.UglifyJsPlugin({
        compress: { warnings: false },
        output: { comments: false },
        sourceMap: false
      }))
    ]),
  }
}

module.exports = config

这是我的 .babelrc,我在其中调用了 react-hot-loader

{
  "presets": [["es2015", { modules: false }], "stage-0", "react"],
  "plugins": ["react-hot-loader/babel"],
  "env": {
    "test": {
      "plugins": ["istanbul"],
      "presets": ["es2015", "stage-0", "react"]
    }
  },
  "sourceMaps": "inline"
}

最佳答案

借助 React Hot Loader v3 和 Babel 转换,您希望在组件的根目录(进行渲染或创建 Redux 提供程序的位置)执行此操作:

render(
  <AppContainer>
    <Root
      store={ store }
    />
  </AppContainer>,
  document.getElementById('root')
);

if (module.hot) {
  module.hot.accept('./containers/Root', () => {
    const RootContainer = require('./containers/Root').default;
    render(
      <AppContainer>
        <RootContainer
          store={ store }
        />
      </AppContainer>,
      document.getElementById('root')
    );
  });
}

使用新版本的 Hot Loader,您必须使用 module.hot.accept 明确接受热更新。

在更复杂的 Redux 项目中(带有路由和热重载 reducer),你可以这样做:

/**
 * Starts the React app with the Router, and renders it to the given DOM container
 * @param  {DOMElement} container
 */
export default function app(container) {
  const store = createStore(
    combineReducers({
      ...reducers,
      routing: routerReducer,
      form: formReducer,
    }),
    compose(
      applyMiddleware(
        routerMiddleware(hashHistory),
        thunkMiddleware,
        promiseMiddleware
      ),
      process.env.NODE_ENV !== 'production' && window.devToolsExtension ? window.devToolsExtension() : (param) => param
    )
  );

  if (module.hot) {
    module.hot.accept('./reducers', () => {
      const nextReducers = require('./reducers');
      const nextRootReducer = combineReducers({
        ...nextReducers,
        routing: routerReducer,
        form: formReducer,
      });
      store.replaceReducer(nextRootReducer);
    });
  }

  const history = syncHistoryWithStore(hashHistory, store);

  render({ store, history, container });

  store.dispatch(loadEventsWhenLoggedIn());

  if (module.hot) {
    module.hot.accept('./render', () => {
      const newRender = require('./render').default;
      newRender({ store, history, container });
    });
  }
}

(和 render.js)

/**
 * Starts the React app with the Router, and renders it to the given DOM container
 * @param  {DOMElement} container
 */
export default function render({ store, history, container }) {
  ReactDOM.render(
    <Provider store={store}>
      <div className='container'>
        <Routes history={history} store={store} />
      </div>
    </Provider>,
    container
  );
}

有关更多示例,您应该查看 Dan Abramov 的 Redux devtools 示例存储库,例如此文件:https://github.com/gaearon/redux-devtools/blob/master/examples/todomvc/index.js

关于javascript - 热模块更换——更新但不重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40058514/

有关javascript - 热模块更换——更新但不重新渲染的更多相关文章

  1. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  4. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  5. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  6. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  7. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  8. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  9. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  10. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

随机推荐