我只是想知道,我开始使用Webpack进行一个新项目,到目前为止它工作正常。我几乎会说我比以前用过的Grunt更喜欢它。但现在我很困惑我应该如何使用它和我的Express后端?
请参阅,我正在创建一个带有前端(ReactJS)和后端(ExpressJS)的应用。该应用程序将在Heroku上发布。现在看来我应该使用Webpack和ExpressJS来使用一个命令(前端和后端)启动和运行应用程序。
但是写这篇博文http://jlongster.com/Backend-Apps-with-Webpack--Part-I的人似乎使用Webpack将所有后端js文件捆绑在一起,这在我看来真的没必要。我为什么要捆绑我的后端文件?我想我只想运行后端,查看我的后端文件以进行更改,并使用Webpack的其余功能仅用于前端。
你们如何捆绑前端但同时运行后端nodejs部分?或者是否有任何理由将后端文件与Webpack捆绑在一起?
答案 0 :(得分:55)
如果我们谈论反应和节点应用,您可以构建isomorphic react app。如果您在客户端的react应用程序中使用 import
ES6模块,那么它们也可以在客户端通过webpack捆绑。
但问题是在服务器上,因为node doesn't support ES6 Modules使用相同的反应模块。您可以在节点服务器端使用require('babel/register');
,但它在运行时转换代码 - 它无效。解决这个问题最常见的方法是通过webpack打包后端(你不需要所有代码都可以通过webpack进行转换 - 只有问题,比如本例中的反应)。
JSX 也是如此。
你的webpack配置必须配置数组:一个用于前端,第二个用于后端:
webpack.config.js
const common = {
module: {
loaders: [ /* common loaders */ ]
},
plugins: [ /* common plugins */ ],
resolve: {
extensions: ['', '.js', '.jsx'] // common extensions
}
// other plugins, postcss config etc. common for frontend and backend
};
const frontend = {
entry: [
'frontend.js'
],
output: {
filename: 'frontend-output.js'
}
// other loaders, plugins etc. specific for frontend
};
const backend = {
entry: [
'backend.js'
],
output: {
filename: 'backend-output.js'
},
target: 'node',
externals: // specify for example node_modules to be not bundled
// other loaders, plugins etc. specific for backend
};
module.exports = [
Object.assign({} , common, frontend),
Object.assign({} , common, backend)
];
如果您使用webpack --watch
启动此配置,它将并行构建您的两个文件。编辑前端特定代码时,只会生成frontend-output.js
,backend-output.js
也是如此。最好的部分是当您编辑同构反应部分时 - webpack将立即构建两个文件。
您可以在此tutorial解释中找到何时使用webpack for node(第4章)。
答案 1 :(得分:3)
您可以使用自述文件中的webpack-node-externals:
npm install webpack-node-externals --save-dev
在您的webpack.config.js中:
var nodeExternals = require('webpack-node-externals');
module.exports = {
...
target: 'node', // in order to ignore built-in modules like path, fs, etc.
externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
...
};
答案 2 :(得分:2)
使用 Webpack 将所有后端 js 文件捆绑在一起,我认为这真的没有必要。
我觉得你说的很对。 完全没有必要。我一直在研究这个主题一段时间。我已经就这个主题提出了很多问题,直到今天,我还没有找到一个“真正”的理由让一个人在 webpack
后端使用 Node.js
。< /p>
我并不是说您不能或不应该设置 webpack-dev-server
来在本地开发您的后端代码。但您绝对不需要在构建过程中捆绑后端代码。
webpack
包适用于浏览器。看看它的官方文档:Why webpack?。从历史上看,浏览器从来没有内置的模块系统,这就是您需要 webpack
的原因。它基本上在浏览器上实现了一个模块系统。另一方面,Node.js 有一个开箱即用的内置模块系统。
而且我确实在我的服务器上重复使用了 SSR
的所有前端代码。完全相同的前端文件在我的服务器上按原样运行,没有任何捆绑(它们只是被转换,但文件夹结构和文件数量是相同的)。当然,我将它捆绑在浏览器上运行,仅此而已。
要在您的 Node.js 服务器上运行,只需使用 babel
进行转译,而不使用 webpack
。
只需在您的 babel 配置中使用 ["@babel/preset-env", { targets: { node: "12" }}],
。选择后端环境的 Node 版本。
backend
dist_app // BABEL TRANSPILED CODE FROM frontend/src
dist_service // BABEL TRANSPILED CODE FROM backend/src
src
index.tsx
frontend
src
App.tsx
public // WEBPACK BUNDLED CODE FROM frontend/src
您可以通过以下方式在服务器上完美呈现您的前端代码:
后端/src/index.tsx
import { renderToString } from "react-dom/server";
import App from "../dist_app/App";
const html = renderToString(<App/>);
我猜这会被认为是同构的。
如果您在代码中使用 path
别名,则应使用 babel-plugin-module-resolver。