Slide 1

Slide 1 text

Scaffolding a Progressive Web App using Vue CLI 3

Slide 2

Slide 2 text

Manuel Wieser | @manuelwieser | manu.ninja Manuel Wieser Lead Web Developer karriere.at Lecturer Hypermedia User Experience Engineering FH OÖ Campus Hagenberg @manuelwieser manu.ninja

Slide 3

Slide 3 text

Topics Vue? Vue CLI? Installation Instant Prototyping Creating a Project What’s in a Project? Vue CLI Plugins Configuration Building

Slide 4

Slide 4 text

Vue (/vjuː/) is a progressive framework for building user interfaces

Slide 5

Slide 5 text

Vue CLI is a tool for scaffolding Vue projects full system for rapid Vue development

Slide 6

Slide 6 text

Installation

Slide 7

Slide 7 text

Manuel Wieser | @manuelwieser | manu.ninja Installation npm uninstall -g vue-cli npm install -g @vue/cli vue --version vue --help

Slide 8

Slide 8 text

Instant Prototyping

Slide 9

Slide 9 text

Manuel Wieser | @manuelwieser | manu.ninja Instant Prototyping npm install -g @vue/cli-service-global echo "\

Hello webclerks\!

\ " > App.vue vue serve

Slide 10

Slide 10 text

Manuel Wieser | @manuelwieser | manu.ninja ● vue serve uses the same default setup (webpack, Babel, PostCSS, ESLint) as projects created by vue create ● Entry can be main.js, index.js, App.vue or app.vue … ● You can provide an index.html, package.json, use local dependencies, or add config files for Babel, PostCSS and ESLint Instant Prototyping

Slide 11

Slide 11 text

Instant Prototyping import Greeting from './Greeting.vue'; export default { data() { return { message: Hello webclerks!' } }, components: { Greeting } };

{{ message }}

export default { props: ['message'] } Greeting.vue App.vue

Slide 12

Slide 12 text

Manuel Wieser | @manuelwieser | manu.ninja Instant Prototyping vue build dist ├── index.html └── js ├── app.fbe6ce0a.js ├── app.fbe6ce0a.js.map ├── chunk-vendors.aa4f98a5.js └── chunk-vendors.aa4f98a5.js.map

Slide 13

Slide 13 text

Creating a Project

Slide 14

Slide 14 text

Manuel Wieser | @manuelwieser | manu.ninja Creating a Project vue create my-project npm install -g @vue/cli-init vue init webpack my-project # vue-cli@2.x vue ui

Slide 15

Slide 15 text

Presets { "useConfigFiles": false, "plugins": { "@vue/cli-plugin-babel": {}, "@vue/cli-plugin-eslint": { "config": "airbnb", "lintOn": ["save", "commit"] } }, // … // … "router": true, "routerHistoryMode": true, "vuex": true, "cssPreprocessor": "sass" } }

Slide 16

Slide 16 text

Manuel Wieser | @manuelwieser | manu.ninja Presets vue config vue create --preset my-preset my-project # --preset my-user/my-repository # --preset my-preset.json

Slide 17

Slide 17 text

What’s in a Project?

Slide 18

Slide 18 text

Manuel Wieser | @manuelwieser | manu.ninja What’s in a Project? ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ └── index.html └── src ├── App.vue ├── assets │ └── logo.png ├── components │ └── HelloWorld.vue └── main.js

Slide 19

Slide 19 text

Manuel Wieser | @manuelwieser | manu.ninja Vue CLI Plugins "dependencies": { "vue": "^2.5.17" }, "devDependencies": { "@vue/cli-plugin-babel": "^3.0.3", "@vue/cli-plugin-eslint": "^3.0.3", "@vue/cli-service": "^3.0.3", "vue-template-compiler": "^2.5.17" }

Slide 20

Slide 20 text

Manuel Wieser | @manuelwieser | manu.ninja CLI Service "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build" } npx vue-cli-service help

Slide 21

Slide 21 text

Configuration "eslintConfig": {...}, "postcss": {...}, "browserslist": [ "> 1%", "last 2 versions", "not ie <= 8" ] module.exports = { presets: [ '@vue/app', ], }; package.json babel.config.js

Slide 22

Slide 22 text

Vue CLI Plugins

Slide 23

Slide 23 text

Manuel Wieser | @manuelwieser | manu.ninja Plugins vue add @vue/pwa # @vue/cli-plugin-pwa vue ui vue add apollo # vue-cli-plugin-apollo

Slide 24

Slide 24 text

Manuel Wieser | @manuelwieser | manu.ninja Changes? ├── package-lock.json ├── package.json ├── public │ ├── img │ │ └── icons │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── ... │ ├── manifest.json │ └── robots.txt └── src ├── main.js └── registerServiceWorker.js

Slide 25

Slide 25 text

Configuration module.exports = { pwa: { name: 'Japanese Phrasebook', themeColor: '#f44336', msTileColor: '#f44336', workboxOptions: {...} } }; cacheId: 'phrasebook', importWorkboxFrom: 'local', navigateFallback: 'shell.html', navigateFallbackWhitelist: [/^((?!\/404).)*$/] vue.config.js workboxOptions

Slide 26

Slide 26 text

Official Plugins ● @vue/cli-plugin-babel ● @vue/cli-plugin-typescript ● @vue/cli-plugin-eslint ● @vue/cli-plugin-pwa ● @vue/cli-plugin-unit-jest ● @vue/cli-plugin-unit-mocha ● @vue/cli-plugin-e2e-cypress ● @vue/cli-plugin-e2e-nightwatch

Slide 27

Slide 27 text

Manuel Wieser | @manuelwieser | manu.ninja Plugin Development

Slide 28

Slide 28 text

Configuration

Slide 29

Slide 29 text

Manuel Wieser | @manuelwieser | manu.ninja HTML ● public/index.html is processed with html-webpack-plugin ○ Variables () ○ JavaScript/CSS ○ preload/prefetch hints (@vue/preload-webpack-plugin) ○ manifest/icon links (@vue/cli-plugin-pwa) ● Multi-Page Application ○ pages option in vue.config.js

Slide 30

Slide 30 text

Manuel Wieser | @manuelwieser | manu.ninja CSS ● Preprocessors are preconfigured, you just have to install the webpack loaders (hasn’t changed from Vue CLI 2) ○ npm install -D sass-loader node-sass ● PostCSS ○ Can be configured via any of its configuration file options or css.loaderOptions.postcss in vue.config.js ● Support for CSS Modules

Slide 31

Slide 31 text

Manuel Wieser | @manuelwieser | manu.ninja webpack Configuration ● vue.config.js ● configureWebpack option is merged using webpack-merge ● chainWebpack option allows total control via webpack-chain

Slide 32

Slide 32 text

Manuel Wieser | @manuelwieser | manu.ninja webpack Configuration module.exports = { configureWebpack: { plugins: [ new MyPlugin() ], } }; vue.config.js

Slide 33

Slide 33 text

Manuel Wieser | @manuelwieser | manu.ninja webpack Configuration module.exports = { configureWebpack: config => { if (process.env.NODE_ENV === 'production') { // You can mutate the config directly … } // … or return an object which will be merged. } };

Slide 34

Slide 34 text

Manuel Wieser | @manuelwieser | manu.ninja webpack Configuration module.exports = { chainWebpack: config => { config .plugin('html') .tap(args => { return [/* … */] }) } };

Slide 35

Slide 35 text

Manuel Wieser | @manuelwieser | manu.ninja Assets ● Relative Path Imports ○ JavaScript/CSS imports, HTML/CSS references ○ file-loader/url-loader ○ Assets Images < 4 KB are inlined ○ Filenames include content hashes (for cache-busting) ● public Folder ○ You may have to prefix your links with <%= BASE_URL %>

Slide 36

Slide 36 text

Manuel Wieser | @manuelwieser | manu.ninja Assets Logo Logo Logo Logo

Slide 37

Slide 37 text

Manuel Wieser | @manuelwieser | manu.ninja webpack Inspection ● You can print the resolved webpack config for inspection ○ vue inspect ○ vue inspect --help ● You can use the resolved webpack config as a file (for IDEs or CLI tools) ○ /node_modules/@vue/cli-service/webpack.config.js

Slide 38

Slide 38 text

Manuel Wieser | @manuelwieser | manu.ninja webpack Configuration vue inspect --rule images vue inspect --rule svg

Slide 39

Slide 39 text

Manuel Wieser | @manuelwieser | manu.ninja webpack Configuration module.exports = { chainWebpack: (config) => { config.module.rules.delete('svg'); config.module.rule('images') .test(/\.(svg|png|jpe?g|gif|webp)(\?.*)?$/); }, }; vue.config.js

Slide 40

Slide 40 text

Building

Slide 41

Slide 41 text

Manuel Wieser | @manuelwieser | manu.ninja Browser Compatibility ● package.json (browserlist) or .browserlistrc ● @babel/preset-env and PostCSS’ autoprefixer ● Polyfills are automatically chosen (per default) ● “Modern Mode”

Slide 42

Slide 42 text

Manuel Wieser | @manuelwieser | manu.ninja Browser Compatibility vue-cli-service build --modern dist/js ├── [5.2K] app-legacy.3a1db1b0.js ├── [5.1K] app.053009ed.js ├── [ 80K] chunk-vendors-legacy.bb3a6f6d.js ├── [ 63K] chunk-vendors.c571e522.js

Slide 43

Slide 43 text

Manuel Wieser | @manuelwieser | manu.ninja Browser Compatibility

Slide 44

Slide 44 text

Manuel Wieser | @manuelwieser | manu.ninja Build Targets ● App ● Library ○ Vue is externalized, falls back to global Vue if it can’t be resolved through the bundler ○ CommonJS, UMD, ES Modules (not yet) ● Web Component ○ Vue is externalized, assumes global Vue is available on the host page ○ Single JavaScript file (everything inlined) that registers a custom element

Slide 45

Slide 45 text

Manuel Wieser | @manuelwieser | manu.ninja Build Targets vue build --target wc --name my-footer 'src/components/Footer.vue' dist/my-footer.min.js 16.55 kb 7.53 kb dist/my-footer.js 43.70 kb 12.46 kb

Slide 46

Slide 46 text

Example

Slide 47

Slide 47 text

Manuel Wieser | @manuelwieser | manu.ninja Japanese Phrasebook

Slide 48

Slide 48 text

Manuel Wieser | @manuelwieser | manu.ninja Japanese Phrasebook https://www.japanese-phrasebook.com/ master Branch (GitHub) vue-cli-2 Branch (GitHub) vue-cli-3 Branch (GitHub)

Slide 49

Slide 49 text

Conclusion

Slide 50

Slide 50 text

Vue CLI 3 Official plugins for Babel, TypeScript, ESLint, PostCSS, PWAs, Unit Testing and E2E Testing Compose your project out of plugins instead of selecting from a few pre-defined templates No need to “eject”, so your project can benefit from bugfixes and updates to plugins Fancy GUI Instant Prototyping Ship your code as native ES2015+ or convert your Vue components to Web Components

Slide 51

Slide 51 text

Manuel Wieser | @manuelwieser | manu.ninja Official Documentation ● Vue CLI 3 Guide ● Vue CLI 3 Configuration Reference ● Vue CLI 3 Plugin Development Guide

Slide 52

Slide 52 text

Scaffolding a Progressive Web App using Vue CLI 3 Manuel Wieser webclerks #15