Node JS 服务器代码中的 Webpack 别名
Posted
技术标签:
【中文标题】Node JS 服务器代码中的 Webpack 别名【英文标题】:Webpack Aliases in Node JS Server code 【发布时间】: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 配置文件。我没有把它们都放在要点里(我还没有设置生产配置),但这对你来说应该是一个好的开始
【参考方案1】:
在与这个问题斗争了 2 天后,我选择了 babel-plugin-webpack-alias。 What you need to do 解析路径是:
$ npm install --save-dev babel-plugin-webpack-alias
将插件添加到您的 .babelrc 中
将别名添加到您的 webpack.config(确保使用 path.join()
)
如果您在加载样式时遇到问题,请参阅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
【讨论】:
以上是关于Node JS 服务器代码中的 Webpack 别名的主要内容,如果未能解决你的问题,请参考以下文章
Node.js / npm / yarn / Vue / webpack 概念介绍
72.vue开发工具node.js以及构建工具webpack
无法访问我的站点中的链接(复制和粘贴):Node.js - Express.js - Webpack - Vue.js - 历史模式
第562期用 webpack 构建 node 后端代码,使其支持 js 新特性并实现热重载
Node.js - 在 Server.js 上执行 Node 命令(Express + React + Webpack)