【发布时间】:2016-04-13 12:39:46
【问题描述】:
我正在构建一个同构的 React/React-Router/Redux/Webpack 应用程序,并且我正在尝试实现服务器端渲染。
我的目录如下:
/client
/actions
/components
/containers
/server
/server.js
在我的 webpack 配置中,我为客户端内的所有文件夹设置了别名:
var path_base = path.resolve(__dirname, '..');
const resolve = path.resolve;
const base = function() {
var args = [path_base];
args.push.apply(args, arguments);
return resolve.apply(resolve,args);
};
const resolve_alias = base.bind(null, 'src/client');
const aliases = [
'actions',
'components',
'constants',
'containers',
'middleware',
'reducers',
'routes',
'store',
'styles',
'utils',
'validation'
];
这样在被 webpack 捆绑的代码中,我可以这样做:
import { Widget } from 'components';
并且该导入由 webpack 解决。
现在在我的服务器代码中,为了进行渲染,我必须导入一些客户端文件,例如 routes/index.js。我在导入路由文件时遇到的问题,它使用 webpack 别名到另一个文件,比如 components 或 containers 所以很自然,节点 js 要求系统无法解决它。
我该如何解决这样的问题?我查看了this question,它谈到了使用mock-require 设置webpack 中存在的相同别名。但是问题就变成了我的路由文件导入了我的所有组件,然后所有组件都导入了样式表、图像等内容。然后我应该使用webpack-isomorphic-tools之类的东西吗?
我一直在看的指南(例如this)都很好地展示了如何完成服务器端渲染,但没有一个真正谈论如何解决所有需求等等。
【问题讨论】:
-
听起来这里有几个问题:(a)在运行服务器端时如何使用别名,以及(b)如何在服务器上处理包含的资源,如样式表。一种解决方案是也通过 webpack 运行您的服务器代码。您可以在配置中使用
target: node,它会在构建期间针对节点优化它(即它不会捆绑节点包含)。我有时会为使用 Babel 的代码执行此操作。如果不进行构建,绝对不要使用别名。任何解决方案充其量都是hacky。 -
为什么我不能使用别名?
-
使用 webpack 进行 build 时,别名很好。您的问题是因为您在 webpack 构建中使用别名并试图让相同的代码在 outside webpack 构建中工作。我的观点是,要使用别名,您还需要构建服务器代码(这将使别名正常工作)。如果没有构建,让别名起作用的唯一方法是将它组合在一起,这就是您的问题所在。黑客是不好的,所以使用别名并构建你的服务器代码,或者干脆放弃别名。
-
那么使用 webpack-isomorphic-tools 之类的东西应该不成问题,因为它支持服务器和客户端代码的别名。
-
gist.github.com/startupthekid/3223a866616b6dc59e4d5d4fc03275a7。我包含了我的别名文件、所有配置,然后是我的 package.json 中的脚本。有很多文件,服务器和客户端各有四个(基本配置、开发配置、生产配置、生产入口文件和开发入口文件),然后是一个基本配置文件以及通用 webpack 配置文件。我没有把它们都放在要点里(我还没有设置生产配置),但这对你来说应该是一个好的开始
标签: node.js reactjs webpack redux