Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scaffolding a Progressive Web App using Vue CLI 3 | webclerks

Scaffolding a Progressive Web App using Vue CLI 3 | webclerks

Vue CLI 3 has been released and it’s completely different from its previous version. Discover how it simplifies your toolchain, reduces configuration fatigue and improves your developer experience.

https://manu.ninja/scaffolding-a-progressive-web-app-using-vue-cli-3

Manuel Wieser

November 14, 2018
Tweet

More Decks by Manuel Wieser

Other Decks in Programming

Transcript

  1. Scaffolding a
    Progressive Web App
    using Vue CLI 3

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  6. Installation

    View full-size slide

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

    View full-size slide

  8. Instant Prototyping

    View full-size slide

  9. Manuel Wieser | @manuelwieser | manu.ninja
    Instant Prototyping
    npm install -g @vue/cli-service-global
    echo "\
    Hello webclerks\!\
    " > App.vue
    vue serve

    View full-size slide

  10. 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

    View full-size slide

  11. Instant Prototyping


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

    {{ message }}

    <br/>export default {<br/>props: ['message']<br/>}<br/>
    Greeting.vue
    App.vue

    View full-size slide

  12. 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

    View full-size slide

  13. Creating a Project

    View full-size slide

  14. Manuel Wieser | @manuelwieser | manu.ninja
    Creating a Project
    vue create my-project
    npm install -g @vue/cli-init
    vue init webpack my-project # [email protected]
    vue ui

    View full-size slide

  15. 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"
    }
    }

    View full-size slide

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

    View full-size slide

  17. What’s in a Project?

    View full-size slide

  18. 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

    View full-size slide

  19. 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"
    }

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  22. Vue CLI Plugins

    View full-size slide

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

    View full-size slide

  24. 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

    View full-size slide

  25. 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

    View full-size slide

  26. 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

    View full-size slide

  27. Manuel Wieser | @manuelwieser | manu.ninja
    Plugin Development

    View full-size slide

  28. Configuration

    View full-size slide

  29. 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

    View full-size slide

  30. 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

    View full-size slide

  31. 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

    View full-size slide

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

    View full-size slide

  33. 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.
    }
    };

    View full-size slide

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

    View full-size slide

  35. 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 %>

    View full-size slide

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






    View full-size slide

  37. 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

    View full-size slide

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

    View full-size slide

  39. 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

    View full-size slide

  40. 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”

    View full-size slide

  41. 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

    View full-size slide

  42. Manuel Wieser | @manuelwieser | manu.ninja
    Browser Compatibility










    View full-size slide

  43. 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

    View full-size slide

  44. 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



    View full-size slide

  45. Manuel Wieser | @manuelwieser | manu.ninja
    Japanese Phrasebook

    View full-size slide

  46. 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)

    View full-size slide

  47. 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

    View full-size slide

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

    View full-size slide

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

    View full-size slide