Code Monkey home page Code Monkey logo

react-isomorphic-boilerplate's Issues

typo

Hi guys,

There some typo error for the description of this repo, I'd like to change it to the one blow, please have a check. Thanks.

😇😇😇 A universal React isomorphic boilerplate for building server-side render web app http://www.jianshu.com/p/0ecd727107bb

全局加载组件

我想在全局加载一个组件,比如底部导航栏
我把它放在client/common/containers/Common.js里,render里代码如下
`



{Children.map(children, child =>
cloneElement(child, {...props})
)}

` 在dev下显示和操作都是没有问题的,但是build完,npm start运行的时候报错 cannot read property 'shape' of undefined cannot read property 'call' of undefined 这应该怎么解决呢?

Redux无法热更新

看了作者的例子受益匪浅,我刚入门webpack,做练习的过程中我也自己用router4+react-loadable仿写了一个demo,但在reducer更改初始值时无法热更新,这是我的demo地址:https://github.com/wd2010/webpack-demo,请大神帮忙看看!

app.js(entry文件)

import React from 'react';
import {hydrate} from 'react-dom';
import configureStore from './store/configureStore';
import createHistory from 'history/createBrowserHistory'
import createApp from './store/createApp';
import Loadable from 'react-loadable';

const initialState = window.__INITIAL_STATE__;
let store=configureStore(initialState)
const history=createHistory()

const render=()=>{
  let application=createApp({store,history});
  hydrate(application,document.getElementById('root'))
}

window.main = () => {
  Loadable.preloadReady().then(() => {
    render()
  });
};

configureStore.js

import {createStore, applyMiddleware,compose} from "redux";
import thunkMiddleware from "redux-thunk";
import createHistory from 'history/createMemoryHistory';
import {  routerReducer, routerMiddleware } from 'react-router-redux'
import {composeWithDevTools} from 'redux-devtools-extension'
import rootReducer from './reducers/index';
const routerReducers=routerMiddleware(createHistory());//路由
const middleware=[thunkMiddleware,routerReducers];

let configureStore=(initialState)=>{
  let store=createStore(rootReducer,initialState,composeWithDevTools(applyMiddleware(...middleware)));
  //热加载配置
if(module.hot) {
    console.log(module.hot.status())
    module.hot.accept('./reducers/index.js', () => {
        store.replaceReducer(rootReducer)
      console.log('=',store.getState())
    });
  }
  return store;
}

export default configureStore;

webpack.config.js

const  ExtractTextWebpackPlugin = require("extract-text-webpack-plugin"),
  HtmlWebpackPlugin=require('html-webpack-plugin'),
  ProgressBarPlugin = require('progress-bar-webpack-plugin');
const path=require('path');
const webpack=require('webpack');
import { ReactLoadablePlugin } from 'react-loadable/webpack';
const DIR_NAME=path.join(__dirname,'../');

const config={
  context: DIR_NAME,
  entry:{
    bundle: ['./client/app.js','webpack-hot-middleware/client?path=/__webpack_hmr'],
    vendor: ['react','react-dom','redux','react-redux'],
  },
  output:{
    path:  path.resolve(DIR_NAME,'./dist/client'),
    filename: '[name].js',
    chunkFilename: 'chunk.[name].js',
    publicPath:'/'
  },

  resolve: {extensions: ['.js', '.jsx' ,'.json', '.scss']},
  module:{
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader:'babel-loader',
          options:{
            presets: ['env', 'react', 'stage-0','react-hmre'],
            plugins: ['transform-runtime', 'add-module-exports','syntax-dynamic-import','react-loadable/babel'],
            cacheDirectory: true,
          }
        }
      },{
        test: /\.html$/,
        exclude:/node_modules/,
        loader: 'html-loader'
      }
    ],
  },
  plugins:[
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
    new ProgressBarPlugin({summary: false}),
    new webpack.optimize.CommonsChunkPlugin({
      names:['vendor','manifest'],
      filename:'[name].js',
    }),
    new HtmlWebpackPlugin({
      filename: '../views/dev/index.html',
      template: './views/tpl/index.html',
      chunks: ['vendor','manifest', 'bundle'],
    }),
    new ReactLoadablePlugin({
      filename: './views/dev/react-loadable.json',

    }),
  ],

}


module.exports=config

clientRouter.js

import React from 'react';
import fs from 'fs';
import path from 'path';
import {renderToString} from 'react-dom/server';
import Loadable from 'react-loadable';
import { getBundles } from 'react-loadable/webpack';
import stats from '../../views/dev/react-loadable.json';
import {routesConfig} from '../../client/routes';
import configureStore from '../../client/store/configureStore';
import createHistory from 'history/createMemoryHistory'
import createApp from '../../client/store/createApp';
import {matchPath} from 'react-router-dom';
import {matchRoutes} from 'react-router-config';
import Helmet from 'react-helmet';

const store=configureStore();


const prepHTML=(data,{html,head,body,scripts,styles,state})=>{
  data=data.replace('<html',`<html ${html}`);
  data=data.replace('</head>',`${head} \n ${styles}</head>`);
  data=data.replace('<div id="root"></div>',`<div id="root">${body}</div>`);
  data=data.replace('<body>',`<body> \n <script>window.__INITIAL_STATE__ =${JSON.stringify(state)}</script>`);
  data=data.replace('</body>',`${scripts}</body>`);
  return data;
}

const markup=({ctx})=>{
  let modules = [];
  const history=createHistory({initialEntries:[ctx.req.url]})
  let state=store.getState();
  let appString= renderToString(
    <Loadable.Capture report={moduleName => modules.push(moduleName)}>
      {createApp({store,history})}
    </Loadable.Capture>
  )

  let bundles = getBundles(stats, modules);
  let scriptfiles = bundles.filter(bundle => bundle.file.endsWith('.js'));
  let stylefiles = bundles.filter(bundle => bundle.file.endsWith('.css'));

  let scripts=scriptfiles.map(script=>`<script src="/${script.file}"></script>`).join('\n');
  let styles=stylefiles.map(style=>`<link href="/${style.file}" rel="stylesheet"/>`).join('\n');

  let filePath=path.join(__dirname,'../../views/dev/index.html')
  let htmlData=fs.readFileSync(filePath,'utf-8');

  const helmet=Helmet.renderStatic();

  let renderedHtml=prepHTML(htmlData,{
    html:helmet.htmlAttributes.toString(),
    head:helmet.title.toString()+helmet.meta.toString()+helmet.link.toString(),
    body:appString,
    scripts:scripts,
    styles:styles,
    state
  })

  return renderedHtml
}

const getMatch=(routesArray, url)=>{
  return routesArray.some(router=>matchPath(url,{
    path: router.props.path,
    exact: router.props.exact,
  }))
}

const clientRouter=async(ctx,next)=>{
  let isMatch=getMatch(routesConfig,ctx.req.url);

  if(isMatch){
    let renderedHtml=markup({ctx});
    ctx.body=renderedHtml
  }else{
    await next()
  }
}

export default clientRouter;

更改reducer初始值时,console.log输出值

[HMR] connected
    bundle.js:6781 [HMR] bundle rebuilding
    bundle.js:6789 [HMR] bundle rebuilt in 180ms
    bundle.js:7715 [HMR] Checking for updates on the server...
    bundle.js:7788 [HMR] Updated modules:
    bundle.js:7790 [HMR]  - ./client/store/reducers/home.js
    bundle.js:7790 [HMR]  - ./client/store/reducers/index.js
    bundle.js:7795 [HMR] App is up to date.
    bundle.js:6781 [HMR] bundle rebuilding
    bundle.js:6789 [HMR] bundle rebuilt in 195ms
    bundle.js:7715 [HMR] Checking for updates on the server...
    bundle.js:7788 [HMR] Updated modules:
    bundle.js:7790 [HMR]  - ./client/store/reducers/home.js
    bundle.js:7790 [HMR]  - ./client/store/reducers/index.js
    bundle.js:7795 [HMR] App is up to date.
    bundle.js:6781 [HMR] bundle rebuilding
    bundle.js:6789 [HMR] bundle rebuilt in 175ms
    bundle.js:7715 [HMR] Checking for updates on the server...
    bundle.js:7788 [HMR] Updated modules:
    bundle.js:7790 [HMR]  - ./client/store/reducers/home.js
    bundle.js:7790 [HMR]  - ./client/store/reducers/index.js
    bundle.js:7795 [HMR] App is up to date.

小白求问要怎么访问后台接口api,想通过koa发请求

async function getMessageList(ctx) {
ctx.url=HOST+'/message/query';
ctx.method='POST';
ctx.query= {


userId:'13145674567',
entId:'2',
startDate:'2016-10-10',
endDate:''
};
let messages =ctx.request.body || 0;
ctx.body = "you post data:"+JSON.stringify({messages:messages});
}

比如这个,配置了server端的routes,不知道controllers该怎么写

Crawler is unable to access data

After retrieving the data,
When going to the page source(command + option + U) it is showing {userinfo: null}. Can you please tell why this is happening.

server/middlewares/clientRoute.js中路由匹配match()函数问题前是否要加await操作符?

match({routes,location:ctx.url},(error,redirectLocation,renderProps)=>{ _renderProps=renderProps })
改为:
await match({routes,location:ctx.url},(error,redirectLocation,renderProps)=>{ _renderProps=renderProps })
我使用你个这脚手架,学习开发一个小项目,运行npm run dev ,浏览器可以正常访问。
但是构建后,执行npm start,页面提示Not found!
经过调试发现,在match函数回调中为_renderProps赋值。在match返回前继续往下运行,提示not found。
奇怪的是开发模式下正常,这是为什么呢?

在开发模式下的一些问题

按着你的思路正在实现一个 boilerplate,发现一些问题,nodemon 只是在监听 server 目录下的代码,但是 server 也承担着服务器渲染的工作,会用到 client 下的代码,所以说会出现下面的一些问题:

  1. 本来客户端代码就有错误,此时运行服务器会崩溃,此时就算改正 client 下的代码也没有用,因为 nodemon 监听的是 server 下的代码,这时必须自己重启服务器
  2. 正常运行之后,修改客户端代码可以实现热替换,但如果刷新一个页面,会从服务器端拉取数据,服务器端返回的还是之前没有修改过代码生成的html,接着React 会发现服务器端返回的跟客户端返回的出现不一致,发出一个警告,如下:

2017-01-05 11 29 42

更新:

看了一下 README 提到了上面的问题,这个问题没有什么解决办法么?😑

服务端请求数据问题

请问这个在服务端是如何请求数据的,看了半天没明白,
因为window.REDUX_STATE 一直是空的

getUrlParams is not defined

运行环境

OSX(10.12)
node(v6.9.4)
npm(3.10.10)

错误截图

[nodemon] starting `node ./server/server.dev.js`
/Users/****/Workspace/react-isomorphic-boilerplate/client/shared/utils.js:61
    getUrlParams: getUrlParams
                  ^

ReferenceError: getUrlParams is not defined
    at Object.<anonymous> (/Users/****/Workspace/react-isomorphic-boilerplate/client/shared/utils.js:51:5)
    at Module._compile (module.js:570:32)
    at loader (/Users/****/Workspace/react-isomorphic-boilerplate/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/****/Workspace/react-isomorphic-boilerplate/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/Users/****)/Workspace/react-isomorphic-boilerplate/client/common/actions/index.js:2:1)
    at Module._compile (module.js:570:32)
    at loader (/Users/****/Workspace/react-isomorphic-boilerplate/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (/Users/****/Workspace/react-isomorphic-boilerplate/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)

代码截图

function getURLParams() {
    const search = location.search.slice(1),
        rParam = /([^&]*)=([^&]*)/g
    let ret = {},
        param

    while (param = rParam.exec(search)) {
        ret[param[1]] = param[2]
    }

    return ret
}

export default {
    ajax,
    getURLParams
}

getURLParams原本为getUrlParams,修改为getURLParams后可以成功运行。

根据模板生成服务器端字符串后 如何更新js或css缓存

请问服务器端生成react渲染后的字符串 然后和模板混合 send到客户端上,请问 模板上的js 和css文件名字都是写死的 第一次发布完毕后 再次发布会有缓存 如何解决这个问题呢,如果客户端不清空缓存则新的样式或js不生效呀

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.