Понимание импорта/экспорта модулей ES6

Я начинаю изучать модули ES6 и синтаксис import/export и хочу, чтобы мои модули выполнялись только там, где они нужны.

Я создал два простых модуля, которые подключаются к <div> с определенными class или id для запуска.

Например:

// product.js

import Vue from 'vue/dist/vue';

export default function() {

  var app = new Vue({
    el: '#c-product',
    data: {
      counter: 0,
    },
    methods: {
      addToCart: function() {
        this.counter++;
      },
      removeFromCart: function() {
        this.counter--;
      }
    }
  });

}

Затем у меня есть другой модуль для карусели:

// carousel.js

import Glide from '@glidejs/glide';

export default function() {

  new Glide('.glide', {
    type: 'carousel',
    startAt: 0,
    perView: 3,
    breakpoints: {
      800: {
        perView: 2
      }
    }
  }).mount();

};

Затем я связываю все с помощью Gulp + Browserify, чтобы иметь файл main.js, в который я импортирую и запускаю модули:

// main.js
import Product from './product';
import Carousel from './carousel';

Product();
Carousel();

Теперь у меня есть файл main.js, и я готов вставить его на страницы .html, но у меня возникают ошибки в консоли в зависимости от того, существуют ли эти элементы div на странице или нет.

Пример: если на странице product.html нет каруселей, у меня в консоли возникают ошибки относительно отсутствия <div> с классом карусели.

Надеюсь быть ясным.

Можете ли вы помочь мне понять?

Вот пример на странице продукта


person antonio matera    schedule 29.01.2019    source источник
comment
Каковы ваши ошибки?   -  person Armel    schedule 29.01.2019
comment
Я добавил изображение.   -  person antonio matera    schedule 29.01.2019
comment
Ошибка гласит, что корневой элемент (с id c-product) должен существовать. Вот сумасшедшая идея - вы проверили, что элемент существует в доме?   -  person Coloured Panda    schedule 29.01.2019
comment
@Kaspars #c-product существует, на самом деле ошибка не в карусели. Но мой вопрос: должен ли я копировать свой модуль не в main.js?   -  person antonio matera    schedule 29.01.2019
comment
Я не понимаю, какое это имеет отношение к модулям. Или вы хотите создать разные сценарии для разных страниц, которые импортируют только те модули, которые необходимы на этой конкретной странице?   -  person Bergi    schedule 29.01.2019
comment
@ Берги второй. Спасибо. Извините, я новичок. :-)   -  person antonio matera    schedule 29.01.2019
comment
Да, вы не стали бы создавать main.js, который будет включен на каждую страницу. В product.html, в котором нет каруселей, вы должны встроить только <script type=module>import Product from './product.js'; Product();</script> и не загружать carousel.js, которые вам не нужны (и которые не работают на этой странице).   -  person Bergi    schedule 29.01.2019
comment
@Bergi Итак, main.js предназначен только для импорта? Должен ли я управлять своими модулями на каждой странице в html? Это похоже на старый способ. Но если так, то ладно.   -  person antonio matera    schedule 29.01.2019
comment
Да, код main.js предназначен только для импорта и инициализации. И да, вы захотите управлять своими модулями, если хотите загружать их по отдельности на разных страницах. Или, как указано в ответе ниже, исправить модули, чтобы они работали (но могли ничего не делать) на всех страницах.   -  person Bergi    schedule 29.01.2019


Ответы (1)


Вы можете решить это с помощью небольшого количества защитного кодирования. Каждый из ваших модулей зависит от наличия определенного узла DOM, поэтому вы должны запросить элемент перед созданием экземпляра модуля. Нравиться:

// product.js

import Vue from 'vue/dist/vue';

export default function() {
  var vueRoot = document.getElementById('c-product')
  if (!vueRoot) return;  // element does not exist, so we return before instantiating

  var app = new Vue({
    el: '#c-product',
    data: {
      counter: 0,
    },
    methods: {
      addToCart: function() {
        this.counter++;
      },
      removeFromCart: function() {
        this.counter--;
      }
    }
  });

}
person flemcito    schedule 29.01.2019
comment
Сначала я думал о чем-то подобном, но тогда это означает, что я должен делать if для каждого модуля, который я создаю? Возможно ли, что официального решения нет? - person antonio matera; 29.01.2019
comment
Действительно... если ваш модуль зависит от определенного элемента, вам нужно проверить его - person flemcito; 29.01.2019
comment
Может быть, вопрос: где я должен вызывать модули? В 1_? Если это так, то правильно, что он имеет глобальные ошибки. Значит main.js только для импорта? - person antonio matera; 29.01.2019
comment
Ну, на это нет однозначного ответа - это вопрос архитектуры. Использование файла main.js для импорта глобальных модулей, безусловно, является одним из способов, но вы также можете создавать специальные пакеты для отдельных страниц (и избегать загрузки, например, VueJS на страницы, которые в нем не нуждаются). - person flemcito; 29.01.2019
comment
О, и, судя по полученной вами ошибке, я предполагаю, что ваш файл main.js загружен в теге head или, по крайней мере, до того, как документ будет готов. Это не сработает... в этом случае невозможно запросить документ, и модули всегда будут давать сбой. Хорошей практикой является загрузка JS в последнюю очередь в body - person flemcito; 29.01.2019
comment
Неа. Загружается как последняя вещь в <body>. - person antonio matera; 30.01.2019