Разделение кода на самом деле причудливое имя для динамического c импорта. Вот как это сделать с помощью Rollup (вы также получите потрясающее потрясение от деревьев в процессе!).
Напоминание о динамическом c импорт:
// "normal" static ES import
//
// - statically analytisable
// - must be called at top level
// - will be greedily resolved (and most often inlined) by your bundler
//
import Foo from './Foo.svelte'
// dynamic import
//
// - called like a function
// - returns a promise
// - default export is accessible on key `default` of the result
// - will be bundled into its own chunk by your bundler (hence code splitting)
//
import('./Foo.svelte').then(module => {
const cmp = module.default
console.log(module.myNamedExport)
})
Обратите внимание, что Dynami * Импорт 1160 * является встроенной функцией ES, как и обычный импорт. Это означает, что они изначально поддерживаются в устаревших браузерах.
Rollup уже некоторое время поддерживает "разбиение кода по динамическим c import" (см. docs ).
Итак, если вы хотите разделить код в своем проекте, это в основном вопрос настройки Rollup таким образом, чтобы он объединял динамический c импорт (другой вариант - разрешить и встроить их, что не приведет к разделению кода).
Вот шаги для этого, начиная с официального шаблона Svelte .
- изменить
output.format
на 'es'
- изменить * От 1023 * до
output.dir
(например, 'public/build'
) - измените тег
<script>
в index.html
, чтобы он указывал на новую точку входа /build/main.js
, и используйте type="module"
- написать код с помощью Dynami c import
- добавить поддержку устаревших браузеров
Сводная конфигурация: output.format
и output.dir
Доступны не все выходные форматы в Rollup может поддерживать динамический импорт c. По умолчанию из шаблона Svelte iife
нет, поэтому нам нужно изменить.
output.format: 'es'
не будет переписывать import
операторов в вашем коде. Это означает, что мы будем полагаться на собственный загрузчик модулей браузера. В настоящее время все браузеры поддерживают ES import
или dynamici c import(...)
, и устаревшие браузеры могут быть заполнены по-разному.
Другим вариантом может быть, например, output.format: 'system'
для System JS, но для этого потребуется отгрузить сторонний загрузчик модулей в дополнение к нашему коду.
Нам также нужно изменить output.file
на output.dir
, потому что разбиение кода не даст ни одного bundle.js
файл, но несколько кусков. (И вы не можете записать отдельные файлы в один файл, очевидно ...)
Итак, вот соответствующая часть нашей конфигурации Rollup сейчас:
input: 'src/main.js', // not changed
output: {
format: 'es',
dir: 'public/build/',
},
Если вы запустите yarn build
(или npm run build
) на этом этапе вы увидите, что ваше приложение теперь разделено на несколько .js
файлов в каталоге `/ public / build /.
index. html
Теперь нам нужно изменить тег <script>
в нашем index.html
(расположен в `public / index. html, в шаблоне Svelte), чтобы использовать его.
<script defer type="module" src="/build/main.js"></script>
Во-первых, нам нужно изменить src
с bundle.js
(который был нашим старым output.file
) на новую точку входа нашего приложения. Поскольку наша точка входа в конфигурации Rollup (input
) - src/main.js
, основная точка входа нашего приложения будет записана в main.js
(настраивается с помощью опции entryFileNames
в Rollup).
Поскольку наш код теперь полон операторов ES import
(поскольку мы используем output.format='esm'
), нам также необходимо изменить тип сценария с script
(по умолчанию) на module
, добавив атрибут type="module"
для нашего тега скрипта.
Вот и все для современных браузеров, теперь у вас есть полностью работающая поддержка разделения кода!
Фактически разделите ваше приложение
Поддержка разделения кода недостаточно, чтобы получить реальное разделение кода. Это просто делает это возможным. Вам все еще нужно отделить динамические c фрагменты от остальной (основной) вашей прикладной программы.
Вы делаете это путем написания динамического c импорта в своем коде. Например:
import('./Foo.svelte')
.then(module => module.default)
.then(Foo => { /* do something with Foo */ })
.catch(err => console.error(err))
Это приведет к тому, что Rollup создаст чанк Foo-[hash].js
(настраивается с помощью опции chunkFileNames
) и, возможно, еще один чанк для зависимостей Foo.svelte
, которые используется совместно с другими компонентами.
В браузере этот файл загружается только в том случае, если в вашем коде встречается оператор import('./Foo.svelte')
(отложенная загрузка).

(Обратите внимание, в водопаде, как Foo
и Cmp
- обычное хранилище - загружаются долго после загрузки страницы, обозначенной вертикальной красной полосой.)
Устаревшие браузеры
Edge (до недавнего времени Chrome) не поддерживает динамический c импорт. Обычный импорт ES, да, но динамический c import(...)
нет. Именно поэтому вам обычно приходится включать несколько заполнителей для устаревших браузеров.
Одним из решений, как в примере rollup-starter-code-split , является использование стороннего загрузчика модулей (например, Sytem JS) в браузере.
Другое, возможно, более простое решение, доступное в наши дни, - это использование пакета dimport
. Поддержка полифилов для импорта ES и динамического c импорта, необходимого для браузера хоста.
Чтобы использовать его, мы заменяем наш тег <script>
в index.html
следующим:
<script defer type="module" src="https://unpkg.com/dimport?module"
data-main="/build/main.js"></script>
<script defer type="nomodule" src="https://unpkg.com/dimport/nomodule"
data-main="/build/main.js"></script>
И вуаля. Полноценное разбиение кода. (Проще, чем вы думали, не так ли?)
Полный пример
Вот полный пример , реализующий все различные биты, описанные в этом ответе. Вы можете быть особенно заинтересованы в этом коммите .
Внимание! Обратите внимание, что пример находится в ветке example-code-splitting
хранилища, а не master
. Вам нужно оформить правильную ветку, если вы клонируете репо!
Пример использования:
# install
npx degit rixo/svelte-template-hot#example-code-splitting svelte-app
cd svelte-app
yarn # or npm install
# dev
yarn dev
# build
yarn build
# serve build
yarn start