A presentation at Vue Day Alicante in in Alicante, Spain by Debbie O'Brien
Leave your legacy code behind and go Nuxt
We have a problem Too much legacy code Hard to scale Front and backend code mixed together Too many dependencies
Old Tech stacks JSF PHP ASP Front and Back mixed together
Unmaintainable Code <ui:fragment rendered=”#{CatalogoBean.campaign.countdown}”>
<div style=”width:360px;margin:0 auto;margin-top:70px;”> <span style=”display:none;” id=“text_days”> <g:get name=”listado” anchorid=”landing.days” defaulttext=”DAYS”/></span> <p id=”countdown” style=”width:500px;font-size:30px;margin-top:50px;color:#fff;;”></p> </div> </ui:fragment>Bad Performance
What are we doing about it? Nothing Dumping more code on top of it
What? Why? No Time No Money Afraid to take the migration step
What should we be doing? Migrating
Where do we start? Piece by piece Break up your project Create and ship
Where do we start? Convince yourself then your team then your boss
Where do we start? Know your tools Know what your capable of Know what you can deliver
Where do we start? Run performance tests to compare Create prototypes Just do it
Go Nuxt
Debbie O’Brien Frontend Tech Lead @Patterson Agency in Mallorca Mentor @OpenClassrooms Tech Degree Moderator @Treehouse Contributor @webpack Contributor @Nuxt Writer @Ultimate Courses Teacher @Vue School debs_obrien Debbie O’Brien
Debbie O’Brien Running Cycling Skiing IV Degree Blackbelt in Taekwondo debs_obrien Debbie O’Brien
Patterson Travel: Case Study
Separate Front and Back Moving from working with mixed code to code separation between Front and Back How do Front and Back communicate? JSON
The JSON war
Decide who is responsible for what Header and Footer - Front Content and shopping cart - Back
Invest in your team
Lead your code Make sure your code looks like it was written by one person
Create Standards
Pre Commit Hooks: Husky “scripts”: { … }, “husky”: { “hooks”: { “pre-commit”: “cross-env PRE_COMMIT=true lint-staged” } },
Use Pull Requests
Test your code Should you write tests at the start, while coding, or when finished developing? I don’t care Just write tests
Test your code
Document your code Use VuePress
Generate your files Use Hygen
Think first, code later Think and plan or draw before you write
Create your own components Don’t just dump big heavy component libraries into your code when you don’t need them Build your own
Dropdown Component
Dropdown Component <div> <span @click=”toggle”> {{ locale }} <SVGOChevron /> </span> <ul v-show=“isOpen”> <li v-for=”lang in languages” :key=”lang.code” @click=”toggle” > <nuxt-link :to=“switchLocalePath(lang.code)” exact> {{ lang.name }} </nuxt-link> </li> </ul> </div>
Dropdown Component data: function() { return { isOpen: false, } }, methods: { toggle: function() { this.isOpen = !this.isOpen } },
Accordion Component
Accordion Component <div> <div @click=“toggleItem”> <h2> <slot name=”title”> </slot> </h2> <SVGOCross :class=”{ ‘rotate-45’: !show }” /> </div> <div v-show=”show”> <slot name=”content”></slot> </div> </div>
Accordion Component data: function() { return { show: false, } }, methods: { toggleItem: function() { this.show = !this.show } },
Accordion Component <BaseAccordian> <template v-slot:title> {{ title }} </template> <template v-slot:content> {{ text }} </template> </BaseAccordian>
Hero components?
Use Named Slots <div> <h1 v-if=”$slots.title” class=“title“> <slot name=”title”></slot> </h1> <span v-if=“$slots.subTitle” class=“sub-title”> <slot name=”subtitle”></slot> </span> <blockquote v-if=”$slots.quote” class=”quote”> <slot name=”quote”></slot> </blockquote> <p v-if=”$slots.author” class=“author”> <slot name=“author”></slot> </p> </div>
Add the slots you need <BaseHero> <template v-slot:title> {{ title }} </template> <template v-slot:quote> {{ quote }} </template> <template v-slot:author> {{ author }} </template> </BaseHero>
Styles Use Tailwind end of conversation
Styles Stop adding big libraries of styles that you never use Stop creating styles for everything Think utilities first
Styles
Styles
Styles Utilities classes === less code to maintain A utility-first CSS framework
Add a PWA
Or you can Just use Nuxt
Nuxt PWA Registers a service worker for offline caching generates manifest.json file adds SEO friendly meta data generates different size app icons
Add a PWA in 3 steps 1 yarn add @nuxtjs/pwa 2 { modules: [ ‘@nuxtjs/pwa’, ], } 3 upload the image to static folder
PWA Tips By default the PWA name === package.json name Set it in Nuxt to be merged with your meta meta: { name: ‘Patterson Travel’, description:‘Patterson Travel Agency’, author: ‘Patterson Agency’, },
Build Static Sites Nuxt Static Sites are faster They act like a SPA Due to the hydration process Static site with SPA Benefits
Static Site + Dynamic Content Patterson.Travel === Nuxt generated static site Booking Engine will not be static Can we mix? Of Course
Static Site + Dynamic Content Just use the < no-ssr > component <template> <div> <TheHeader /> <no-ssr placeholder=”Loading…”> <!— this component will only be rendered on client-side —> <BookingEngine /> </no-ssr> <TheFooter /> </div> </template>
Run Performance Tests Be aware of what your shipping Use the wepack analyser Run an audit in chrome dev tools Check your css with CSS Stats
Analyze your bundle
yarn build -a
Improve your code Nuxt gives you code splitting by routes for free But you have to: Code Split your components
How does Code Splitting work? a e S Ask n i k r a L n
Code Split your components Just change this: import BaseHero from ‘~/components/BaseHero.vue’ components: { BaseHero, }, to this: components: { BaseHero: () => import(‘~/components/BaseHero.vue’), },
Lazy Load your translations locales: [ { code: ‘en’, iso: ‘en-US’, name: ‘English’, file: ‘en.js’, }, ], lazy: true, langDir: ‘i18n/’,
Lazy load your images yarn add v-lazy-image import Vue from ‘vue’ import VLazyImage from ‘v-lazy-image’ Vue.component(‘VLazyImage’, VLazyImage) plugins: [ ‘~/plugins/lazy-load-images.js’, ],
Use a CDN for your images <v-lazy-image src=“https://res.cloudinary.com/idemo/image/upload/ q_auto,f_auto/cloudinary”/>
Improve your SEO head() { return { title: ‘Patterson Agency’, meta: [ { hid: ‘description’, name: ‘description’, content:’The agency that designs, coordinates…’, }, ], } },
Put Accessibility first Use labels for forms Use aria tags Be careful with colour contrasts
Use your tools Chrome dev tools for accessibility
Modern mode Build two versions of your app: modern bundle: browsers that support ES modules, legacy bundle: targets older browsers that do not “build”: “nuxt build —modern”, “generate”: “nuxt generate —modern”,
Be proud of your code
So what are you waiting for? Do you still have an excuse or are you going to leave your legacy code behind?
Thank you
Thank you Debbie O’Brien Frontend Tech Lead Consultant Open Source Contributor @debs_obrien
Want to migrate to a Single Page Application but still need great SEO? Nuxt has you covered. But Nuxt is so much more than just Server Side Rendering. Join me on this talk to discover why you should be considering Nuxt as your framework of choice. How to call your data from an api with asyncData and why you should consider using static sites. What? Static sites? Yes. I will also go through how to setup a great boilerplate project so you can easily get started and migrate all your sites or build new ones. Are you Nuxt?