from the Core
Почему начать с Nuxt быстрее чем vue-ssr?
Nuxt - готовое решение из коробки, включающее в себя vue-ssr
vue-ssr - низкоуровневая библиотека для ssr рендеринга
В Nuxt интегрированы наиболее используемые vue библиотеки
- vue-meta (опционально, для мета тегов и SEO)
- vue-router
- vuex ( опционально)
Библиотеки для сборки
- Babel (вместе с собственном конфигом nuxt)
- Настроенный и оптимизированный конфиг webpack
- PostCSS уже включен и настроен
ОПРЕДЕЛЕННАЯ СТРУКТУРА ПРОЕКТА
- Одна и таже структура для всех проектов
- Место для практически каждого файла
Улучшенная функциональность компонентов
- asyncData / fetch для страниц
- анимации для перехода между страницами
- Layouts
Модули
Для Nuxt имеется множество готовых модулей:
- @nuxt/http
- @nuxt/pwa
- @nuxt/auth
- и другие
- @nuxtjs/apollo
Поддержка Typescript
- @nuxt/typescript-build - поддержка typescript для layouts, components, plugins и middlewares
-
@nuxt/typescript-runtime - поддержка typescript для nuxt.config, локальных модулей и server-middleware
-
@nuxt/types - типы для всех классов nuxt
router.js
Роутинг на основе файловой системы
Роутинг на основе файловой системы
import user from '....'
import cart from '....'
import favorites from '....'
import Vuex from 'vuex'
const createStore = () => {
return new Vuex.Store({
namespaced: true,
state: () => ({
query: ''
}),
mutations: {
updateQuery(state, query) {
state.query = query;
}
},
modules: {
user,
cart,
favorites,
},
actions: {
async newSearch({dispatch, commit}, data) {
//...
},
async populateQuery({dispatch, commit}, query) {
//...
}
},
getters: {
getQuery: state => state.query,
getLoading: state => state.isLoading
},
})
};
VUEX
классический vuex store
export const state = () => ({/**/})
export const mutations = {/**/}
export const actions = {/**/}
export const getters = {/**/}
Теперь NUXT way с использованием файловой системы
один модуль на файл
export default {
setName(state, name){
state.name = name
},
// и другие мутации
}
Модуль как директория
Developer Experience
Улучшенные логи с consola
Логи с SSR в консоли браузера
Прогресс бар при hot reload проекта
Экран загрузки при билде проекта
Оптимизация SSR
render: {
compressor: false
}
- отключение компрессии на уровне nuxt
- использование кеширующего сервера, например nginx
- extractCss в случае большого css бандла
Экспериментальное отключение функционала
features: {
router: true,
store: true,
layouts: true,
meta: true,
middleware: true,
transitions: true,
deprecations: true,
validate: true,
asyncData: true,
fetch: true,
clientOnline: true,
clientPrefetch: true,
clientUseUrl: false,
componentAliases: true,
componentClientOnly: true
}
Отключение неиспользуемых функций
Все включено
Минимально необходимый набор
Экспериментальное отключение функционала
autocannon -d 60 http://localhost:3000
Running 60s test @ http://localhost:3000
10 connections
Stat 2.5% 50% 97.5% 99% Avg Stdev Max
Latency 4 ms 4 ms 8 ms 10 ms 4.67 ms 1.42 ms 19.37 ms
Stat 1% 2.5% 50% 97.5% Avg Stdev Min
Req/Sec 1655 1764 1951 2038 1931.57 78.95 1655
Bytes/Sec 5.88 MB 6.27 MB 6.93 MB 7.24 MB 6.86 MB 280 kB 5.88 MB
Req/Bytes counts sampled once per second.
116k requests in 60.08s, 412 MB read
autocannon -d 60 http://localhost:3000
Running 60s test @ http://localhost:3000
10 connections
Stat 2.5% 50% 97.5% 99% Avg Stdev Max
Latency 8 ms 9 ms 16 ms 18 ms 10.12 ms 2.25 ms 30.38 ms
Stat 1% 2.5% 50% 97.5% Avg Stdev Min
Req/Sec 784 805 951 1046 942.29 57.03 784
Bytes/Sec 3.68 MB 3.78 MB 4.47 MB 4.91 MB 4.42 MB 268 kB 3.68 MB
Req/Bytes counts sampled once per second.
57k requests in 60.09s, 265 MB read
Все включено
Минимально необходимый набор
2X разница в производительности
Оптимизация кода
- асинхронные компоненты
<template>
<div>
<SyncComponent />
<AsyncComponent />
</div>
</template>
<script>
import AsyncComponent from '~/components/AsyncComponent.vue'
import SyncComponent from '~/components/SyncComponent.vue'
export default {
components: {
SyncComponent,
AsyncComponent: () => import('~/components/AsyncComponent.vue')
}
}
</script>
- ClientOnly тег для тяжелых комопнентов
Vue-lazy-hydration
<!-- по списку событий-->
<LazyHydrate on-interaction="['fullscreen', 'mousedown']">
...
</LazyHydrate>
<!-- По видимости -->
<LazyHydrate when-visible>
...
</LazyHydrate>
<!-- когда процессор не занят -->
<LazyHydrate when-idle>
....
</LazyHydrate>
<!-- только на сервере -->
<LazyHydrate ssr-only>
...
</LazyHydrate>
<!-- контролируемая гидрация -->
<LazyHydrate ssr-only :trigger-hydration="isItReady">
<ArticleContent :content="article.content"/>
</LazyHydrate>
<script>
import LazyHydrate from 'vue-lazy-hydration';
export default {
components: {
LazyHydrate,
// The `ArticleContent` будет импортирован только если isItReady true
ArticleContent: () => import('./ArticleContent.vue'),
},
// ...
};
</script>
yarn add vue-lazy-hydration
<template>
<div class="ArticlePage">
<ImageSlider/>
<ArticleContent :content="article.content"/>
<AdSlider/>
<CommentForm :article-id="article.id"/>
</div>
</template>
<script>
import {
hydrateOnInteraction,
hydrateSsrOnly,
hydrateWhenIdle,
hydrateWhenVisible,
} from 'vue-lazy-hydration';
export default {
components: {
AdSlider: hydrateWhenVisible(
() => import('./AdSlider.vue'),
// Optional.
{ observerOptions: { rootMargin: '100px' } },
),
ArticleContent: hydrateSsrOnly(
() => import('./ArticleContent.vue'),
{ ignoredProps: ['content'] },
),
CommentForm: hydrateOnInteraction(
() => import('./CommentForm.vue'),
// `focus` is the default event.
{ event: 'focus', ignoredProps: ['articleId'] },
),
ImageSlider: hydrateWhenIdle(() => import('./ImageSlider.vue')),
},
// ...
};
</script>
Врапперы импортов
Vue-lazy-hydration
После
До
Vue-lazy-hydration
Анализирование бандла
nuxt build --analyze
Что нового готовит NUXT 3
- Новое cli для создание проекта nuxt create
- Новый метод fetch, asyncData deprecated
- Режимы билда nuxt для разных платформ
server
static
serverless
- Автоматический импорт плагинов, компонентов, миддлваре
- Полностью статический режим
- Webpack 5
nuxt/blueprints
- микро фреймворки на основе модулей nuxt
- создано на основе NuxtPress
- микро фреймворки на основе модулей nuxt
- множественные инстансы одного blueprint
- поддержка вебпак алиасов в темплейтах
- автоматическое определение и добавление шаблонов .tmpl
- копирование темплейтов из каждого инстанса blueprint
nuxt/blueprints
import ExampleBlueprint from './blueprint'
export default {
modules: [
function exampleBlueprint () {
const options1 = {
id: '1',
backgroundColor: 'gold'
}
const options2 = {
id: '2',
backgroundColor: 'silver'
}
new ExampleBlueprint(this.nuxt, options1).init()
new ExampleBlueprint(this.nuxt, options2).init()
}
]
}
Использование blueprint
div {
background-color: <%= options.backgroundColor %>;
padding: 1rem;
margin: 1rem auto;
}
blueprint/components/hello.tmpl.vue
<template>
<div>
<h2>Hello from ExampleBlueprint instance <%= options.id %></h2>
<p>With a fancy background</p>
</div>
</template>
<style scoped>
@import url('../css/style.css')
</style>
Шаблоны
Немного о том, как Nuxt.js устроен изнутри
Пакеты nuxt
@nuxt/builder
@nuxt/cli
@nuxt/core
@nuxt/generator
@nuxt/webpack
@nuxt/webpack
Внешние плагины
@nuxt/friendly-errors-webpack-plugin
time-fix-plugin
extract-css-chunks-webpack-plugin
hard-source-webpack-plugin
terser-webpack-plugin
webpackbar
optimize-css-assets-webpack-plugin
html-webpack-plugin
Middleware
webpack-dev-middleware
webpack-hot-middleware
Внутренние плагины
warning-ignore
CorsPlugin
ModernModePlugin
VueSSRServerPlugin
VueSSRClientPlugin
@nuxt/babel-preset-app
Postcss Config
@nuxt/core
Resolver
Module
Nuxt
@nuxt/config
@nuxt/server
@nuxt/vue-renderer
addPlugin
addTemplate
addLayout
addErrorLayout
addModule
resolveAlias
resolveModule
resolvePath
Обработка nuxt.config
Настройка сервера, используется библиотека connect
Компиляция vue шаблонов
Renderer
SPA
SSR
MODERN
@nuxt/cli
NuxtCommand
Options
build
dev
generate
help
index
start
common
locking
server
list
run
@nuxt/builder
watch
@nuxt/devalue
валидация ( validatePages, validateTemplate )
serialize-javascript
Builder
Сериализация данных
резолвинг ( resolveRoutes, resolveLayouts, resolveStore, resolveMiddleware, resolveCustomTemplates, resolvePlugins)
build & generate
TemplateContext
router, store, plugins, isDev, etc
@nuxt/vue-app
lodash темплейты
'App.js', | |
'client.js', | |
'index.js', | |
'router.js', | |
'router.scrollBehavior.js', | |
'server.js', | |
'utils.js', | |
'empty.js', | |
'components/nuxt-error.vue', | |
'components/nuxt-child.js', | |
'components/nuxt-link.server.js', | |
'components/nuxt-link.client.js', | |
'components/nuxt.js', | |
'views/app.template.html', | |
'views/error.html' |
пакеты nuxt
@nuxt/builder
@nuxt/cli
@nuxt/core
@nuxt/generator
@nuxt/webpack
nuxt
nuxt-start
@nuxt/cli
@nuxt/core
nuxt-edge & nuxt-start-edge