【问题标题】:Webpack Aliases in Node JS Server codeNode JS 服务器代码中的 Webpack 别名
【发布时间】: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 别名到另一个文件,比如 componentscontainers 所以很自然,节点 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


【解决方案1】:

在与这个问题斗争了 2 天后,我选择了 babel-plugin-webpack-alias。 What you need to do 解析路径是:

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

我尝试的另一个选项是universal-webpack,但我发现它有点冗长。如果你想大致了解整个服务器端加载是如何工作的,可以查看this video

【讨论】:

  • babel-plugin-webpack-alias 有效,但似乎打破了 Jest。将此插件隔离到 Babel 的 development 环境(通过 env 配置键)为我解决了这个问题
【解决方案2】:

如果你真的想要它们,通过 babel 运行你的服务器端代码并​​使用这个插件:https://www.npmjs.com/package/babel-plugin-module-alias 它可以让你做和 webpack 一样的事情。

编辑:这个效果更好:https://github.com/jagrem/babel-resolve-relative-module 它允许多条路径

【讨论】:

  • 不使用它们的原因是什么?
  • 这似乎会导致问题,而且您必须依赖至少在服务器上使用一个插件,并且可能通过 Babel 运行您的整个代码库。我想这很好,但如果你引入 Babel 的唯一原因是为了别名,那似乎需要做很多工作
  • 感谢您链接到那个 Babel 插件!我没想过要在 Babel 方面寻找混叠。这对我帮助很大!
【解决方案3】:

尝试使用NODE_PATH。在 require 调用期间,Node 将始终在此路径中查找模块。它允许根据需要缩短相对路径。

// turn this
import {Widget} from '../../components';

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

更多信息请参见Node.js docs

附注这东西很敏感,所以要小心使用。现在您的代码与环境紧密相关,可能会在某处中断。

【讨论】:

    【解决方案4】:

    如果您使用 webpack-isomorphic-tools,那么它会将您的 webpack 配置考虑到您的服务器端,这将使您的所有别名都工作。

    https://www.npmjs.com/package/webpack-isomorphic-tools

    【讨论】:

      猜你喜欢
      • 2018-07-18
      • 2018-02-05
      • 2018-06-11
      • 2018-08-17
      • 2018-04-22
      • 2023-03-09
      • 2016-03-10
      • 2017-07-05
      • 2015-03-01
      相关资源
      最近更新 更多