Таблицы данных Bootstrap4 с WebPack не интегрированы в Rails 6?

#ruby-on-rails #webpack #bootstrap-4 #datatables

#ruby-on-rails #webpack #bootstrap-4 #таблицы данных

Вопрос:

В настоящее время я работаю над HR-системой, где я обрабатываю модуль посещаемости. Я хочу показать таблицу, используя таблицы данных Bootstrap4. Я перепробовал все ссылки StackOverflow, но ни одно из решений не работает для меня.

Я сталкиваюсь со следующей ошибкой в этом коде:

Ошибка application.js: 1 Не обнаружена: не удается найти модуль ‘jquery’ в webpackMissingModule (application.js:1)

посещаемость: 131 Неперехваченная ошибка ссылки: $ не определен при посещаемости: 131

$(…)DataTable не является функцией

packages.json :

     {
    "name": "inhouse_activities",
    "private": true,
    "dependencies": {
        "@fortawesome/fontawesome-free": "^5.15.0",
        "@nathanvda/cocoon": "^1.2.14",
        "@rails/actioncable": "^6.0.0",
        "@rails/activestorage": "^6.0.0",
        "@rails/ujs": "^6.0.0",
        "@rails/webpacker": "4.3.0",
        "bootstrap": "^4.5.2",
        "coffee-loader": "^1.0.0",
        "coffeescript": "1.12.7",
        "datatables.net": "^1.10.22",
        "datatables.net-bs4": "^1.10.22",
        "imports-loader": "^1.2.0",
        "jquery": "^3.5.1",
        "popper.js": "^1.16.1",
        "toastr": "^2.1.4",
        "turbolinks": "^5.2.0"
    },
    "version": "0.1.0",
    "devDependencies": {
        "webpack-dev-server": "^3.11.0"
    }
}
  

config/webpack/loaders/datatable.js :

 module.exports = {
    test: /datatables.net.*/,
    use: [{
      loader: 'imports-loader?define=>false'
    }]
  }
  

config/webpack/environment.js :

 const { environment } = require("@rails/webpacker");
const coffee = require("./loaders/coffee");

const webpack = require("webpack");
const datatable =  require('./loaders/datatable')

environment.plugins.prepend(
    "Provide",
    new webpack.ProvidePlugin({
        $: "jquery/src/jquery",
        jQuery: "jquery/src/jquery",
        Popper: ["popper.js", "default"]
    })
);

environment.loaders.append('expose', {
    test: require.resolve('jquery'),
    use: [{
      loader: 'expose-loader',
      options: '$'
    }]
  })

environment.loaders.prepend("coffee", coffee);
environment.loaders.prepend('coffee', datatable);

module.exports = environment;
  

views/attendances/_table.html.erb :

 <div class="container">
    <table id="example" class="table table-striped table-bordered" style="width: 1000px;">
        <thead>
            <th>Name</th>
            <th>Position</th>
            <th>Office</th>
            <th>Age</th>
            <th>Start date</th>
            <th>Salary</th>
        </thead>
        <tbody>
            <tr>
                <td>Tiger Nixon</td>
                <td>System Architect</td>
                <td>Edinburgh</td>
                <td>61</td>
                <td>2011/04/25</td>
                <td>$320,800</td>
            </tr>
            <tr>
                <td>Garrett Winters</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
            <tr>
                <td> Paul Byrd</td>
                <td> Chief Financial Officer (CFO)</td>
                <td> New York</td>
                <td>64</td>
                <td> 2010/06/09</td>
                <td> $725,000</td>
            </tr>
            <tr>
                <td> Gloria Little</td>
                <td>Systems Administrator</td>
                <td>New York</td>
                <td>59</td>
                <td>2009/04/10</td>
                <td>$237,500</td>
            </tr>
            <tr>
                <td>Bradley Greer</td>
                <td>Software Engineer</td>
                <td>London</td>
                <td>41</td>
                <td>2012/10/13</td>
                <td>$132,000</td>
            </tr>
            <tr>
                <td>Dai Rios</td>
                <td>Personnel Lead</td>
                <td>Edinburgh</td>
                <td>35</td>
                <td>2012/09/26</td>
                <td>$217,500</td>
            </tr>
            <tr>
                <td>Jenette Caldwell</td>
                <td>Development Lead</td>
                <td>New York</td>
                <td>30</td>
                <td>2011/09/03</td>
                <td>$345,000</td>
            </tr>
      <tr>
                <td>Hassam Saeed</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
      <tr>
                <td>Hunaid Nawaz</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
      <tr>
                <td>Armaghan Fazal</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
      <tr>
                <td>Fahad Anwar</td>
                <td>Accountant</td>
                <td>Tokyo</td>
                <td>63</td>
                <td>2011/07/25</td>
                <td>$170,750</td>
            </tr>
        </tbody>
    </table>
</div>


<script type="text/javascript">

  $(document).ready(function() {
      console.log($('#example'))
    $('#example').DataTable();
  });
</script>
  

app/assets/stylesheets/application.scss :

 $fa-font-path: "@fortawesome/fontawesome-free/webfonts";
@import "@fortawesome/fontawesome-free/scss/fontawesome";
@import "@fortawesome/fontawesome-free/scss/solid";
@import "@fortawesome/fontawesome-free/scss/regular";
@import "@fortawesome/fontawesome-free/scss/brands";
@import "@fortawesome/fontawesome-free/scss/v4-shims";
@import "bootstrap/dist/css/bootstrap";

@import "toastr/toastr";
@import "custom";
@import "session";
  

app/javascript/packs/application.js :

 require("jquery");
require("@rails/ujs").start();
require("turbolinks").start();
require("@rails/activestorage").start();
require("channels");


import $ from "jquery";
// window.$ = $
// window.$ = $
// require('datatables.net-bs4')
// require('datatables.net')( window, jQuery );
require("datatables.net-bs4")(window, $);

require("@nathanvda/cocoon");

import "controllers";
import "@fortawesome/fontawesome-free/js/all";
  

application.html.erb :

 <!DOCTYPE html>
<html>
  <head>
    <title>HR-System</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%# <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/dataTables.bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/fixedheader/3.1.7/css/fixedHeader.bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/responsive/2.2.6/css/responsive.bootstrap.min.css"/> %>
  </head>

  <body>
    <%= yield %>
    
    <script><%= yield :javascript %></script>
    <%# <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.22/datatables.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/responsive/2.2.6/js/dataTables.responsive.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/responsive/2.2.6/js/responsive.bootstrap.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/fixedheader/3.1.7/js/dataTables.fixedHeader.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/1.10.22/js/dataTables.bootstrap.min.js"></script>      %>
    </body>
</html>
  

Всякий раз, когда я раскомментирую эти файлы в Application.html.erb, весь код работает нормально, без каких-либо ошибок.

Надеюсь на лучший ответ.

Ответ №1:

Я не уверен, в чем основная причина, но я нашел некоторое обходное решение, если вы хотите использовать DataTable из Webpack вместо CDN.

Если вы хотите использовать DataTable функцию внутри файла js в папке javascript/pack/ :

 // In application.js

var $  = require( 'jquery' );
var dt = require('datatables.net-bs4');

$(document).ready(() => {
  console.log($.fn.DataTable)
  //
})

/* Got
ƒ (opts) {
    return $(this).dataTable(opts).api();
  }
*/ 
 
  

Из последней строки внизу документа

Пожалуйста, обратите внимание, что приведенное выше показано для модулей CommonJS. Если вы используете загрузчик AMD, вам не нужно выполнять требуемую библиотеку (т. Е. Удалять завершающий ()).

Или, если вы хотите вызвать $('#example').DataTable(); файл views/attendances/_table.html.erb , вам следует отредактировать application.js подайте немного:

 var $  = require( 'jquery' );
var dt = require('datatables.net-bs4');
window.$ = $
  

Я нашел это обсуждение, надеюсь, это поможет!

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

1. Неперехваченная ошибка: не удается найти модуль ‘jquery’ в webpackMissingModule (toastr.js: 16) в toastr.js:16 в Object../node_modules/toastr/toastr.js (toastr.js: 495) в webpack_require (bootstrap: 19) в Object../app/javascript/controllers/index.js (index.js:1) в webpack_require (bootstrap:19) в Module../app/javascript/packs/application.js (приложение.js: 1) при webpack_require (bootstrap:19) при начальной загрузке:83 при начальной загрузке:83 посещаемость: 131 Неперехваченная ошибка ссылки: $ не определена при посещаемости:131

2. Я помещаю эти строки в начало application.js

3. Я поместил его в раздел «Все требования», я еще не видел, чтобы вы требовали toastr , вы добавили его controller.js ?

4. Да, я добавил в контроллер js для отображения пользовательских сообщений

5. Спасибо! Мне нужно было поместить .DataTable() в файл представления, и это сработало!

Ответ №2:

Я не уверен, что это опечатка, но ваш каталог webpack написан неправильно: webapck vs webpack .

Я использую jquery немного иначе, чем вы. Это с синтаксисом expose-loader 1.0: config/webpack/environment.js

 environment.plugins.prepend('Provide', new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery',
  jquery: 'jquery', 
})
)

environment.loaders.append('expose', {
  test: require.resolve('jquery'),
  use: [
    { loader: 'expose-loader', options: { exposes: ['$', 'jQuery'] } }, 
  ]
})
  

Говоря об этом, у меня есть expose-loader, явно включенный в package.json . Я не думаю, что какой-либо из пакетов Rails webpacker включает его по умолчанию.

     "@rails/webpacker": "5.1.1",
    "bootstrap": "^4.3.1",
    "datatables.net-bs4": "^1.10.19",
    "expose-loader": "^1.0.0",
    "jquery": "~3.4.1",
    "popper.js": "^1.15.0",
  

У меня вообще нет config/webpack/loaders/datatable.js файла.

В app/javascript/packs/application.js я вообще не импортирую / не требую jquery, который загружается глобально с вышеуказанной конфигурацией.

 import 'bootstrap'
require('datatables.net-bs4')
  

app/views/whatever.html.erb

 ...
<script>
    $('#assignments_table').DataTable({
        paging: false, 
        language: {
            emptyTable: "No assignments entered",
        },
    });
</script>
  

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

1. проблема с jquery решена, но она по-прежнему выдает ошибку о том, что DataTable не является функцией