Как подключить `Bootstrap` с помощью `nmp`?

Как подключить Bootstrap с помощью nmp ?
В проекте с cdn Bootstrap подключается­.

cdn
Проект cdn - cdn_01.zip — Яндекс.Диск

npm
Проект - npm - npm_02.zip — Яндекс.Диск

app.js

const express = require("express")
const path = require("path")
 
const app = express()
 
// vvv vvv vvv vvv vvv vvv vvv
app.use(
  "/css",
  express.static(path.join(__dirname, "node_modules/bootstrap/dist/css"))
)
app.use(
  "/js",
  express.static(path.join(__dirname, "node_modules/bootstrap/dist/js"))
)
app.use("/js", express.static(path.join(__dirname, "node_modules/jquery/dist")))
// ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^ ^^^
 
app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "views/index.html"))
})
 
app.listen(5000, () => {
  console.log("Listening on port " + 5000)
})

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
 
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="./css/bootstrap.min.css">
    <!-- <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
      integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
      crossorigin="anonymous"
    /> -->
 
    <title>Hello, the world!</title>
  </head>
  <body>
    <div class="jumbotron">
      <div class="container"><h1>Hello, the world!</h1></div>
    </div>
 
    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script
      src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
      integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
      integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"
      integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI"
      crossorigin="anonymous"
    ></script>
  </body>
</html>



15.08.2022_21-57-48

Странный набор требований. Я бы качал дистрибутив библиотеки и клал бы в папку со статическими файлами. Таким образом избегаешь кучи сложностей. Например, все продолжит работать даже в случае отсутствия node_modules или если забудешь перезапустить сборку проекта.

Если нужно именно через npm, то делал бы через систему сборки: каким-нить webpack-ом (популярный выбор) или parcel-ом (мой личный выбор). Сборка создает файлы в папке со статикой, файлы подключаются на странице. parcel не требует конфигурационного файла, и можно обойтись флагами команды.

Подход через подключение файлов внутри node_modules интересный, сам такое не использовал и не встречал.

1 симпатия

Главная цель: обеспечить отображение стилей, т.к. приложение node.js будет работать без доступа к интернету.

Я бы качал дистрибутив библиотеки и клал бы в папку со статическими файлами
Не могли бы подсказать откуда скачать?
Или просто “Bootstrap скачать”?

Ещё проблема: нашёл таблицу, а там куча зависимостей.
И чё это всё искать и скачивать?
Может посоветуете таблицу попроще?
Требования к таблице: только для чтения, сортировка не требуется, чтобы цвет можно было менять…
Стиль таблицы как кнопка “В главное меню” на картинке…

Пример текущей таблицы.

19.08.2022_00-29-42
Фрагмент кода

<h4>include Раздел 1</h4>

<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    <link href="https://cdn.datatables.net/1.12.0/css/dataTables.bootstrap5.min.css" rel="stylesheet">

    <script src="https://code.jquery.com/jquery-3.6.0.js"
        integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
        crossorigin="anonymous"></script>

    <script src="https://cdn.datatables.net/1.12.0/js/jquery.dataTables.min.js"></script>

    <script src="https://cdn.datatables.net/1.12.0/js/dataTables.bootstrap5.min.js"></script>

    <title></title>
</head>

<body>
    <div class="container">
        <h1 class="mt-4 mb-4 text-center text-primary"><b>Title***</b></h1>
        <span id="message"></span>
        <div class="card">
            <div class="card-header">
                <div class="row">
                    <div class="col col-sm-9">
                        <input></input>
                    </div>
                    <div class="col col-sm-3">
                        <button type="button" id="add_data" class="btn btn-success btn-sm float-end">Search</button>
                    </div>
                </div>
            </div>
            <div class="card-body">
                <div class="table-responsive">
                    <table class="table table-striped table-bordered" id="sample_data">
                        <thead>
                            <tr>
                                <th>ФИО</th>          
                            </tr>
                        </thead>
                        <tbody></tbody>
                    </table>
                </div>
            </div>
        </div>
        <!-- div class="container". END vvvv -->
        <div>
        <!-- div class="container". END ^^^^ -->


        <script>
            $(document).ready(function(){
            
                load_data();
            
                function load_data()
                {
                    $.ajax({                    
                         url:"http://localhost:3000/prisoners/getAll", 
                        method:"POST",
                        data:{action:'fetch'},
                        dataType : "JSON",
                        success:function(data)
                        {
                            console.log("View `prisoners.ejs` + data = " + data);
                            console.log("View `prisoners.ejs` + data[0] = " + data[0]);
                            console.log("View `prisoners.ejs` + data[0].first_name = " + data[0].first_name);
                            console.log("View `prisoners.ejs` + data.length = " + data.length);
                            // console.log("View `prisoners.ejs` + data.data.length = " + data.data.length);                        
                            
                            var html = '';    
                            if(data.length > 0)
                            {
                                for(var count = 0; count < data.length; count++)
                                {
                                    // console.log("View `prisoners.ejs` + data[count].fio = " + data.fio);
                                    console.log("View `prisoners.ejs` + data[count].fio = " + data[count].fio);
                                    html += `
                                    <tr>
                                        <td>` + data[count].fio + `</td>                                                          
                                    </tr>
                                    `;
                                    
                                }
                            }
            
                            $('#sample_data tbody').html(html);
                        }
                    });
                }
            
                $('#add_data').click(function(){    
                    $('#dynamic_modal_title').text('Add Data');    
                    $('#sample_form')[0].reset();    
                    $('#action').val('Add');    
                    $('#action_button').text('Add');    
                    $('#action_modal').modal('show');    
                });
            
                $('#sample_form').on('submit', function(event){
            
                    event.preventDefault();
            
                    $.ajax({
                        url:"http://localhost:3000/sample_data/action",
                        method:"POST",
                        data:$('#sample_form').serialize(),
                        dataType:"JSON",
                        beforeSend:function(){
                            $('#action_button').attr('disabled', 'disabled');
                        },
                        success:function(data)
                        {
                            $('#action_button').attr('disabled', false);    
                            $('#message').html('<div class="alert alert-success">'+data.message+'</div>');    
                            $('#action_modal').modal('hide');    
                            load_data();
            
                            setTimeout(function(){
                                $('#message').html('');
                            }, 5000);
                        }
                    });
            
                });
            
                $(document).on('click', '.edit', function(){    
                    var id = $(this).data('id');    
                    $('#dynamic_modal_title').text('Edit Data');    
                    $('#action').val('Edit');    
                    $('#action_button').text('Edit');    
                    $('#action_modal').modal('show');    
                    $.ajax({
                        url:"http://localhost:3000/sample_data/action",
                        method:"POST",
                        data:{id:id, action:'fetch_single'},
                        dataType:"JSON",
                        success:function(data)
                        {
                            $('#first_name').val(data.first_name);
                            $('#last_name').val(data.last_name);
                            $('#gender').val(data.gender);
                            $('#age').val(data.age);
                            $('#id').val(data.id);
                        }
                    });
            
                });
            
                $(document).on('click', '.delete', function(){
            
                    var id = $(this).data('id');
            
                    if(confirm("Are you sure you want to delete this data?"))
                    {
                        $.ajax({
                            url:"http://localhost:3000/sample_data/action",
                            method:"POST",
                            data:{action:'delete', id:id},
                            dataType:"JSON",
                            success:function(data)
                            {
                                $('#message').html('<div class="alert alert-success">'+data.message+'</div>');
                                load_data();
                                setTimeout(function(){
                                    $('#message').html('');
                                }, 5000);
                            }
                        });
                    }
            
                });
            });
            
            </script>
</body>

В самом бутстрапе есть таблицы Tables · Bootstrap. Оттолкнись от таблицы бутстрапа, напиши дополнительные классы для других цветов.