diff --git a/lib/app/app.js b/lib/app/app.js index 7280539b06..b15fc16576 100644 --- a/lib/app/app.js +++ b/lib/app/app.js @@ -64,7 +64,7 @@ export function createApp () { router, render (h) { return h('div', { attrs: { id: 'app' }}, [ - h('router-view') + h('router-view', { ref: 'layout' }) ]) } }) diff --git a/lib/app/clientEntry.js b/lib/app/clientEntry.js index 093afa69af..8851846a6b 100644 --- a/lib/app/clientEntry.js +++ b/lib/app/clientEntry.js @@ -1,7 +1,8 @@ -/* global GA_ID, ga */ +/* global BASE_URL, GA_ID, ga, PWA_ENABLED */ import './.temp/polyfill' import { createApp } from './app' +import { register } from 'register-service-worker' const { app, router } = createApp() @@ -31,4 +32,36 @@ if (process.env.NODE_ENV === 'production' && GA_ID) { router.onReady(() => { app.$mount('#app') + + // Register service worker + if (process.env.NODE_ENV === 'production' && PWA_ENABLED) { + register(`${BASE_URL}service-worker.js`, { + ready () { + console.log('[vuepress:pwa] Service worker is active.') + app.$refs.layout.$emit('sw-ready') + }, + cached () { + console.log('[vuepress:pwa] Content has been cached for offline use.') + app.$refs.layout.$emit('sw-cached') + }, + updated () { + console.log('[vuepress:pwa] Content updated.') + app.$refs.layout.$emit('sw-updated') + }, + offline () { + console.log('[vuepress:pwa] No internet connection found. App is running in offline mode.') + app.$refs.layout.$emit('sw-offline') + }, + error (err) { + console.error('[vuepress:pwa] Error during service worker registration:', err) + app.$refs.layout.$emit('sw-error', err) + if (GA_ID) { + ga('send', 'exception', { + exDescription: err.message, + exFatal: false + }) + } + } + }) + } }) diff --git a/lib/build.js b/lib/build.js index a92d38570b..cb273cdcd8 100644 --- a/lib/build.js +++ b/lib/build.js @@ -71,6 +71,15 @@ module.exports = async function build (sourceDir, cliOptions = {}) { await renderPage({ path: '/404.html' }) } + if (options.siteConfig.pwa) { + const wbb = require('workbox-build') + wbb.generateSW({ + swDest: path.resolve(outDir, 'service-worker.js'), + globDirectory: outDir, + globPatterns: ['**\/*.{js,css,html,png,jpg,jpeg,gif,svg,woff,woff2,eot,ttf,otf}'] + }) + } + // DONE. const relativeDir = path.relative(process.cwd(), outDir) console.log(`\n${chalk.green('Success!')} Generated static files in ${chalk.cyan(relativeDir)}.`) diff --git a/lib/default-theme/styles/code.styl b/lib/default-theme/styles/code.styl index 0ed6339265..c9be35b540 100644 --- a/lib/default-theme/styles/code.styl +++ b/lib/default-theme/styles/code.styl @@ -1,6 +1,6 @@ @require './config' -p, h1, h2, h3, h4, h5, h6 +.content code color lighten($textColor, 20%) padding 0.25rem 0.5rem @@ -9,31 +9,33 @@ p, h1, h2, h3, h4, h5, h6 background-color rgba(27,31,35,0.05) border-radius 3px -pre, pre[class*="language-"] - background-color $codeBgColor - color #fff - line-height 1.4 - border-radius 6px - padding 1.25rem 1.5rem - margin 0.85rem 0 - white-space pre-wrap - word-break break-word - overflow auto - position relative - code - font-size 0.85rem - &:before - position absolute - top 0.8em - right 1em - font-size 0.75rem - color rgba(255, 255, 255, 0.4) - -.highlighted-line - background-color rgba(0, 0, 0, 66%) - display block - margin 0.1rem -1.8rem 0 - padding 0.1rem 1.8rem +.content + pre, pre[class*="language-"] + background-color $codeBgColor + line-height 1.4 + border-radius 6px + padding 1.25rem 1.5rem + margin 0.85rem 0 + white-space pre-wrap + word-break break-word + overflow auto + position relative + code + color #fff + padding 0 + background-color none + border-radius 0 + &:before + position absolute + top 0.8em + right 1em + font-size 0.75rem + color rgba(255, 255, 255, 0.4) + .highlighted-line + background-color rgba(0, 0, 0, 66%) + display block + margin 0.1rem -1.8rem 0 + padding 0.1rem 1.8rem pre[class="language-js"], pre[class="language-javascript"] &:before diff --git a/lib/markdown/index.js b/lib/markdown/index.js index f0b4dd429d..17dc6e1edc 100644 --- a/lib/markdown/index.js +++ b/lib/markdown/index.js @@ -32,6 +32,11 @@ module.exports = ({ markdown = {}}) => { includeLevel: [2, 3] }, markdown.toc)) + // apply user config + if (markdown.config) { + markdown.config(md) + } + // override render to allow custom plugins return data const render = md.render md.render = (...args) => { @@ -43,10 +48,5 @@ module.exports = ({ markdown = {}}) => { } } - // apply user config - if (markdown.config) { - markdown.config(md) - } - return md } diff --git a/lib/webpack/createBaseConfig.js b/lib/webpack/createBaseConfig.js index 4a7dea8e2d..76b714d7fa 100644 --- a/lib/webpack/createBaseConfig.js +++ b/lib/webpack/createBaseConfig.js @@ -210,11 +210,13 @@ module.exports = function createBaseConfig ({ }) } - // inject Google analytics ID + // inject constants config - .plugin('ga') + .plugin('injections') .use(require('webpack/lib/DefinePlugin'), [{ - GA_ID: siteConfig.ga ? JSON.stringify(siteConfig.ga) : `false` + BASE_URL: JSON.stringify(siteConfig.base), + GA_ID: siteConfig.ga ? JSON.stringify(siteConfig.ga) : false, + PWA_ENABLED: !!siteConfig.pwa }]) return config diff --git a/package.json b/package.json index aeaaf99d92..994082c312 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "optimize-css-assets-webpack-plugin": "^4.0.0", "postcss-loader": "^2.1.3", "prismjs": "^1.13.0", + "register-service-worker": "^1.2.0", "rimraf": "^2.6.2", "stylus": "^0.54.5", "stylus-loader": "^3.0.2", @@ -84,6 +85,7 @@ "webpack-merge": "^4.1.2", "webpack-serve": "^0.3.1", "webpackbar": "^2.6.1", + "workbox-build": "^3.1.0", "yaml-front-matter": "^4.0.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 65f64243a9..4ba91a7de7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -348,6 +348,13 @@ babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" +babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + balanced-match@^0.4.2: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" @@ -892,6 +899,12 @@ commander@~2.13.0: version "2.13.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" +common-tags@^1.4.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.7.2.tgz#24d9768c63d253a56ecff93845b44b4df1d52771" + dependencies: + babel-runtime "^6.26.0" + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1000,6 +1013,10 @@ copy-webpack-plugin@^4.5.1: p-limit "^1.0.0" serialize-javascript "^1.4.0" +core-js@^2.4.0: + version "2.5.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.5.tgz#b14dde936c640c0579a6b50cabcc132dd6127e3b" + core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1988,6 +2005,14 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +fs-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -2180,7 +2205,7 @@ got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2803,6 +2828,12 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" +isemail@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.1.2.tgz#937cf919002077999a73ea8b1951d590e84e01dd" + dependencies: + punycode "2.x.x" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2947,6 +2978,14 @@ jest-validate@^22.4.0, jest-validate@^22.4.3: leven "^2.1.0" pretty-format "^22.4.3" +joi@^11.1.1: + version "11.4.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-11.4.0.tgz#f674897537b625e9ac3d0b7e1604c828ad913ccb" + dependencies: + hoek "4.x.x" + isemail "3.x.x" + topo "2.x.x" + js-base64@^2.1.9: version "2.4.3" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582" @@ -3038,6 +3077,12 @@ json5@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + optionalDependencies: + graceful-fs "^4.1.6" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -4490,6 +4535,10 @@ prettier@^1.11.1: version "1.11.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.11.1.tgz#61e43fc4cd44e68f2b0dfc2c38cd4bb0fccdcc75" +pretty-bytes@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" + pretty-error@^2.0.2: version "2.1.1" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" @@ -4570,14 +4619,14 @@ punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" +punycode@2.x.x, punycode@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -punycode@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" - q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -4712,6 +4761,10 @@ regenerate@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + regex-cache@^0.4.2: version "0.4.4" resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" @@ -4737,6 +4790,10 @@ regexpu-core@^1.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" +register-service-worker@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/register-service-worker/-/register-service-worker-1.2.0.tgz#c0472dcc856e391ba7a87c0aa96c4f6cf1aec67c" + registry-auth-token@^3.0.1: version "3.3.2" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" @@ -5559,6 +5616,12 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +topo@2.x.x: + version "2.0.2" + resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182" + dependencies: + hoek "4.x.x" + toposort@^1.0.0: version "1.0.6" resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec" @@ -5686,6 +5749,10 @@ unique-string@^1.0.0: dependencies: crypto-random-string "^1.0.0" +universalify@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -6071,6 +6138,87 @@ wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" +workbox-background-sync@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-3.1.0.tgz#8a7afcda4d2cd8ed4aa625c2fb740ed35ff25142" + dependencies: + workbox-core "^3.1.0" + +workbox-broadcast-cache-update@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-broadcast-cache-update/-/workbox-broadcast-cache-update-3.1.0.tgz#bb9845ca1c21357bf5ff3b976398cbc38f073063" + dependencies: + workbox-core "^3.1.0" + +workbox-build@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-3.1.0.tgz#547fb91c6bb3fa93395b512baf776a378ca988e1" + dependencies: + babel-runtime "^6.26.0" + common-tags "^1.4.0" + fs-extra "^4.0.2" + glob "^7.1.2" + joi "^11.1.1" + lodash.template "^4.4.0" + pretty-bytes "^4.0.2" + workbox-background-sync "^3.1.0" + workbox-broadcast-cache-update "^3.1.0" + workbox-cache-expiration "^3.1.0" + workbox-cacheable-response "^3.1.0" + workbox-core "^3.1.0" + workbox-google-analytics "^3.1.0" + workbox-precaching "^3.1.0" + workbox-routing "^3.1.0" + workbox-strategies "^3.1.0" + workbox-sw "^3.1.0" + +workbox-cache-expiration@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-cache-expiration/-/workbox-cache-expiration-3.1.0.tgz#e3178b5109ed9e3e059aa524396da3a3075305c0" + dependencies: + workbox-core "^3.1.0" + +workbox-cacheable-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-3.1.0.tgz#64fdac9101c7718475766ff86e091443260d4348" + dependencies: + workbox-core "^3.1.0" + +workbox-core@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-3.1.0.tgz#974637bf9398b9e37ebd58d73dc6016c0fdc1d23" + +workbox-google-analytics@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-3.1.0.tgz#ce7acd4e56b71ae425708717fe2e8d217b7b5750" + dependencies: + workbox-background-sync "^3.1.0" + workbox-core "^3.1.0" + workbox-routing "^3.1.0" + workbox-strategies "^3.1.0" + +workbox-precaching@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-3.1.0.tgz#fb53f9c8e25d46bcb06da5e160c9b9d2d0e53058" + dependencies: + workbox-core "^3.1.0" + +workbox-routing@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-3.1.0.tgz#05a76ae7083c17402f4493407f15450e42e71bfd" + dependencies: + workbox-core "^3.1.0" + +workbox-strategies@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-3.1.0.tgz#5de2eba844f345da50441f973efdc1c2f763ea58" + dependencies: + workbox-core "^3.1.0" + +workbox-sw@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-3.1.0.tgz#cf8c95a1258973d0fb519573a9d111e30788a7a0" + worker-farm@^1.5.2: version "1.6.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0"