Webpack用于后端?

时间:2016-06-13 11:05:07

标签: node.js heroku webpack

我只是想知道,我开始使用Webpack进行一个新项目,到目前为止它工作正常。我几乎会说我比以前用过的Grunt更喜欢它。但现在我很困惑我应该如何使用它和我的Express后端?

请参阅,我正在创建一个带有前端(ReactJS)和后端(ExpressJS)的应用。该应用程序将在Heroku上发布。现在看来我应该使用Webpack和ExpressJS来使用一个命令(前端和后端)启动和运行应用程序。

但是写这篇博文http://jlongster.com/Backend-Apps-with-Webpack--Part-I的人似乎使用Webpack将所有后端js文件捆绑在一起,这在我看来真的没必要。我为什么要捆绑我的后端文件?我想我只想运行后端,查看我的后端文件以进行更改,并使用Webpack的其余功能仅用于前端。

你们如何捆绑前端但同时运行后端nodejs部分?或者是否有任何理由将后端文件与Webpack捆绑在一起?

3 个答案:

答案 0 :(得分:55)

为什么在节点后端使用webpack

如果我们谈论反应节点应用,您可以构建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.jsbackend-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