Как я могу объединить Express Js (NodeJS) и движок Pug с помощью Webpack?

#javascript #node.js #express #webpack #server-side-rendering

#javascript #node.js #выражать #веб-пакет #рендеринг на стороне сервера

Вопрос:

Введение: Я использовал фреймворк ExpressJS с node в качестве сервера и pug в качестве движка шаблонов. Я хочу объединить .js , .pug и .css.

Я знаю о конфигурации webpack (module bundler) для статических файлов (рендеринг на стороне CSR-клиента). Для CSR appoach мы выполним следующие действия.

  1. Объедините все файлы с помощью webpack
  2. Хост html amp; bundle.js (созданный webpack ранее) с использованием сервера (iis / npm serve или любого другого выбора).

Итак, я попробовал то же самое с ExpressJS, который (рендеринг на стороне SSR-сервера), 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);
 

srcroutesUserManagementRoutes.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' amp;amp; password == 'admin')
        return true;

    else
        return false;    
}
 

srcпросмотрыУправление пользователями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" amp;amp; exit 1"
  },
 

Комментарии:

1. Зачем вам вообще связывать код узла на стороне сервера? Это не имеет смысла и невозможно. Webpack используется для объединения клиентских модулей JS-кода в один скрипт, поскольку поддержка браузером модулей еще не завершена. Единственный тип объединения на стороне сервера, который, на мой взгляд, имеет некоторый смысл, — это вставка скриптов и таблиц стилей в качестве встроенных элементов в обслуживаемые HTML-файлы.

2. Для ясности: ваше приложение express — это программа, написанная на JS и запускаемая node (которая просто случайно отвечает на входящие http-запросы). запросы). Он никоим образом не «обслуживается»; это просто набор скриптов и ресурсов, находящихся на жестком диске, которые считываются и выполняются node.exe . Объединение ничего не даст; чтобы опубликовать свой серверный код, вы обычно помещаете его в репозиторий git, а они обычно состоят из десятков, если не сотен файлов.

3. @ChrisG Я понял твою точку зрения. Сэр, я новичок в интерфейсной разработке. Когда я изучил CSR, его легко понять. SSR немного сбивает меня с толку. 1. Как я могу использовать функции ES6, а также объединить все файлы JavaScript в единый блок (для минимизации — все в составной сборке), когда я публикую свое приложение для prod? 2. Почему у нас есть 2 конфигурации webpack (сервер, клиент) в react-ssr. Можем ли мы сопоставить эти два> ExpressJS amp;> React-SSR. Заранее спасибо.

4. 1. Использование функций ES6, как import я предполагаю? Это можно сделать, включив флаг или используя последнюю версию Node. Опять же, зачем вам вообще нужна «составная сборка»? Почему? Для этого нет никаких причин, даже для производства. Если вам нужен один скрипт, просто напишите весь свой экспресс-код в одном скрипте. 2. Можете ли вы опубликовать ссылку на то, где react-ssr объясняет, как настроить веб-пакет на стороне сервера? Единственное, что приближается к этому , — это вот что.

Ответ №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()
]


}