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

Scaffolding a Progressive Web App using Vue CLI 3 | Stahlstadt.js

Scaffolding a Progressive Web App using Vue CLI 3 | Stahlstadt.js

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
https://www.youtube.com/watch?v=cKwcZTtF_EU

Manuel Wieser

October 09, 2018
Tweet

More Decks by Manuel Wieser

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  5. Installation

    View Slide

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

    View Slide

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

    View Slide

  8. Instant Prototyping

    View Slide

  9. @manuelwieser | https://manu.ninja/
    Instant Prototyping
    npm install -g @vue/cli-service-global
    echo "\
    Hallo Stahlstadt.js\!\
    " > App.vue
    vue serve

    View Slide

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

    View Slide

  11. Instant Prototyping


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

    {{ message }}

    <br/>export default {<br/>props: ['message']<br/>}<br/>

    View Slide

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

    View Slide

  13. Creating a Project

    View Slide

  14. @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 # [email protected]

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  21. @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

    View Slide

  22. Development

    View Slide

  23. @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”

    View Slide

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

    View Slide

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










    View Slide

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

    View Slide

  27. @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 %>

    View Slide

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






    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  32. @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.
    }
    };

    View Slide

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

    View Slide

  34. @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

    View Slide

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

    View Slide

  36. @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

    View Slide

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

    View Slide

  38. @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

    View Slide

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

    View Slide

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



    View Slide

  41. Example

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  45. Links

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide