Advertisement
Guest User

Quasar PWA diff

a guest
Aug 25th, 2017
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 15.96 KB | None | 0 0
  1. diff --git a/template/README.md b/template/README.md
  2. index f7a1c4f..c0b0f26 100644
  3. --- a/template/README.md
  4. +++ b/template/README.md
  5. @@ -1,6 +1,6 @@
  6. -# Quasar App
  7. +# Quasar PWA App
  8.  
  9. -> A Quasar project
  10. +> A Quasar PWA project
  11.  
  12.  ## Build Setup
  13.  
  14. @@ -8,7 +8,7 @@
  15.  # install dependencies
  16.  $ npm install
  17.  
  18. -# serve with hot reload at localhost:8080
  19. +# serve with hot reload at localhost:8081
  20.  $ quasar dev
  21.  
  22.  # build for production with minification
  23. diff --git a/template/build/fs-utils.js b/template/build/fs-utils.js
  24. new file mode 100644
  25. index 0000000..92e6c0e
  26. --- /dev/null
  27. +++ b/template/build/fs-utils.js
  28. @@ -0,0 +1,13 @@
  29. +var fs = require('fs')
  30. +var UglifyJS = require('uglify-es')
  31. +
  32. +module.exports = {
  33. +  loadMinified: function (filePath) {
  34. +    var code = fs.readFileSync(filePath, 'utf-8')
  35. +    var result = UglifyJS.minify(code)
  36. +    if (result.error) {
  37. +      return ''
  38. +    }
  39. +    return result.code
  40. +  }
  41. +}
  42. diff --git a/template/build/script.build.js b/template/build/script.build.js
  43. index 31758c0..2e1b37d 100644
  44. --- a/template/build/script.build.js
  45. +++ b/template/build/script.build.js
  46. @@ -3,7 +3,6 @@ process.env.NODE_ENV = 'production'
  47.  require('colors')
  48.  
  49.  var
  50. -  shell = require('shelljs'),
  51.    path = require('path'),
  52.    env = require('./env-utils'),
  53.    css = require('./css-utils'),
  54. @@ -19,9 +18,6 @@ console.log(' building for Cordova or Electron.\n')
  55.  require('./script.clean.js')
  56.  console.log((' Building Quasar App with "' + env.platform.theme + '" theme...\n').bold)
  57.  
  58. -shell.mkdir('-p', targetPath)
  59. -shell.cp('-R', 'src/statics', targetPath)
  60. -
  61.  function finalize () {
  62.    console.log((
  63.      '\n Build complete with "' + env.platform.theme.bold + '" theme in ' +
  64. diff --git a/template/build/service-worker-dev.js b/template/build/service-worker-dev.js
  65. new file mode 100644
  66. index 0000000..979e196
  67. --- /dev/null
  68. +++ b/template/build/service-worker-dev.js
  69. @@ -0,0 +1,17 @@
  70. +// This service worker file is effectively a 'no-op' that will reset any
  71. +// previous service worker registered for the same host:port combination.
  72. +// In the production build, this file is replaced with an actual service worker
  73. +// file that will precache your site's local assets.
  74. +// See https://github.com/facebookincubator/create-react-app/issues/2272#issuecomment-302832432
  75. +
  76. +self.addEventListener('install', () => self.skipWaiting());
  77. +
  78. +self.addEventListener('activate', () => {
  79. +  self.clients.matchAll({ type: 'window' }).then(windowClients => {
  80. +    for (let windowClient of windowClients) {
  81. +      // Force open pages to refresh, so that they have a chance to load the
  82. +      // fresh navigation response from the local dev server.
  83. +      windowClient.navigate(windowClient.url);
  84. +    }
  85. +  });
  86. +});
  87. \ No newline at end of file
  88. diff --git a/template/build/service-worker-prod.js b/template/build/service-worker-prod.js
  89. new file mode 100644
  90. index 0000000..dd6f006
  91. --- /dev/null
  92. +++ b/template/build/service-worker-prod.js
  93. @@ -0,0 +1,55 @@
  94. +(function() {
  95. +  'use strict';
  96. +
  97. +  // Check to make sure service workers are supported in the current browser,
  98. +  // and that the current page is accessed from a secure origin. Using a
  99. +  // service worker from an insecure origin will trigger JS console errors.
  100. +  const isLocalhost = Boolean(window.location.hostname === 'localhost' ||
  101. +      // [::1] is the IPv6 localhost address.
  102. +      window.location.hostname === '[::1]' ||
  103. +      // 127.0.0.1/8 is considered localhost for IPv4.
  104. +      window.location.hostname.match(
  105. +        /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
  106. +      )
  107. +    );
  108. +
  109. +  window.addEventListener('load', function() {
  110. +      if ('serviceWorker' in navigator &&
  111. +          (window.location.protocol === 'https:' || isLocalhost)) {
  112. +        navigator.serviceWorker.register('service-worker.js')
  113. +        .then(function(registration) {
  114. +          // updatefound is fired if service-worker.js changes.
  115. +          registration.onupdatefound = function() {
  116. +            // updatefound is also fired the very first time the SW is installed,
  117. +            // and there's no need to prompt for a reload at that point.
  118. +            // So check here to see if the page is already controlled,
  119. +            // i.e. whether there's an existing service worker.
  120. +            if (navigator.serviceWorker.controller) {
  121. +              // The updatefound event implies that registration.installing is set
  122. +              const installingWorker = registration.installing;
  123. +
  124. +              installingWorker.onstatechange = function() {
  125. +                switch (installingWorker.state) {
  126. +                  case 'installed':
  127. +                    // At this point, the old content will have been purged and the
  128. +                    // fresh content will have been added to the cache.
  129. +                    // It's the perfect time to display a "New content is
  130. +                    // available; please refresh." message in the page's interface.
  131. +                    break;
  132. +
  133. +                  case 'redundant':
  134. +                    throw new Error('The installing ' +
  135. +                                    'service worker became redundant.');
  136. +
  137. +                  default:
  138. +                    // Ignore
  139. +                }
  140. +              };
  141. +            }
  142. +          };
  143. +        }).catch(function(e) {
  144. +          console.error('Error during service worker registration:', e);
  145. +        });
  146. +      }
  147. +  });
  148. +})();
  149. diff --git a/template/build/webpack.base.conf.js b/template/build/webpack.base.conf.js
  150. index 8fff6ef..d42105a 100644
  151. --- a/template/build/webpack.base.conf.js
  152. +++ b/template/build/webpack.base.conf.js
  153. @@ -59,7 +59,13 @@ module.exports = {
  154.            loaders: merge({js: 'babel-loader'}, cssUtils.styleLoaders({
  155.              sourceMap: useCssSourceMap,
  156.              extract: env.prod
  157. -          }))
  158. +          })),
  159. +          transformToRequire: {
  160. +            video: 'src',
  161. +            source: 'src',
  162. +            img: 'src',
  163. +            image: 'xlink:href'
  164. +          }
  165.          }
  166.        },
  167.        {
  168. diff --git a/template/build/webpack.dev.conf.js b/template/build/webpack.dev.conf.js
  169. index b4dd19e..4c3d8d1 100644
  170. --- a/template/build/webpack.dev.conf.js
  171. +++ b/template/build/webpack.dev.conf.js
  172. @@ -1,4 +1,6 @@
  173.  var
  174. +  fs = require('fs'),
  175. +  path = require('path'),
  176.    config = require('../config'),
  177.    webpack = require('webpack'),
  178.    merge = require('webpack-merge'),
  179. @@ -31,13 +33,12 @@ module.exports = merge(baseWebpackConfig, {
  180.      new HtmlWebpackPlugin({
  181.        filename: 'index.html',
  182.        template: 'src/index.html',
  183. -      inject: true
  184. +      inject: true,
  185. +      serviceWorkerLoader: `<script>${fs.readFileSync(path.join(__dirname,
  186. +        './service-worker-dev.js'), 'utf-8')}</script>`
  187.      }),
  188.      new FriendlyErrorsPlugin({
  189.        clearConsole: config.dev.clearConsoleOnRebuild
  190.      })
  191. -  ],
  192. -  performance: {
  193. -    hints: false
  194. -  }
  195. +  ]
  196.  })
  197. diff --git a/template/build/webpack.prod.conf.js b/template/build/webpack.prod.conf.js
  198. index c25411b..f8f5bc5 100644
  199. --- a/template/build/webpack.prod.conf.js
  200. +++ b/template/build/webpack.prod.conf.js
  201. @@ -7,7 +7,10 @@ var
  202.    baseWebpackConfig = require('./webpack.base.conf'),
  203.    ExtractTextPlugin = require('extract-text-webpack-plugin'),
  204.    HtmlWebpackPlugin = require('html-webpack-plugin'),
  205. -  OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
  206. +  OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin'),
  207. +  CopyWebpackPlugin = require('copy-webpack-plugin'),
  208. +  SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin'),
  209. +  fsUtils = require('./fs-utils')
  210.  
  211.  module.exports = merge(baseWebpackConfig, {
  212.    module: {
  213. @@ -49,7 +52,9 @@ module.exports = merge(baseWebpackConfig, {
  214.          // https://github.com/kangax/html-minifier#options-quick-reference
  215.        },
  216.        // necessary to consistently work with multiple chunks via CommonsChunkPlugin
  217. -      chunksSortMode: 'dependency'
  218. +      chunksSortMode: 'dependency',
  219. +      serviceWorkerLoader: `<script>${fsUtils.loadMinified(path.join(__dirname,
  220. +        './service-worker-prod.js'))}</script>`
  221.      }),
  222.      // split vendor js into its own file
  223.      new webpack.optimize.CommonsChunkPlugin({
  224. @@ -73,6 +78,22 @@ module.exports = merge(baseWebpackConfig, {
  225.      new webpack.optimize.CommonsChunkPlugin({
  226.        name: 'manifest',
  227.        chunks: ['vendor']
  228. +    }),
  229. +    // copy custom static assets
  230. +    new CopyWebpackPlugin([
  231. +      {
  232. +        from: path.resolve(__dirname, '../src/statics'),
  233. +        to: 'statics',
  234. +        ignore: ['.*']
  235. +      }
  236. +    ]),
  237. +    // service worker caching
  238. +    new SWPrecacheWebpackPlugin({
  239. +      cacheId: 'my-quasar-app',
  240. +      filename: 'service-worker.js',
  241. +      staticFileGlobs: ['dist/**/*.{js,html,css,woff,svg}'],
  242. +      minify: true,
  243. +      stripPrefix: 'dist/'
  244.      })
  245.    ]
  246.  })
  247. diff --git a/template/config/index.js b/template/config/index.js
  248. index 89c2580..9d07490 100644
  249. --- a/template/config/index.js
  250. +++ b/template/config/index.js
  251. @@ -32,7 +32,7 @@ module.exports = {
  252.      // auto open browser or not
  253.      openBrowser: true,
  254.      publicPath: '/',
  255. -    port: 8080,
  256. +    port: 8081,
  257.  
  258.      // If for example you are using Quasar Play
  259.      // to generate a QR code then on each dev (re)compilation
  260. diff --git a/template/package.json b/template/package.json
  261. index 22ab124..0e22a06 100644
  262. --- a/template/package.json
  263. +++ b/template/package.json
  264. @@ -26,6 +26,7 @@
  265.      "babel-preset-stage-2": "^6.0.0",
  266.      "colors": "^1.1.2",
  267.      "connect-history-api-fallback": "^1.1.0",
  268. +    "copy-webpack-plugin": "^4.0.1",
  269.      "css-loader": "^0.28.0",
  270.      "es6-promise": "^4.1.1",
  271.      "eslint": "^4.4.1",
  272. @@ -54,6 +55,8 @@
  273.      "shelljs": "^0.7.0",
  274.      "stylus": "^0.54.5",
  275.      "stylus-loader": "^3.0.1",
  276. +    "sw-precache-webpack-plugin": "^0.11.4",
  277. +    "uglify-es": "^3.0.28",
  278.      "url-loader": "^0.5.7",
  279.      "vue-loader": "~12.2.2",
  280.      "vue-style-loader": "^3.0.1",
  281. diff --git a/template/src/index.html b/template/src/index.html
  282. index 4e7bfd2..d961466 100644
  283. --- a/template/src/index.html
  284. +++ b/template/src/index.html
  285. @@ -1,16 +1,40 @@
  286.  <!DOCTYPE html>
  287. -<html>
  288. +<html lang="en">
  289.    <head>
  290.      <meta charset="utf-8">
  291. +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  292.      <meta name="format-detection" content="telephone=no">
  293.      <meta name="msapplication-tap-highlight" content="no">
  294. -    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
  295. +    <meta name="viewport" content="width=device-width, initial-scale=1">
  296.  
  297. -    <title>Quasar App</title>
  298. -    <link rel="icon" href="statics/quasar-logo.png" type="image/x-icon">
  299. +    <title>Quasar PWA App</title>
  300. +    <link rel="icon" type="image/png" sizes="32x32" href="<%= htmlWebpackPlugin.files.publicPath %>statics/icons/favicon-32x32.png">
  301. +    <link rel="icon" type="image/png" sizes="16x16" href="<%= htmlWebpackPlugin.files.publicPath %>statics/icons/favicon-16x16.png">
  302. +    <link rel="manifest" href="<%= htmlWebpackPlugin.files.publicPath %>statics/manifest.json">
  303. +
  304. +    <!-- Add to home screen for Safari on iOS -->
  305. +    <meta name="apple-mobile-web-app-capable" content="yes">
  306. +    <meta name="apple-mobile-web-app-status-bar-style" content="white">
  307. +    <meta name="apple-mobile-web-app-title" content="Quasar App">
  308. +    <link rel="apple-touch-icon" href="<%= htmlWebpackPlugin.files.publicPath %>statics/icons/apple-icon-152x152.png">
  309. +    <!-- Add to home screen for Windows -->
  310. +    <meta name="msapplication-TileImage" content="<%= htmlWebpackPlugin.files.publicPath %>statics/icons/ms-icon-144x144.png">
  311. +    <meta name="msapplication-TileColor" content="#ffffff">
  312. +
  313. +    <meta name="theme-color" content="#027be3">
  314. +
  315. +    <% for (var chunk of webpack.chunks) {
  316. +        for (var file of chunk.files) {
  317. +          if (file.match(/\.(js|css)$/)) { %>
  318. +    <link rel="<%= chunk.initial?'preload':'prefetch' %>" href="<%= htmlWebpackPlugin.files.publicPath + file %>" as="<%= file.match(/\.css$/)?'style':'script' %>"><% }}} %>
  319.    </head>
  320.    <body>
  321. +    <noscript>
  322. +      This is your fallback content in case JavaScript fails to load.
  323. +    </noscript>
  324.      <div id="q-app"></div>
  325. +    <!-- Todo: only include in production -->
  326. +    <%= htmlWebpackPlugin.options.serviceWorkerLoader %>
  327.      <!-- built files will be auto injected -->
  328.    </body>
  329.  </html>
  330. diff --git a/template/src/main.js b/template/src/main.js
  331. index 1958813..c62777f 100644
  332. --- a/template/src/main.js
  333. +++ b/template/src/main.js
  334. @@ -18,18 +18,16 @@ Vue.config.productionTip = false
  335.  Vue.use(Quasar) // Install Quasar Framework
  336.  
  337.  if (__THEME === 'mat') {
  338. -  require('quasar-extras/roboto-font')
  339. +  // require('quasar-extras/roboto-font')
  340.  }
  341. -import 'quasar-extras/material-icons'
  342. +// import 'quasar-extras/material-icons'
  343.  // import 'quasar-extras/ionicons'
  344.  // import 'quasar-extras/fontawesome'
  345.  // import 'quasar-extras/animate'
  346.  
  347. -Quasar.start(() => {
  348. -  /* eslint-disable no-new */
  349. -  new Vue({
  350. -    el: '#q-app',
  351. -    router,
  352. -    render: h => h(require('./App'))
  353. -  })
  354. +/* eslint-disable no-new */
  355. +new Vue({
  356. +  el: '#q-app',
  357. +  router,
  358. +  render: h => h(require('./App'))
  359.  })
  360. diff --git a/template/src/router.js b/template/src/router.js
  361. index d21dc28..8c06c76 100644
  362. --- a/template/src/router.js
  363. +++ b/template/src/router.js
  364. @@ -1,12 +1,18 @@
  365.  import Vue from 'vue'
  366.  import VueRouter from 'vue-router'
  367.  
  368. +import Hello from '@/Hello.vue'
  369. +
  370.  Vue.use(VueRouter)
  371.  
  372. +/*
  373. + * Uncomment this section and use "load()" if you want
  374. + * to lazy load routes.
  375.  function load (component) {
  376.    // '@' is aliased to src/components
  377.    return () => import(`@/${component}.vue`)
  378.  }
  379. +*/
  380.  
  381.  export default new VueRouter({
  382.    /*
  383. @@ -22,9 +28,6 @@ export default new VueRouter({
  384.     */
  385.  
  386.    routes: [
  387. -    { path: '/', component: load('Hello') },
  388. -
  389. -    // Always leave this last one
  390. -    { path: '*', component: load('Error404') } // Not found
  391. +    { path: '/', component: Hello }
  392.    ]
  393.  })
  394. diff --git a/template/src/statics/icons/apple-icon-152x152.png b/template/src/statics/icons/apple-icon-152x152.png
  395. new file mode 100644
  396. index 0000000..c918acd
  397. Binary files /dev/null and b/template/src/statics/icons/apple-icon-152x152.png differ
  398. diff --git a/template/src/statics/icons/favicon-16x16.png b/template/src/statics/icons/favicon-16x16.png
  399. new file mode 100644
  400. index 0000000..177c86e
  401. Binary files /dev/null and b/template/src/statics/icons/favicon-16x16.png differ
  402. diff --git a/template/src/statics/icons/favicon-32x32.png b/template/src/statics/icons/favicon-32x32.png
  403. new file mode 100644
  404. index 0000000..b8e6cdf
  405. Binary files /dev/null and b/template/src/statics/icons/favicon-32x32.png differ
  406. diff --git a/template/src/statics/icons/icon-192x192.png b/template/src/statics/icons/icon-192x192.png
  407. new file mode 100644
  408. index 0000000..2a9b50b
  409. Binary files /dev/null and b/template/src/statics/icons/icon-192x192.png differ
  410. diff --git a/template/src/statics/icons/icon-512x512.png b/template/src/statics/icons/icon-512x512.png
  411. new file mode 100644
  412. index 0000000..a57354e
  413. Binary files /dev/null and b/template/src/statics/icons/icon-512x512.png differ
  414. diff --git a/template/src/statics/icons/ms-icon-144x144.png b/template/src/statics/icons/ms-icon-144x144.png
  415. new file mode 100644
  416. index 0000000..b0880e8
  417. Binary files /dev/null and b/template/src/statics/icons/ms-icon-144x144.png differ
  418. diff --git a/template/src/statics/manifest.json b/template/src/statics/manifest.json
  419. new file mode 100644
  420. index 0000000..c98ebf6
  421. --- /dev/null
  422. +++ b/template/src/statics/manifest.json
  423. @@ -0,0 +1,20 @@
  424. +{
  425. +  "name": "Quasar App",
  426. +  "short_name": "Quasar-PWA",
  427. +  "icons": [
  428. +    {
  429. +      "src": "/statics/icons/icon-192x192.png",
  430. +      "sizes": "192x192",
  431. +      "type": "image/png"
  432. +    },
  433. +    {
  434. +      "src": "/statics/icons/icon-512x512.png",
  435. +      "sizes": "512x512",
  436. +      "type": "image/png"
  437. +    }
  438. +  ],
  439. +  "start_url": "/index.html",
  440. +  "display": "standalone",
  441. +  "background_color": "#ffffff",
  442. +  "theme_color": "#027be3"
  443. +}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement