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. @manuelwieser | https://manu.ninja/ Manuel Wieser Lead Web Developer karriere.at Lecturer

    Hypermedia User Experience Engineering FH OÖ Campus Hagenberg @manuelwieser https://manu.ninja/
  2. 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
  3. @manuelwieser | https://manu.ninja/ Instant Prototyping npm install -g @vue/cli-service-global echo

    "<template>\ <h1>Hallo Stahlstadt.js\!</h1>\ </template>" > App.vue vue serve
  4. @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
  5. Instant Prototyping <template> <Greeting :message="message"/> </template> <script> import Greeting from

    './Greeting.vue'; export default { data() { return { message: 'Hallo Stahlstadt.js!' } }, components: { Greeting } }; </script> <template> <h1>{{ message }}</h1> </template> <script> export default { props: ['message'] } </script>
  6. @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
  7. @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]
  8. @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" }
  9. 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" } }
  10. @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
  11. • ~/.vuerc • Git Repository ◦ preset.json ◦ Generator.js (optional)

    ◦ Prompt.js (optional) • Local JSON Presets { "useTaobaoRegistry": false, "presets": { "my-preset": { // … } } }
  12. @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
  13. @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”
  14. @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
  15. @manuelwieser | https://manu.ninja/ Browser Compatibility <head> <link href=/js/app.8c81428a.js rel=modulepreload as=script>

    <link href=/js/chunk-vendors.78830d76.js rel=modulepreload as=script> </head> <body> <script type=module src=/js/chunk-vendors.78830d76.js></script> <script type=module src=/js/app.8c81428a.js></script> <script src=/js/chunk-vendors-legacy.c19c13a2.js nomodule></script> <script src=/js/app-legacy.243e8169.js nomodule></script> </body>
  16. @manuelwieser | https://manu.ninja/ HTML • public/index.html is processed with html-webpack-plugin

    ◦ Variables (<link rel="icon" href="<%= BASE_URL %>favicon.ico">) ◦ 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
  17. @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 %>
  18. @manuelwieser | https://manu.ninja/ Static Assets Handling <img src="./assets/logo.svg" alt="Logo"> <!--

    becomes --> <img src="./assets/logo.ec9a16c8.svg" alt="Logo"> <img src="./assets/logo.svg" alt="Logo"> <!-- becomes (after modifying default config) --> <img src="data:image/svg+xml;base64,..." alt="Logo">
  19. @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
  20. @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
  21. @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. } };
  22. @manuelwieser | https://manu.ninja/ Working with webpack module.exports = { chainWebpack:

    config => { config .plugin('html') .tap(args => { return [/* … */] }) } };
  23. @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) ◦ <projectRoot>/node_modules/@vue/cli-service/webpack.config.js
  24. @manuelwieser | https://manu.ninja/ Working with webpack vue inspect --rule svg

    { test: /\.(svg)(\?.*)?$/, use: [{ loader: 'file-loader', options: { name: 'img/[name].[hash:8].[ext]' } }] }
  25. @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
  26. @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
  27. @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
  28. @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
  29. @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 <script src="https://unpkg.com/vue"></script> <script src="./my-footer.js"></script> <my-footer></my-footer>
  30. 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
  31. @manuelwieser | https://manu.ninja/ Official Documentation • Vue CLI 3 Guide

    • Vue CLI 3 Configuration Reference • Vue CLI 3 Plugin Development Guide
  32. @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