Webpack用于后端?

Eri*_*Ven 54 heroku node.js webpack

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

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

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

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

Eve*_*tss 59

为什么在节点后端使用webpack

如果我们正在谈论react节点应用程序,你可以构建同构反应应用程序.如果你import在客户端的react app 中使用ES6模块就可以了 - 它们在客户端由webpack捆绑在一起.

但是,当您使用相同的反应模块时问题出现在服务器上,因为节点不支持ES6模块.您可以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)
];
Run Code Online (Sandbox Code Playgroud)

如果您使用webpack --watch它启动此配置将并行构建您的两个文件.编辑前端时,只会frontend-output.js生成特定代码,同样适用于backend-output.js.最好的部分是当您编辑同构反应部分时 - webpack将立即构建两个文件.

您可以在本教程中找到何时使用webpack for node的说明(第4章).

  • @1252748 在 `externals` 中,您应该指定特定于节点环境的模块,例如 `fs`(webpack 将无法编译此模块)。您可以在此处阅读有关内容 https://webpack.js.org/configuration/externals/ 大多数情况下,此插件 https://www.npmjs.com/package/webpack-node-externals 将涵盖所有有问题的节点模块. 像这样使用它:`externals: [require('webpack-node-externals')()]`。 (2认同)

cbd*_*per 9

使用Webpack将所有后端js文件捆绑在一起,我认为这确实没有必要。

我认为你是完全正确的。根本没有必要。我已经研究这个话题有一段时间了。我就这个主题提出了很多问题,直到今天,我还没有找到一个webpackNode.js后端使用的“真正”理由。

我并不是说您不能或不应该设置webpack-dev-server在本地开发后端代码。但您绝对不需要在构建过程中捆绑后端代码。

webpack捆绑包适用于浏览器。看看它的官方文档:Why webpack? 。从历史上看,浏览器从来没有内置的模块系统,这就是您需要webpack. 它基本上在浏览器上实现了一个模块系统。另一方面,Node.js 有一个开箱即用的内置模块系统。

我确实在我的服务器上重复使用了所有前端代码SSR。完全相同的前端文件按原样在我的服务器上运行,没有任何捆绑(它们只是转译,但文件夹结构和文件数量相同)。当然,我将其捆绑在浏览器上运行,但仅此而已。

要在 Node.js 服务器上运行,babel只需使用 , 不使用进行转译即可webpack

["@babel/preset-env", { targets: { node: "12" }}],只需在你的 babel 配置上使用即可。选择后端环境的 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
Run Code Online (Sandbox Code Playgroud)

您可以通过执行以下操作在服务器上完美呈现前端代码:

后端/src/index.tsx

import { renderToString } from "react-dom/server";
import App from "../dist_app/App";

const html = renderToString(<App/>);
Run Code Online (Sandbox Code Playgroud)

我猜这将被视为同构。

如果您path在代码中使用别名,则应该使用babel-plugin-module-resolver


era*_*ros 7

只有几个方面我可以弥补对后端代码使用 webpack 的需要。

ES 模块 ( import)

import在节点中只有实验支持(至少从节点 8 到 15)。但是你不需要使用 webpack 因为它们在 node.js 中工作。只需使用esm它非常轻量级并且没有构建步骤。

棉绒

只需使用eslint,无需使用 webpack。

热重载/重启

您可以nodemon为此使用。这不是热重载,但我认为它更容易处理。我希望我可以参考一个比 nodemon 更轻量级的项目,但它确实可以解决问题。


您分享的博文(现在已经过时)使用 webpack 进行热重载。我认为这是一种矫枉过正,打开了一罐蠕虫,因为现在您必须处理 webpack 配置问题,并且热重载也会导致意外行为。

我们在前端使用 webpack 之类的工具所获得的好处并没有真正转化为后端。

我们在前端捆绑文件的另一个原因是浏览器可以以最佳方式下载它们,以最佳块,缓存破坏,缩小。后端不需要任何这些。

旧的(而且很糟糕,但可能有用)答案

您可以使用自述文件中的 webpack-node-externals

npm install webpack-node-externals --save-dev
Run Code Online (Sandbox Code Playgroud)

在你的 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
    ...
};
Run Code Online (Sandbox Code Playgroud)