Slide 1

Slide 1 text

Scaffolding a Progressive Web App using Vue CLI 3 Manuel Wieser Stahlstadt.js #18

Slide 2

Slide 2 text

or My Hero’s Journey with Vue CLI 3 Manuel Wieser Stahlstadt.js #18

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

Basics Vue? Vue (/vjuː/) is a progressive framework for building user interfaces Vue CLI aims to be the standard tooling baseline for the Vue ecosystem

Slide 5

Slide 5 text

Installation

Slide 6

Slide 6 text

@manuelwieser | https://manu.ninja/ Cleanup npm uninstall vue-cli -g # or yarn global remove vue-cli

Slide 7

Slide 7 text

@manuelwieser | https://manu.ninja/ Install npm install -g @vue/cli # or yarn global add @vue/cli

Slide 8

Slide 8 text

Instant Prototyping

Slide 9

Slide 9 text

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

Hallo Stahlstadt.js\!

\ " > App.vue vue serve

Slide 10

Slide 10 text

@manuelwieser | https://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: 'Hallo Stahlstadt.js!' } }, components: { Greeting } };

{{ message }}

export default { props: ['message'] }

Slide 12

Slide 12 text

@manuelwieser | https://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

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

Slide 15

Slide 15 text

@manuelwieser | https://manu.ninja/ 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 16

Slide 16 text

@manuelwieser | https://manu.ninja/ Plugins vue add @vue/pwa # @vue/cli-plugin-pwa # or vue add apollo # vue-cli-plugin-apollo

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

@manuelwieser | https://manu.ninja/ Presets vue create --preset my-preset my-project # or vue create --preset username/repo my-project # or vue create --preset my-preset.json

Slide 19

Slide 19 text

● ~/.vuerc ● Git Repository ○ preset.json ○ Generator.js (optional) ○ Prompt.js (optional) ● Local JSON Presets { "useTaobaoRegistry": false, "presets": { "my-preset": { // … } } }

Slide 20

Slide 20 text

@manuelwieser | https://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

@manuelwieser | https://manu.ninja/ Global CLI Config ˜/.vuerc vue config Target Browsers .browserslistrc package.json (browserslist) Project (webpack, Plugins …) vue.config.js package.json (vue) Babel babel.config.js ESLint .eslintrc package.json (eslintConfig) Typescript tsconfig.json Plugins mostly vue.config.js, plugin.config.js or package.json field Configuration

Slide 22

Slide 22 text

Development

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

@manuelwieser | https://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 25

Slide 25 text

@manuelwieser | https://manu.ninja/ Browser Compatibility

Slide 26

Slide 26 text

@manuelwieser | https://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 27

Slide 27 text

@manuelwieser | https://manu.ninja/ Static Assets Handling ● 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 28

Slide 28 text

@manuelwieser | https://manu.ninja/ Static Assets Handling Logo Logo Logo Logo

Slide 29

Slide 29 text

@manuelwieser | https://manu.ninja/ Working with 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 30

Slide 30 text

@manuelwieser | https://manu.ninja/ Working with webpack ● vue.config.js ● configureWebpack option is merged using webpack-merge ● chainWebpack option allows total control via webpack-chain

Slide 31

Slide 31 text

@manuelwieser | https://manu.ninja/ Working with webpack // vue.config.js module.exports = { configureWebpack: { plugins: [ new MyPlugin() ], } };

Slide 32

Slide 32 text

@manuelwieser | https://manu.ninja/ Working with webpack 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 33

Slide 33 text

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

Slide 34

Slide 34 text

@manuelwieser | https://manu.ninja/ Working with webpack ● 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 35

Slide 35 text

@manuelwieser | https://manu.ninja/ Working with webpack vue inspect --rule svg { test: /\.(svg)(\?.*)?$/, use: [{ loader: 'file-loader', options: { name: 'img/[name].[hash:8].[ext]' } }] }

Slide 36

Slide 36 text

@manuelwieser | https://manu.ninja/ Environment Variables and Modes .env # loaded in all cases .env.local # loaded in all cases, ignored by Git .env.[mode] # loaded in specified mode .env.[mode].local # loaded in specified mode, ignored by Git # .env.[mode].local > .env.[mode] > .env # Variables that exist when Vue CLI is bootstrapped have the highest priority and won’t be overwritten by .env files

Slide 37

Slide 37 text

@manuelwieser | https://manu.ninja/ Environment Variables and Modes ● development is used by vue-cli-service serve ● production is used by vue-cli-service build / test:e2e ● test is used by vue-cli-service test:unit ● You can specify your own modes with the --mode flag

Slide 38

Slide 38 text

@manuelwieser | https://manu.ninja/ Environment Variables and Modes ● Only VUE_APP_* variables will be statically embedded in your build files ○ VUE_APP_SECRET=secret ○ console.log(process.env.VUE_APP_SECRET) ○ "secret" ● NODE_ENV is either "development", "production" or "test" ● BASE_URL corresponds to baseUrl in vue.config.js ● Variables are available inside public/index.html

Slide 39

Slide 39 text

@manuelwieser | https://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 40

Slide 40 text

@manuelwieser | https://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 41

Slide 41 text

Example

Slide 42

Slide 42 text

@manuelwieser | https://manu.ninja/ Japanese Phrasebook

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

Conclusion 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 45

Slide 45 text

Links

Slide 46

Slide 46 text

@manuelwieser | https://manu.ninja/ Official Documentation ● Vue CLI 3 Guide ● Vue CLI 3 Configuration Reference ● Vue CLI 3 Plugin Development Guide

Slide 47

Slide 47 text

@manuelwieser | https://manu.ninja/ 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 48

Slide 48 text

Scaffolding a Progressive Web App using Vue CLI 3 Manuel Wieser Stahlstadt.js #18