Ошибка зависимости HMR от шаблона проектирования фасада реагирования

При переходе к маршрутизатору Redux-first в моем шаблонном проекте activjs redux webpack заметил, что HMR перестал работать!

Итак, я пытаюсь понять, как работают зависимости на HMR accept метод и почему простой вызов module.hot.accept() вместо указания зависимостей и обратного вызова успешен (при избыточном вызове возникает ошибка миграции 2.0, поскольку провайдер не поддерживает изменение хранилища на лету).

Я потратил много времени на исследования, но не смог найти решения по этому поводу, поэтому планировал вернуться к своему маршрутизатору 4, где мой шаблон проектирования фасада работает нормально.

введите описание изображения здесь

У меня было это работает с React router 4, который я также использовал тот же шаблон фасада для организации моих компонентов реагирования и файлов редуксов.

введите описание изображения здесь

Запись приложения:

import React from 'react'
import { render } from 'react-dom'
import { AppContainer as HotReload } from 'react-hot-loader'
import configureStore from './root/store'
import { createBrowserHistory } from 'history'

const MainApi = require('./modules/main').default
const App = MainApi.containers.App    
const history = createBrowserHistory()
const store = configureStore(history)

// render method for instantiation and Hot module reload
const renderApp = (RootComponent) => {
  let rootEl = document.getElementById('app')
  render(
    <HotReload>
      <RootComponent store={store} history={history} />
    </HotReload>,
    rootEl
  )
}

// create instance
renderApp(Root)

// Hot Module Replacement API
if (process.env.NODE_ENV === 'development' && module.hot) {
  module.hot.accept('./modules/main/containers/app', () => {
    const App = require('./modules/main/containers/app').default
    renderApp(App)
  })
}

if (process.env.NODE_ENV === 'production') {
  require('offline-plugin/runtime').install()
}

Единственный способ убедиться в его работоспособности - принять без указания каких-либо зависимостей и обратного вызова. Результатом этого является предупреждение Redux о переходе на 2.0

if (module.hot) {
  module.hot.accept()
}

введите описание изображения здесь

Хотя я понимаю, что проблема может быть связана с "зависимостями", переданными hot.module.accept(dependencies, callback)на основании списка updated modulesих указание, по-видимому, не решает проблему во время тестирования и наблюдения (TIAS).

Ради вас, я поделюсь, как организованы модули ниже.

введите описание изображения здесь

А также

введите описание изображения здесь

Как модуль раскрывает API модуля:

введите описание изображения здесь

Корневой редуктор:

введите описание изображения здесь

Корневое хранилище или configureStore:

import { createStore, applyMiddleware, combineReducers, compose } from 'redux'
import { composeWithDevTools } from 'redux-devtools-extension/logOnlyInProduction'
import { connectRoutes } from 'redux-first-router'
import routes from './routes'
import rootReducer from './reducer'
import AboutApi from 'modules/about'

// TODO: combine all the modules actions
const actionCreators = AboutApi.actions
const composeEnhancers = (...args) =>
  typeof window !== 'undefined'
    ? composeWithDevTools({ actionCreators })(...args)
    : compose(...args)

export default (history, preloadedState) => {
  const routerSetup = connectRoutes(history, routes.map, routes.options)
  const combinedReducers = combineReducers({ ...rootReducer, location: routerSetup.reducer })
  const middlewares = applyMiddleware(routerSetup.middleware)
  const enhancers = composeEnhancers(routerSetup.enhancer, middlewares)
  const store = createStore(combinedReducers, preloadedState, enhancers)

  if (module.hot) {
    module.hot.accept('./reducer', () => {
      const rootReducer = require('./reducer')
      const combinedReducers = combineReducers({ ...rootReducer, location: routerSetup.reducer })
      store.replaceReducer(combinedReducers)
    })
  }

  return { store, thunk: routerSetup.thunk }
}

Следующая шаблонная / демонстрационная программа "Первый редуктор" работает, но не использует один и тот же шаблон проектирования фасада для организации файлов реакции и редукции ( https://github.com/faceyspacey/redux-first-router-demo/tree/master/src)

Файл конфигурации разработки веб-пакета:

var path = require('path')
var webpack = require('webpack')
var AssetsPlugin = require('assets-webpack-plugin')
var assetsPluginInstance = new AssetsPlugin({ path: path.resolve(__dirname), update: true })
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var rootDir = path.resolve(__dirname, '../')

module.exports = {
  context: path.resolve(rootDir, 'src'),
  entry: [
    'babel-polyfill',
    // 'webpack-hot-middleware/client',
    'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=false&quiet=false&noInfo=false',
    'react-hot-loader/patch',
    'webpack/hot/dev-server',
    path.join(rootDir, '/src/js/index.js')
  ],
  output: {
    path: path.join(rootDir, '/dist/development'),
    publicPath: '/assets/',
    filename: 'js/bundle.js?[hash]'
  },
  devtool: 'inline-source-map',
  devServer: {
    hot: true,
    // match the output path
    contentBase: path.join(rootDir, '/dist/development'),
    // match the output `publicPath`
    publicPath: '/assets/'
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /(node_modules)/,
        use: [{
          loader: 'babel-loader'
        }]
      },
      {
        test: /\.scss$/,
        use: ['css-hot-loader'].concat(ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [{
            loader: 'css-loader'
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
              includePaths: [
                path.join(rootDir, 'node_modules')
              ],
              outputStyle: 'compressed'
            }
          }]
        }))
      },
      {
        test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
        use: [
          'file-loader?name=[path][name].[ext]'
        ]
      },
      {
        test: /\.(jpg|png|gif|svg)$/i,
        use: [
          'file-loader?name=[path][name].[ext]&emitFile=false'
        ]
      },
      {
        test: /\.(webm|mp4)$/,
        use: [
          'file-loader?name=[path][name].[ext]&emitFile=false'
        ]
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('css/[name].min.css?[hash]'),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('development')
      }
    }),
    assetsPluginInstance
  ]
}

0 ответов

Другие вопросы по тегам