如何使用 Webpack 捆绑 Express Js (NodeJs) 和 Pug 引擎?

Posted

技术标签:

【中文标题】如何使用 Webpack 捆绑 Express Js (NodeJs) 和 Pug 引擎?【英文标题】:How can I bundle Express Js (NodeJs) and Pug engine using Webpack? 【发布时间】:2021-04-07 14:55:50 【问题描述】:

简介: 我使用 ExpressJs 框架,节点作为服务器,pug 作为模板引擎。我想捆绑 .js 、 .pug 和 .css。

我知道 webpack (module bundler) 配置静态文件 (CSR-client side rendering) 。对于 CSR 方法,我们将遵循以下步骤。

    使用 webpack 打包所有文件 使用服务器(iis / npm serve 或任何其他选择)托管 html 和 bundle.js(之前由 webpack 创建)

所以,我尝试了与 ExpressJs 相同的方法,即(s-s-r-服务器端渲染),webpack 捆绑了所有文件不包括 NodeModules,包括包含服务器的 index.js (nodeJs)。

对吗?如果是这样,如何使用 index.js 中的捆绑主机来提供文件? 如果这完全是错误的,您能否提出一些好的做法?

index.js

var express = require('express');
var cookieParser = require('cookie-parser');//cookie Parser
var bodyParser = require('body-parser');//JSON data

//Inbuild Functions
const userManagementRoutes = require('./src/routes/userManagementRoutes');
const app = express();

//view Engine
app.set('view engine', 'pug');
app.set('views', './src/views/userManagement');

//for cookie parser
app.use(cookieParser());

// for parsing application/xwww-form-urlencoded
app.use(bodyParser.urlencoded( extended: true )); 

//Static File Server
app.use('/Malips', express.static('public'));

//Routes
app.use('/', userManagementRoutes)

//server
app.listen(3000);

src\routes\UserManagementRoutes.js

const express = require('express');
const loginController = require('../controllers/userManagement/loginController');

const router = express.Router();

router.get('/', function(req, res)
    res.render('app.pug');
);

router.get('/Login', function(req, res)
    res.render('login.pug');
);

router.post('/Login', function(req, res)
    const  userName, password  = req.body;
    if(loginController(userName, password))
        res.render('home.pug',userName : userName);
    
    else
        res.render('login.pug',errorMessage : 'Invalid Credentials');
    
);

module.exports  = router;

src\controller\userManagement\LoginController

module.exports = function LoginController(userName, password)

    if(userName == 'admin@gmail.com' && password == 'admin')
        return true;

    else
        return false;    

src\views\userManagement\Login.pug

extends _layout.pug
block content
    div 
    form(action="/Login", method="post")
        label UserName
        br 
        input(type='email', name = 'userName' required autofocus)
        br
        label Password
        br
        input(type='text' name = 'password' required autofocus)
        br
        input(type="submit")
        h3 #errorMessage

package.json

  "scripts": 
    "start": "nodemon index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  ,

【问题讨论】:

为什么首先要捆绑服务器端节点代码?这没有意义,也不可能。 Webpack 用于将客户端 JS 代码模块捆绑到单个脚本中,因为浏览器对模块的支持尚未最终确定。我认为唯一有意义的服务器端捆绑类型是将脚本和样式表作为内联元素插入到提供的 HTML 文件中。 明确一点:您的 express 应用程序是一个用 JS 编写并由节点运行的程序(只是碰巧会回复传入的 http 请求)。它不以任何方式“服务”;它只是位于硬盘驱动器上的一堆脚本和资源,由 node.exe 读取和执行。捆绑它什么也得不到;要发布您的服务器端代码,您通常会将其放在 git 存储库中,这些代码通常包含数十个(如果不是数百个)文件。 @ChrisG 我明白你的意思。先生,我是前端开发的初学者。当我学习了 CSR 时,它很容易理解。 s-s-r对我来说有点混乱。 1. 当我发布我的产品应用程序时,如何利用 ES6 功能并将所有 javascript 文件捆绑到一个单元中(用于缩小 - 组合构建中的所有内容)? 2. 为什么我们在 react-s-s-r 中有 2 个 webpack 配置(服务器,客户端)。我们可以关联这两个 > ExpressJs & > React-s-s-r。提前致谢。 1.我假设使用像import 这样的ES6 特性?这可以通过启用标志或使用最新版本的 Node.js 来完成。再说一次,为什么你首先想要一个“组合构建”? 为什么? 没有理由这样做,即使是为了生产。如果您想要一个脚本,只需将所有快速代码编写在一个脚本中即可。 2. 你能发布一个链接到 react-s-s-r 解释如何设置服务器端 webpack 的地方吗?唯一接近的是this。 【参考方案1】:

我找到了一种方法,其中模板引擎 (.pug) 保持不变,并且只有 Javascript 会捆绑。

.babelrc


    "plugins": ["@babel/plugin-proposal-class-properties", "@babel/plugin-transform-runtime"],
    "presets": ["@babel/preset-env"]

webpack.config.js

const path = require('path');
const nodeExternals = require('webpack-node-externals');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackPugPlugin = require('html-webpack-pug-plugin');

module.exports = 
    mode: 'development',
    entry: './index.js',
    output: 
        path: path.resolve(__dirname, './dist'),
        filename: 'app-bundle.js'
    ,


target: 'node', 
externals: [nodeExternals()],

module: 
    rules:[
        
            test: '/\.(js|jsx)$/',
            exclude: /node_modules/,
            use: 'babel-loader'
        ,
        
            test: '/\.pug$/',
            use: 'pug-loader'
        ,
        
            test: '/\.css$/',
            use: ['styles-loader', 'css-loader']
        
    ]
,

plugins: [
    
    new HtmlWebpackPlugin(
        template: 'src/views/_layout.pug',
        filename: '_layout.pug'
    ),
    new HtmlWebpackPlugin(
        template: 'src/views/app.pug',
        filename: 'app.pug'
    ),
    new HtmlWebpackPlugin(
        template: 'src/views/home.pug',
        filename: 'home.pug'
    ),
    new HtmlWebpackPlugin(
        template: 'src/views/login.pug',
        filename: 'login.pug'
    ),

    new HtmlWebpackPugPlugin()
]



【讨论】:

以上是关于如何使用 Webpack 捆绑 Express Js (NodeJs) 和 Pug 引擎?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 NewRelic 集成到与 Webpack 捆绑的 Node Typescript Express 服务器中?

如何使用 webpack 捆绑 puppeteer 进行生产部署?

生产模式下 webpack 捆绑的 Swagger UI Express 插件问题

Webpack和Express之间的区别?

Webpack:如何使用动态捆绑组合两个完全独立的捆绑包

React Hot Reloading + Webpack 没有 Express 或 Webpack-Dev-Server