From dc0e2fac41a8b280e89799b2835c18bda001cfde Mon Sep 17 00:00:00 2001 From: NGPixel Date: Tue, 23 May 2017 00:27:16 -0400 Subject: [PATCH] refactor: client-side optimizations + lazy-loading --- client/js/app.js | 15 +++--- client/js/components/anchor.vue | 2 - .../modal-create-page.vue} | 33 ++++++------ .../modal-create-user.vue} | 0 client/js/components/page-loader.js | 4 +- .../{view.js => content-view.component.js} | 33 +++++------- client/js/pages/source-view.component.js | 27 ++++++++++ client/js/pages/source.component.js | 26 --------- client/js/store/index.js | 6 ++- ...n-users-create.js => modal-create-page.js} | 0 client/js/store/modules/modal-create-user.js | 15 ++++++ fuse.js | 37 +++++++++---- package.json | 11 ++-- server/views/pages/view.pug | 3 +- server/views/pages/welcome.pug | 15 +++--- yarn.lock | 53 +++++++++++++------ 16 files changed, 163 insertions(+), 117 deletions(-) rename client/js/{modals/create.vue => components/modal-create-page.vue} (61%) rename client/js/{modals/admin-users-create.vue => components/modal-create-user.vue} (100%) rename client/js/pages/{view.js => content-view.component.js} (52%) create mode 100644 client/js/pages/source-view.component.js delete mode 100644 client/js/pages/source.component.js rename client/js/store/modules/{admin-users-create.js => modal-create-page.js} (100%) create mode 100644 client/js/store/modules/modal-create-user.js diff --git a/client/js/app.js b/client/js/app.js index 67312c47..74c307c8 100644 --- a/client/js/app.js +++ b/client/js/app.js @@ -8,7 +8,7 @@ import Vue from 'vue' import VueResource from 'vue-resource' import VueClipboards from 'vue-clipboards' import store from './store' -import io from 'socket.io-client' +import io from 'socket-io-client' import i18next from 'i18next' import i18nextXHR from 'i18next-xhr-backend' import VueI18Next from '@panter/vue-i18next' @@ -23,14 +23,15 @@ import alertComponent from './components/alert.vue' import anchorComponent from './components/anchor.vue' import colorPickerComponent from './components/color-picker.vue' import loadingSpinnerComponent from './components/loading-spinner.vue' +import modalCreatePageComponent from './components/modal-create-page.vue' +import modalCreateUserComponent from './components/modal-create-user.vue' import searchComponent from './components/search.vue' import treeComponent from './components/tree.vue' -import adminUsersCreateComponent from './modals/admin-users-create.vue' - import adminProfileComponent from './pages/admin-profile.component.js' import adminSettingsComponent from './pages/admin-settings.component.js' -import sourceComponent from './pages/source.component.js' +import contentViewComponent from './pages/content-view.component.js' +import sourceViewComponent from './pages/source-view.component.js' // ==================================== // Initialize Vue Modules @@ -81,12 +82,14 @@ $(() => { alert: alertComponent, adminProfile: adminProfileComponent, adminSettings: adminSettingsComponent, - adminUsersCreate: adminUsersCreateComponent, anchor: anchorComponent, colorPicker: colorPickerComponent, + contentView: contentViewComponent, loadingSpinner: loadingSpinnerComponent, + modalCreatePage: modalCreatePageComponent, + modalCreateUser: modalCreateUserComponent, search: searchComponent, - sourceView: sourceComponent, + sourceView: sourceViewComponent, tree: treeComponent }, store, diff --git a/client/js/components/anchor.vue b/client/js/components/anchor.vue index 63538719..069f03b7 100644 --- a/client/js/components/anchor.vue +++ b/client/js/components/anchor.vue @@ -14,8 +14,6 @@ diff --git a/client/js/modals/admin-users-create.vue b/client/js/components/modal-create-user.vue similarity index 100% rename from client/js/modals/admin-users-create.vue rename to client/js/components/modal-create-user.vue diff --git a/client/js/components/page-loader.js b/client/js/components/page-loader.js index b101b82e..3d778a77 100644 --- a/client/js/components/page-loader.js +++ b/client/js/components/page-loader.js @@ -1,13 +1,13 @@ 'use strict' import $ from 'jquery' -import _ from 'lodash' +import delay from 'lodash/delay' module.exports = { complete () { $('#page-loader').addClass('is-loaded') - _.delay(() => { + delay(() => { $('#page-loader').addClass('is-hidden') }, 1100) } diff --git a/client/js/pages/view.js b/client/js/pages/content-view.component.js similarity index 52% rename from client/js/pages/view.js rename to client/js/pages/content-view.component.js index 7e124e02..faedef2d 100644 --- a/client/js/pages/view.js +++ b/client/js/pages/content-view.component.js @@ -1,23 +1,13 @@ 'use strict' -/* eslint-disable no-new */ - -import $ from 'jquery' import MathJax from 'mathjax' -module.exports = (alerts) => { - if ($('#page-type-view').length) { - let currentBasePath = ($('#page-type-view').data('entrypath') !== 'home') ? $('#page-type-view').data('entrypath') : '' - - // Copy Path - - // new Vue({ - // el: '.modal-copypath', - // render: h => h(CopyPath) - // }) - - // MathJax Render - +export default { + name: 'content-view', + data() { + return {} + }, + mounted() { MathJax.Hub.Config({ jax: ['input/TeX', 'input/MathML', 'output/SVG'], extensions: ['tex2jax.js', 'mml2jax.js'], @@ -36,8 +26,13 @@ module.exports = (alerts) => { messageStyle: 'none' }) MathJax.Hub.Configured() - - require('../modals/create.js')(currentBasePath) - require('../modals/move.js')(currentBasePath, alerts) } } + +// module.exports = (alerts) => { +// if ($('#page-type-view').length) { +// let currentBasePath = ($('#page-type-view').data('entrypath') !== 'home') ? $('#page-type-view').data('entrypath') : '' +// require('../modals/create.js')(currentBasePath) +// require('../modals/move.js')(currentBasePath, alerts) +// } +// } diff --git a/client/js/pages/source-view.component.js b/client/js/pages/source-view.component.js new file mode 100644 index 00000000..8a169d33 --- /dev/null +++ b/client/js/pages/source-view.component.js @@ -0,0 +1,27 @@ +'use strict' + +/* global FuseBox */ + +import pageLoader from '../components/page-loader' + +export default { + name: 'source-view', + data() { + return {} + }, + mounted() { + FuseBox.import('/js/ace/source-view.js', (ace) => { + let scEditor = ace.edit('source-display') + scEditor.setTheme('ace/theme/dawn') + scEditor.getSession().setMode('ace/mode/markdown') + scEditor.setOption('fontSize', '14px') + scEditor.setOption('hScrollBarAlwaysVisible', false) + scEditor.setOption('wrap', true) + scEditor.setReadOnly(true) + scEditor.renderer.updateFull() + scEditor.renderer.on('afterRender', () => { + pageLoader.complete() + }) + }) + } +} diff --git a/client/js/pages/source.component.js b/client/js/pages/source.component.js deleted file mode 100644 index faac5714..00000000 --- a/client/js/pages/source.component.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict' - -import * as ace from 'brace' -import 'brace/theme/tomorrow_night' -import 'brace/mode/markdown' -import pageLoader from '../components/page-loader' - -export default { - name: 'source-view', - data() { - return {} - }, - mounted() { - let scEditor = ace.edit('source-display') - scEditor.setTheme('ace/theme/tomorrow_night') - scEditor.getSession().setMode('ace/mode/markdown') - scEditor.setOption('fontSize', '14px') - scEditor.setOption('hScrollBarAlwaysVisible', false) - scEditor.setOption('wrap', true) - scEditor.setReadOnly(true) - scEditor.renderer.updateFull() - scEditor.renderer.on('afterRender', () => { - pageLoader.complete() - }) - } -} diff --git a/client/js/store/index.js b/client/js/store/index.js index 355d3a98..89195897 100644 --- a/client/js/store/index.js +++ b/client/js/store/index.js @@ -3,7 +3,8 @@ import Vuex from 'vuex' import alert from './modules/alert' import anchor from './modules/anchor' -import adminUsersCreate from './modules/admin-users-create' +import modalCreatePage from './modules/modal-create-page' +import modalCreateUser from './modules/modal-create-user' Vue.use(Vuex) @@ -22,6 +23,7 @@ export default new Vuex.Store({ modules: { alert, anchor, - adminUsersCreate + modalCreatePage, + modalCreateUser } }) diff --git a/client/js/store/modules/admin-users-create.js b/client/js/store/modules/modal-create-page.js similarity index 100% rename from client/js/store/modules/admin-users-create.js rename to client/js/store/modules/modal-create-page.js diff --git a/client/js/store/modules/modal-create-user.js b/client/js/store/modules/modal-create-user.js new file mode 100644 index 00000000..038f5577 --- /dev/null +++ b/client/js/store/modules/modal-create-user.js @@ -0,0 +1,15 @@ +'use strict' + +export default { + state: { + shown: false + }, + getters: {}, + mutations: { + shownChange: (state, shownState) => { state.shown = shownState } + }, + actions: { + adminUsersCreateOpen({ commit }) { commit('shownChange', true) }, + adminUsersCreateClose({ commit }) { commit('shownChange', false) } + } +} diff --git a/fuse.js b/fuse.js index 88a77b50..c5f91166 100644 --- a/fuse.js +++ b/fuse.js @@ -13,7 +13,7 @@ const fs = Promise.promisifyAll(require('fs-extra')) const fsbx = require('fuse-box') const nodemon = require('nodemon') const path = require('path') -const uglify = require('uglify-js') +const uglify = require('uglify-es') // ====================================================== // Parse cmd arguments @@ -64,13 +64,28 @@ let globalTasks = Promise.mapSeries([ if (err.code === 'ENOENT') { console.info(colors.white(' └── ') + colors.green('Copy + Minify ACE modes to assets...')) return fs.ensureDirAsync('./assets/js/ace').then(() => { - return fs.readdirAsync('./node_modules/brace/mode').then(modeList => { - return Promise.map(modeList, mdFile => { - console.info(colors.white(' mode-' + mdFile)) - let result = uglify.minify(path.join('./node_modules/brace/mode', mdFile), { output: { 'max_line_len': 1000000 } }) - return fs.writeFileAsync(path.join('./assets/js/ace', 'mode-' + mdFile), result.code) + return Promise.join( + // Core + Promise.all([ + fs.readFileAsync('./node_modules/brace/index.js', 'utf8'), + fs.readFileAsync('./node_modules/brace/theme/dawn.js', 'utf8'), + fs.readFileAsync('./node_modules/brace/mode/markdown.js', 'utf8') + ]).then(items => { + console.info(colors.white(' source-view.js')) + let result = uglify.minify(items.join(';\n'), { output: { 'max_line_len': 1000000 } }) + return fs.writeFileAsync('./assets/js/ace/source-view.js', result.code) + }), + // Modes + fs.readdirAsync('./node_modules/brace/mode').then(modeList => { + return Promise.map(modeList, mdFile => { + return fs.readFileAsync(path.join('./node_modules/brace/mode', mdFile), 'utf8').then(modeCode => { + console.info(colors.white(' mode-' + mdFile)) + let result = uglify.minify(modeCode, { output: { 'max_line_len': 1000000 } }) + return fs.writeFileAsync(path.join('./assets/js/ace', 'mode-' + mdFile), result.code) + }) + }, { concurrency: 3 }) }) - }) + ) }) } else { throw err @@ -179,7 +194,7 @@ let globalTasks = Promise.mapSeries([ const ALIASES = { 'brace-ext-modelist': 'brace/ext/modelist.js', 'simplemde': 'simplemde/dist/simplemde.min.js', - 'socket.io-client': 'socket.io-client/dist/socket.io.js', + 'socket-io-client': 'socket.io-client/dist/socket.io.js', 'vue': (dev) ? 'vue/dist/vue.js' : 'vue/dist/vue.min.js' } const SHIMS = { @@ -209,7 +224,7 @@ globalTasks.then(() => { ['.scss', fsbx.SassPlugin({ outputStyle: (dev) ? 'nested' : 'compressed' }), fsbx.CSSPlugin()], fsbx.BabelPlugin({ comments: false, presets: ['es2015'] }), fsbx.JSONPlugin(), - !dev && fsbx.UglifyJSPlugin({ + !dev && fsbx.UglifyESPlugin({ compress: { unused: false }, output: { 'max_line_len': 1000000 } }) @@ -225,8 +240,8 @@ globalTasks.then(() => { }) } - const bundleLibs = fuse.bundle('libs').instructions('~ index.js') - const bundleApp = fuse.bundle('app').instructions('!> index.js') + const bundleLibs = fuse.bundle('libs').instructions('~ index.js - brace') + const bundleApp = fuse.bundle('app').instructions('!> [index.js]') const bundleSetup = fuse.bundle('configure').instructions('> configure.js') switch (mode) { diff --git a/package.json b/package.json index a210d0e0..62e64970 100644 --- a/package.json +++ b/package.json @@ -89,8 +89,8 @@ "mime-types": "^2.1.15", "moment": "^2.18.1", "moment-timezone": "^0.5.13", - "mongodb": "^2.2.26", - "mongoose": "^4.10.0", + "mongodb": "^2.2.27", + "mongoose": "^4.10.1", "multer": "^1.3.0", "node-graceful": "^0.2.3", "ora": "^1.2.0", @@ -126,7 +126,7 @@ }, "devDependencies": { "@glimpse/glimpse": "^0.20.9", - "@panter/vue-i18next": "^0.4.1", + "@panter/vue-i18next": "^0.5.0", "babel-cli": "latest", "babel-jest": "latest", "babel-preset-es2015": "latest", @@ -147,6 +147,7 @@ "jquery-simple-upload": "^1.0.0", "jquery-smooth-scroll": "^2.2.0", "jquery-sticky": "^1.0.4", + "lodash-es": "^4.17.4", "mathjax": "^2.7.1", "node-sass": "latest", "nodemon": "latest", @@ -154,11 +155,11 @@ "snyk": "latest", "twemoji-awesome": "^1.0.6", "typescript": "^2.3.2", - "uglify-js": "latest", + "uglify-es": "^3.0.10", "vee-validate": "^2.0.0-rc.3", "vue": "^2.3.3", "vue-clipboards": "^1.0.0", - "vue-resource": "^1.3.1", + "vue-resource": "^1.3.3", "vue-template-compiler": "^2.3.3", "vue-template-es2015-compiler": "^1.5.2", "vuex": "^2.3.1" diff --git a/server/views/pages/view.pug b/server/views/pages/view.pug index 103e45a2..31a44f1d 100644 --- a/server/views/pages/view.pug +++ b/server/views/pages/view.pug @@ -31,7 +31,8 @@ block rootNavRight block content - #page-type-view.page-type-container(data-entrypath=pageData.meta.path) + //- #page-type-view.page-type-container(data-entrypath=pageData.meta.path) + content-view(inline-template) .container.is-fluid.has-mkcontent .columns.is-gapless diff --git a/server/views/pages/welcome.pug b/server/views/pages/welcome.pug index 0366bf2e..86b9395b 100644 --- a/server/views/pages/welcome.pug +++ b/server/views/pages/welcome.pug @@ -2,13 +2,10 @@ extends ../layout.pug block rootNavCenter - block content - - #page-type-welcome - .container - .welcome - img(src='/images/logo.png', alt='Wiki.js') - h1= t('welcome.title') - h2= t('welcome.subtitle') - a.button.is-indigo(href='/create/home')= t('welcome.createhome') + .container + .welcome + img(src='/images/logo.png', alt='Wiki.js') + h1= t('welcome.title') + h2= t('welcome.subtitle') + a.button.is-indigo(href='/create/home')= t('welcome.createhome') diff --git a/yarn.lock b/yarn.lock index fcb62fad..3569373f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -53,9 +53,9 @@ "@glimpse/glimpse-server" "0.20.9" lodash "^4.15.0" -"@panter/vue-i18next@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@panter/vue-i18next/-/vue-i18next-0.4.1.tgz#6b06b783cd4d8f2c80255457d3fa0db6aff1091c" +"@panter/vue-i18next@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@panter/vue-i18next/-/vue-i18next-0.5.0.tgz#3a7928d8113b680ca81a1a899eb5aad34ba9c17a" abab@^1.0.3: version "1.0.3" @@ -4005,6 +4005,10 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +lodash-es@^4.17.4: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.4.tgz#dcc1d7552e150a0640073ba9cb31d70f032950e7" + lodash._baseassign@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" @@ -4457,7 +4461,14 @@ mongodb-core@2.1.10: bson "~1.0.4" require_optional "~1.0.0" -mongodb@2.2.26, "mongodb@>= 1.2.0 <3.0.0", mongodb@^2.2.26: +mongodb-core@2.1.11: + version "2.1.11" + resolved "https://registry.yarnpkg.com/mongodb-core/-/mongodb-core-2.1.11.tgz#1c38776ceb174997a99c28860eed9028da9b3e1a" + dependencies: + bson "~1.0.4" + require_optional "~1.0.0" + +mongodb@2.2.26: version "2.2.26" resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.26.tgz#1bd50c557c277c98e1a05da38c9839c4922b034a" dependencies: @@ -4465,9 +4476,17 @@ mongodb@2.2.26, "mongodb@>= 1.2.0 <3.0.0", mongodb@^2.2.26: mongodb-core "2.1.10" readable-stream "2.2.7" -mongoose@*, mongoose@^4.10.0: - version "4.10.0" - resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.10.0.tgz#f4ff031f8b9e7105ae62b7cb3d4fc4e00f320b87" +"mongodb@>= 1.2.0 <3.0.0", mongodb@^2.2.27: + version "2.2.27" + resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-2.2.27.tgz#34122034db66d983bcf6ab5adb26a24a70fef6e6" + dependencies: + es6-promise "3.2.1" + mongodb-core "2.1.11" + readable-stream "2.2.7" + +mongoose@*, mongoose@^4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/mongoose/-/mongoose-4.10.1.tgz#5982948c51d2174d27b782a89ea502a2a53c9db0" dependencies: async "2.1.4" bson "~1.0.4" @@ -6782,6 +6801,13 @@ uc.micro@^1.0.1, uc.micro@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" +uglify-es@^3.0.10: + version "3.0.10" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.0.10.tgz#8fc9b86f2b57b2805e8863a6fcde1a92210cb885" + dependencies: + commander "~2.9.0" + source-map "~0.5.1" + uglify-js@^2.6, uglify-js@^2.6.1: version "2.8.24" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.24.tgz#48eb5175cf32e22ec11a47e638d7c8b4e0faf2dd" @@ -6791,13 +6817,6 @@ uglify-js@^2.6, uglify-js@^2.6.1: optionalDependencies: uglify-to-browserify "~1.0.0" -uglify-js@latest: - version "3.0.9" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.0.9.tgz#974c5e638f5e2348f8509f0233667caedd52d813" - dependencies: - commander "~2.9.0" - source-map "~0.5.1" - uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" @@ -7024,9 +7043,9 @@ vue-clipboards@^1.0.0: dependencies: clipboard "^1.5.15" -vue-resource@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-1.3.1.tgz#bf2f7b70bfe21b397c9d7607878f776a3acea2cf" +vue-resource@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-1.3.3.tgz#6f12cfc77cccd47fb7e07aff6c42d75e34005992" dependencies: got "^6.7.1"