Как сделать разбиение кода с помощью Svelte без Sapper - PullRequest
4 голосов
/ 02 февраля 2020

Как вы делите код с помощью Svelte?

(я вижу, что вы можете сделать это с помощью Sapper, но я не хочу брать зависимость от бэкэнда узла)

Ответы [ 2 ]

10 голосов
/ 02 февраля 2020

Разделение кода на самом деле причудливое имя для динамического 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 .

  1. изменить output.format на 'es'
  2. изменить * От 1023 * до output.dir (например, 'public/build')
  3. измените тег <script> в index.html, чтобы он указывал на новую точку входа /build/main.js, и используйте type="module"
  4. написать код с помощью Dynami c import
  5. добавить поддержку устаревших браузеров

Сводная конфигурация: 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') (отложенная загрузка).

enter image description here

(Обратите внимание, в водопаде, как 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
2 голосов
/ 02 февраля 2020

Это репо может быть хорошим местом для старта https://github.com/Rich-Harris/rollup-svelte-code-splitting

...