react-isomorphic-boilerplate
react-isomorphic-boilerplate copied to clipboard
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。
奇怪的是开发模式下正常,这是为什么呢?
await关键字后面跟的只能是一个Promise对象
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/await,如果这个值不是一个 promise,那么会把它转换成一个已经 resolved 的 promise,并且等待它。这里match确实是异步的,_renderProps在回调中被赋值,在赋值前,程序如果继续往下执行,会出问题啊。这个项目,没有出现问题,但是我用这个框架做一个demo时,确实出了问题。
match本身是一个同步方法,不涉及网络请求与文件操作,可以在代码match函数内外console.log查看执行顺序
方便上传项目源码吗
我就是用console.log发现的这个问题。很奇怪的是,在dev模式没有这个问题。源码在这https://github.com/sivkun/myplayer-isomorphic。
https://github.com/ReactTraining/react-router/issues/4677 产生原因:webpack2与webpack1对require.ensure的打包机制处理方式不同
谢谢,我看一下
审查webpack打包后的代码,可以看到 webpack1中require.ensure原型是
/******/ __webpack_require__.e = function requireEnsure(chunkId, callback) {
/******/ // "1" is the signal for "already loaded"
/******/ if(!installedChunks[chunkId]) {
/******/ var chunk = require("./chunk." + ({"1":"home","2":"explore","3":"about"}[chunkId]||chunkId) + ".js");
/******/ var moreModules = chunk.modules, chunkIds = chunk.ids;
/******/ for(var moduleId in moreModules) {
/******/ var _m = moreModules[moduleId];
/******/ // Check if module is deduplicated
/******/ switch(typeof _m) {
/******/ case "object":
/******/ // Module can be created from a template
/******/ modules[moduleId] = (function(_m) {
/******/ var args = _m.slice(1), templateId = _m[0];
/******/ return function (a,b,c) {
/******/ modules[templateId].apply(this, [a,b,c].concat(args));
/******/ };
/******/ }(_m));
/******/ break;
/******/ case "function":
/******/ // Normal module
/******/ modules[moduleId] = _m;
/******/ break;
/******/ default:
/******/ // Module is a copy of another module
/******/ modules[moduleId] = modules[_m];
/******/ break;
/******/ }
/******/ }
/******/ for(var i = 0; i < chunkIds.length; i++)
/******/ installedChunks[chunkIds[i]] = 1;
/******/ }
/******/ callback.call(null, __webpack_require__);
/******/ };
webpack2的require.ensure原型是
/******/ __webpack_require__.e = function requireEnsure(chunkId) {
/******/ // "0" is the signal for "already loaded"
/******/ if(installedChunks[chunkId] !== 0) {
/******/ var chunk = require("./" + chunkId + ".bundle.js");
/******/ var moreModules = chunk.modules, chunkIds = chunk.ids;
/******/ for(var moduleId in moreModules) {
/******/ modules[moduleId] = moreModules[moduleId];
/******/ }
/******/ for(var i = 0; i < chunkIds.length; i++)
/******/ installedChunks[chunkIds[i]] = 0;
/******/ }
/******/ return Promise.resolve();
/******/ };
webpack1直接调用回调函数,webpack2返回的是个promise
我也遇到了上面的问题,但我改为一下:
if(typeof require.ensure !=='function'){
require.ensure = function(dependencies,callback){
setTimeout(function() {
callback(require)
});
}
}
还是无法解决,match的回调还是后执行,不知道有没有其他方法呢~谢谢