Как кэшировать импортированные модули bust в es6?

Модули ES6 позволяют нам создать единую точку входа так:

// main.js

import foo from 'foo';

foo()
<script src="scripts/main.js" type="module"></script>

Ответ 1

С моей точки зрения, динамический импорт может быть решением здесь.

Шаг 1) Создайте файл манифеста с gulp или webpack. Там у вас есть такое отображение:

export default {
    "/vendor/lib-a.mjs": "/vendor/lib-a-1234.mjs",
    "/vendor/lib-b.mjs": "/vendor/lib-b-1234.mjs"
};

Шаг 2) Создайте файловую функцию для разрешения ваших путей

import manifest from './manifest.js';

const busted (file) => {
 return manifest[file];
};

export default busted;

Шаг 3) Используйте динамический импорт

import busted from '../busted.js';

import(busted('/vendor/lib-b.mjs'))
  .then((module) => {
    module.default();
});

Я пробую это в Chrome, и это работает. Обработка относительных путей является сложной частью здесь.

Ответ 2

Для всего этого есть одно решение, которое не включает строку запроса. допустим, ваши файлы модулей находятся в /modules/. Используйте относительное разрешение модулей ./ или ../ при импорте модулей, а затем перепишите свои пути на стороне сервера, чтобы включить номер версии. Используйте что-то вроде /modules/xxx/ затем перепишите путь к /modules/. Теперь вы можете просто иметь глобальный номер версии для модулей, включив свой первый модуль в <script type="module" src="/modules/1.1.2/foo.mjs"></script>

Или если вы не можете переписать пути, а затем просто поместить файлы в папку /modules/version/ в процессе разработки и переименовывать version папки на номер версии и пути обновления в тег сценария, когда вы публикуете.

Ответ 3

Просто подумайте, но вы должны быть в состоянии получить weboack, чтобы поместить хэш контента во все разделенные пакеты и записать этот хеш в ваши операторы импорта для вас. Я считаю, что это делает второй по умолчанию.

Ответ 4

HTTP-заголовки на помощь. Служите вашим файлам с ETag, который является контрольной суммой файла. S3 делает это по умолчанию на примере. Когда вы попытаетесь импортировать файл снова, браузер запросит файл, на этот раз прикрепив ETag к заголовку " if-none-match ": сервер проверит, соответствует ли ETag текущему файлу, и отправит обратно либо 304 Not. Модифицированный, сохраняющий пропускную способность и время, или новое содержимое файла (с его новым ETag).

Таким образом, если вы измените один файл в своем проекте, пользователю не придется загружать полный контент всех остальных модулей. Было бы целесообразно добавить короткий заголовок max-age, чтобы в случае, если один и тот же модуль запрашивается дважды за короткое время, дополнительных запросов не будет.

Если вы добавите очистку кеша (например, добавление? X = {randomNumber} через пакет или добавление контрольной суммы к каждому имени файла), вы заставите пользователя загружать полное содержимое каждого необходимого файла в каждой новой версии проекта.

В обоих сценариях вы все равно будете делать запрос для каждого файла (импортированные файлы на каскаде будут выдавать новые запросы, которые, по крайней мере, могут заканчиваться маленьким 304, если вы используете etags). Чтобы избежать этого, вы можете использовать динамический импорт, eg if (userClickedOnSomethingAndINeedToLoadSomeMoreStuff) { import('./someModule').then('...') }