Webpack在Node JS服务器代码中的别名配置

12

我正在构建一个同构的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别名指向另一个文件,比如componentscontainers,因此自然情况下,node js require系统无法解析它。

我该如何解决这样的问题?我查看了这个问题,它讨论了基本上设置与webpack相同的别名,用mock-require实现。但问题在于我的路由文件导入了所有组件,然后所有组件都导入像样式表、图像等东西。那我应该使用类似于webpack-isomorphic-tools的东西吗?

我一直在查看的指南(例如此处)都很好地展示了如何实现服务器端渲染,但它们都没有讨论如何解析所有requires等内容。


为什么不应该使用别名? - barndog
当你使用webpack进行构建时,别名是可以的。你的问题是因为你在webpack构建中使用了别名,并试图让相同的代码在webpack构建之外工作。我的观点是,要使用别名,你需要构建你的服务器代码(这将使别名正常工作)。没有构建,让别名工作的唯一方法就是把它们拼凑在一起,这就是你的问题所在。拼凑是不好的,所以使用别名并构建你的服务器代码,或者放弃别名。 - Josh David Miller
那么使用类似 webpack-isomorphic-tools 这样的工具就不是问题了,因为它支持别名,适用于服务器和客户端代码。 - barndog
我无法对那个工具发表意见,因为我从未需要使用它。在我看来,它似乎是我建议你避免的那种非常规方法。但是,在这次来回交流和下面答案的讨论之后,我真的不确定对于你的问题一个有效的答案是什么。是否有一个?你希望从SO社区中得到什么? - Josh David Miller
1
我在Gist上放了我的别名文件、所有配置文件以及package.json中的脚本。有很多文件,每个服务器和客户端都有四个(基础配置、开发配置、生产配置、生产入口文件和开发入口文件),还有一个基础配置文件和通用webpack配置文件。我没有把它们全部放在Gist上(我还没有设置生产配置),但这应该是一个不错的开始。 - barndog
显示剩余10条评论
4个回答

6

在为期两天的挣扎后,我选择了babel-plugin-webpack-alias来解决这个问题。要解决路径问题,您需要执行以下操作

  1. $ npm install --save-dev babel-plugin-webpack-alias
  2. 将插件添加到您的 .babelrc 文件中
  3. 将别名添加到您的 webpack.config 中(确保使用 path.join()
  4. 如果您在加载样式时遇到问题,请参考此帖子

我尝试的另一个选项是universal-webpack,但我发现它有点啰嗦。如果您想大致了解整个服务器端加载的工作原理,可以查看此视频


babel-plugin-webpack-alias 可以使用,但似乎会破坏 Jest。通过将此插件隔离到 Babel 的 development 环境(通过 env 配置键)可以解决这个问题。 - FeifanZ

1

不使用它们的理由是什么? - barndog
1
它似乎只会引起问题,而且你必须依赖于至少在服务器上使用插件,并且可能需要通过Babel运行整个代码库。我想这没关系,但如果你引入Babel的唯一原因是为了别名,那么看起来需要做很多工作。 - zackify
感谢您链接到那个 Babel 插件!我没有想到在别名方面要去查找 Babel 的相关内容。这对我帮助很大! - Kevin

0

0
尝试使用NODE_PATH。Node在进行require调用时,将始终在此路径中查找模块。这允许您根据需要缩短相对路径。
// turn this
import {Widget} from '../../components';

// into this
import {Widget} from 'components';

请查看Node.js文档以获取更多信息。

附言:此功能非常敏感,因此请谨慎使用。现在您的代码紧密依赖于环境,并且可能会在某些地方出现故障。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接