From 36a6cab2cccacd2f4642fe117fa2af242c279148 Mon Sep 17 00:00:00 2001 From: nicejade Date: Mon, 7 May 2018 01:29:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20upgrade=20&=20optimizate=20webpack4=20?= =?UTF-8?q?=F0=9F=98=8A=20#24?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build/utils.js | 61 +- build/vendor-manifest.json | 2 +- build/webpack.base.conf.js | 49 +- build/webpack.dll.conf.js | 41 +- build/webpack.prod.conf.js | 163 +- index.ejs | 2 +- package.json | 61 +- src/assets/scss/bootstrap/_bootstrap.scss | 6 +- src/assets/scss/common.scss | 1 - src/assets/scss/style.scss | 2 +- src/components/CountUp.vue | 2 +- src/views/manage/Adverts.vue | 14 +- src/views/manage/Links.vue | 14 +- src/views/manage/Users.vue | 12 +- static/js/vendor.dll.js | 86 +- test/index.js | 8 +- yarn.lock | 7696 +++++++++++++-------- 17 files changed, 5168 insertions(+), 3052 deletions(-) diff --git a/build/utils.js b/build/utils.js index 7dc098c8..19971e94 100644 --- a/build/utils.js +++ b/build/utils.js @@ -1,6 +1,5 @@ -var path = require('path') -var config = require('../config') -var ExtractTextPlugin = require('extract-text-webpack-plugin') +const path = require('path') +const config = require('../config') exports.assetsPath = function (_path) { var assetsSubDirectory = process.env.NODE_ENV === 'production' @@ -11,41 +10,39 @@ exports.assetsPath = function (_path) { exports.cssLoaders = function (options) { options = options || {} - // generate loader string to be used with extract text plugin - function generateLoaders (loaders) { - var sourceLoader = loaders.map(function (loader) { - var extraParamChar - if (/\?/.test(loader)) { - loader = loader.replace(/\?/, '-loader?') - extraParamChar = '&' - } else { - loader = loader + '-loader' - extraParamChar = '?' - } - return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '') - }).join('!') - // Extract CSS when that option is specified - // (which is the case during production build) - if (options.extract) { - return ExtractTextPlugin.extract({ - use: sourceLoader, - fallback: 'vue-style-loader' + var cssLoader = { + loader: 'css-loader', + options: { + minimize: process.env.NODE_ENV === 'production', + sourceMap: options.sourceMap + } + } + + // generate loader string to be used with extract text plugin + function generateLoaders (loader, loaderOptions) { + var loaders = [cssLoader] + if (loader) { + loaders.push({ + loader: loader + '-loader', + options: Object.assign({}, loaderOptions, { + sourceMap: options.sourceMap + }) }) - } else { - return ['vue-style-loader', sourceLoader].join('!') } + + return ['vue-style-loader'].concat(loaders) } // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html return { - css: generateLoaders(['css']), - postcss: generateLoaders(['css']), - less: generateLoaders(['css', 'less']), - sass: generateLoaders(['css', 'sass?indentedSyntax']), - scss: generateLoaders(['css', 'sass']), - stylus: generateLoaders(['css', 'stylus']), - styl: generateLoaders(['css', 'stylus']) + css: generateLoaders(), + postcss: generateLoaders(), + less: generateLoaders('less'), + sass: generateLoaders('sass', { indentedSyntax: true }), + scss: generateLoaders('sass'), + stylus: generateLoaders('stylus'), + styl: generateLoaders('stylus') } } @@ -57,7 +54,7 @@ exports.styleLoaders = function (options) { var loader = loaders[extension] output.push({ test: new RegExp('\\.' + extension + '$'), - loader: loader + use: loader }) } return output diff --git a/build/vendor-manifest.json b/build/vendor-manifest.json index 72c26bcb..937ceb11 100644 --- a/build/vendor-manifest.json +++ b/build/vendor-manifest.json @@ -1 +1 @@ -{"name":"vendor_library","content":{"./node_modules/axios/lib/utils.js":{"id":0,"meta":{}},"./node_modules/process/browser.js":{"id":1,"meta":{}},"./node_modules/webpack/buildin/global.js":{"id":2,"meta":{}},"./node_modules/axios/lib/defaults.js":{"id":3,"meta":{}},"./node_modules/axios/lib/helpers/bind.js":{"id":4,"meta":{}},"./node_modules/axios/lib/adapters/xhr.js":{"id":5,"meta":{}},"./node_modules/axios/lib/core/createError.js":{"id":6,"meta":{}},"./node_modules/axios/lib/cancel/isCancel.js":{"id":7,"meta":{}},"./node_modules/axios/lib/cancel/Cancel.js":{"id":8,"meta":{}},"./node_modules/crypto-js/core.js":{"id":9,"meta":{}},"./node_modules/raven-js/src/utils.js":{"id":10,"meta":{}},"./node_modules/js-cookie/src/js.cookie.js":{"id":12,"meta":{}},"./node_modules/q/q.js":{"id":13,"meta":{}},"./node_modules/timers-browserify/main.js":{"id":14,"meta":{}},"./node_modules/setimmediate/setImmediate.js":{"id":15,"meta":{}},"./node_modules/axios/index.js":{"id":16,"meta":{}},"./node_modules/axios/lib/axios.js":{"id":17,"meta":{}},"./node_modules/is-buffer/index.js":{"id":18,"meta":{}},"./node_modules/axios/lib/core/Axios.js":{"id":19,"meta":{}},"./node_modules/axios/lib/helpers/normalizeHeaderName.js":{"id":20,"meta":{}},"./node_modules/axios/lib/core/settle.js":{"id":21,"meta":{}},"./node_modules/axios/lib/core/enhanceError.js":{"id":22,"meta":{}},"./node_modules/axios/lib/helpers/buildURL.js":{"id":23,"meta":{}},"./node_modules/axios/lib/helpers/parseHeaders.js":{"id":24,"meta":{}},"./node_modules/axios/lib/helpers/isURLSameOrigin.js":{"id":25,"meta":{}},"./node_modules/axios/lib/helpers/btoa.js":{"id":26,"meta":{}},"./node_modules/axios/lib/helpers/cookies.js":{"id":27,"meta":{}},"./node_modules/axios/lib/core/InterceptorManager.js":{"id":28,"meta":{}},"./node_modules/axios/lib/core/dispatchRequest.js":{"id":29,"meta":{}},"./node_modules/axios/lib/core/transformData.js":{"id":30,"meta":{}},"./node_modules/axios/lib/helpers/isAbsoluteURL.js":{"id":31,"meta":{}},"./node_modules/axios/lib/helpers/combineURLs.js":{"id":32,"meta":{}},"./node_modules/axios/lib/cancel/CancelToken.js":{"id":33,"meta":{}},"./node_modules/axios/lib/helpers/spread.js":{"id":34,"meta":{}},"./node_modules/vue/dist/vue.min.js":{"id":35,"meta":{}},"./node_modules/vue-router/dist/vue-router.common.js":{"id":36,"meta":{}},"./node_modules/vue-i18n/dist/vue-i18n.common.js":{"id":37,"meta":{}},"./node_modules/vuex/dist/vuex.esm.js":{"id":38,"meta":{"harmonyModule":true},"exports":["Store","mapState","mapMutations","mapGetters","mapActions","default"]},"./node_modules/crypto-js/sha256.js":{"id":39,"meta":{}},"./node_modules/crypto-js/md5.js":{"id":40,"meta":{}},"./node_modules/raven-js/src/singleton.js":{"id":41,"meta":{}},"./node_modules/raven-js/src/raven.js":{"id":42,"meta":{}},"./node_modules/raven-js/vendor/TraceKit/tracekit.js":{"id":43,"meta":{}},"./node_modules/raven-js/vendor/json-stringify-safe/stringify.js":{"id":44,"meta":{}},"./node_modules/raven-js/src/configError.js":{"id":45,"meta":{}},"./node_modules/raven-js/src/console.js":{"id":46,"meta":{}}}} \ No newline at end of file +{"name":"vendor_library","content":{"./node_modules/axios/lib/utils.js":{"id":0,"buildMeta":{"providedExports":true}},"./node_modules/webpack/buildin/global.js":{"id":1,"buildMeta":{"providedExports":true}},"./node_modules/raven-js/src/utils.js":{"id":2,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/defaults.js":{"id":3,"buildMeta":{"providedExports":true}},"./node_modules/timers-browserify/main.js":{"id":4,"buildMeta":{"providedExports":true}},"./node_modules/process/browser.js":{"id":5,"buildMeta":{"providedExports":true}},"./node_modules/raven-js/vendor/json-stringify-safe/stringify.js":{"id":6,"buildMeta":{"providedExports":true}},"./node_modules/crypto-js/core.js":{"id":7,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/cancel/Cancel.js":{"id":8,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/cancel/isCancel.js":{"id":9,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/core/createError.js":{"id":10,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/adapters/xhr.js":{"id":11,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/bind.js":{"id":12,"buildMeta":{"providedExports":true}},"./node_modules/raven-js/src/console.js":{"id":13,"buildMeta":{"providedExports":true}},"./node_modules/raven-js/src/configError.js":{"id":14,"buildMeta":{"providedExports":true}},"./node_modules/raven-js/vendor/md5/md5.js":{"id":15,"buildMeta":{"providedExports":true}},"./node_modules/raven-js/vendor/TraceKit/tracekit.js":{"id":16,"buildMeta":{"providedExports":true}},"./node_modules/raven-js/src/raven.js":{"id":17,"buildMeta":{"providedExports":true}},"./node_modules/raven-js/src/singleton.js":{"id":18,"buildMeta":{"providedExports":true}},"./node_modules/crypto-js/md5.js":{"id":19,"buildMeta":{"providedExports":true}},"./node_modules/crypto-js/sha256.js":{"id":20,"buildMeta":{"providedExports":true}},"./node_modules/vuex/dist/vuex.esm.js":{"id":21,"buildMeta":{"exportsType":"namespace","providedExports":["Store","install","mapState","mapMutations","mapGetters","mapActions","createNamespacedHelpers","default"]}},"./node_modules/vue-i18n/dist/vue-i18n.common.js":{"id":22,"buildMeta":{"providedExports":true}},"./node_modules/vue-router/dist/vue-router.esm.js":{"id":23,"buildMeta":{"exportsType":"namespace","providedExports":["default"]}},"./node_modules/vue/dist/vue.min.js":{"id":24,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/spread.js":{"id":25,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/cancel/CancelToken.js":{"id":26,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/combineURLs.js":{"id":27,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/isAbsoluteURL.js":{"id":28,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/core/transformData.js":{"id":29,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/core/dispatchRequest.js":{"id":30,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/core/InterceptorManager.js":{"id":31,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/cookies.js":{"id":32,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/btoa.js":{"id":33,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/isURLSameOrigin.js":{"id":34,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/parseHeaders.js":{"id":35,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/buildURL.js":{"id":36,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/core/enhanceError.js":{"id":37,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/core/settle.js":{"id":38,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/helpers/normalizeHeaderName.js":{"id":39,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/core/Axios.js":{"id":40,"buildMeta":{"providedExports":true}},"./node_modules/is-buffer/index.js":{"id":41,"buildMeta":{"providedExports":true}},"./node_modules/axios/lib/axios.js":{"id":42,"buildMeta":{"providedExports":true}},"./node_modules/axios/index.js":{"id":43,"buildMeta":{"providedExports":true}},"./node_modules/vue-content-placeholder/dist/vue-content-placeholder.min.js":{"id":44,"buildMeta":{"moduleConcatenationBailout":"eval()","providedExports":true}},"./node_modules/vue/dist/vue.runtime.esm.js":{"id":45,"buildMeta":{"exportsType":"namespace","providedExports":["default"]}},"./node_modules/vue-social-sharing/dist/vue-social-sharing.common.js":{"id":46,"buildMeta":{"providedExports":true}},"./node_modules/vue-meta/lib/vue-meta.js":{"id":47,"buildMeta":{"providedExports":true}},"./node_modules/marked/lib/marked.js":{"id":48,"buildMeta":{"providedExports":true}},"./node_modules/countup/dist/countUp.min.js":{"id":49,"buildMeta":{"providedExports":true}},"./node_modules/setimmediate/setImmediate.js":{"id":50,"buildMeta":{"providedExports":true}},"./node_modules/q/q.js":{"id":51,"buildMeta":{"providedExports":true}},"./node_modules/js-cookie/src/js.cookie.js":{"id":52,"buildMeta":{"providedExports":true}}}} \ No newline at end of file diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js index 9ef07fa3..912b4846 100644 --- a/build/webpack.base.conf.js +++ b/build/webpack.base.conf.js @@ -1,20 +1,35 @@ -var path = require('path') -var utils = require('./utils') -var config = require('../config') -var webpack = require('webpack') -var autoprefixer = require('autoprefixer') -var vueLoaderConfig = require('./vue-loader.conf') -var svgoConfig = require('../config/svgo-config.json') -var chalk = require('chalk') -var ProgressBarPlugin = require('progress-bar-webpack-plugin') -var HappyPack = require('happypack') -var os = require('os') -var happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }) +const path = require('path') +const utils = require('./utils') +const config = require('../config') +const webpack = require('webpack') +const autoprefixer = require('autoprefixer') +const vueLoaderConfig = require('./vue-loader.conf') +const svgoConfig = require('../config/svgo-config.json') +const chalk = require('chalk') +const ProgressBarPlugin = require('progress-bar-webpack-plugin') +const HappyPack = require('happypack') +const os = require('os') +const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length }) +const MiniCssExtractPlugin = require('mini-css-extract-plugin') -function resolve (dir) { +const env = process.env.NODE_ENV + +const resolve = (dir) => { return path.join(__dirname, '..', dir) } +const cssLoader = new MiniCssExtractPlugin({ + use: [ + 'happypack/loader?id=happy-css' + ] +}) + +// inject happypack accelerate packing for vue-loader @17-08-18 +Object.assign(vueLoaderConfig.loaders, { + js: 'happypack/loader?id=happy-babel-vue', + css: cssLoader +}) + function createHappyPlugin (id, loaders) { return new HappyPack({ id: id, @@ -27,8 +42,10 @@ function createHappyPlugin (id, loaders) { module.exports = { entry: { - app: './src/main.js' + app: './src/main.js', + vendor: ['lodash'] }, + mode: env === 'production' ? 'production' : 'development', output: { path: config.build.assetsRoot, filename: '[name].js', @@ -107,7 +124,7 @@ module.exports = { test: /\.(woff2?|eot|woff|ttf|otf)(\?.*)?$/, loader: 'url-loader', query: { - limit: 100000, + limit: 8192, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } @@ -140,7 +157,7 @@ module.exports = { createHappyPlugin('happy-babel-js', ['babel-loader?cacheDirectory=true']), createHappyPlugin('happy-babel-vue', ['babel-loader?cacheDirectory=true']), createHappyPlugin('happy-svg', ['svg-sprite-loader']), - // createHappyPlugin('happysass', ['css-loader', 'sass-loader']), + createHappyPlugin('happy-css', ['css-loader', 'vue-style-loader']), new HappyPack({ loaders: [{ path: 'vue-loader', diff --git a/build/webpack.dll.conf.js b/build/webpack.dll.conf.js index 32f26fe1..3e232069 100644 --- a/build/webpack.dll.conf.js +++ b/build/webpack.dll.conf.js @@ -1,8 +1,10 @@ const path = require('path') const webpack = require('webpack') -var HtmlWebpackPlugin = require('html-webpack-plugin') +const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') module.exports = { + mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', entry: { vendor: [ 'js-cookie', @@ -14,10 +16,12 @@ module.exports = { 'vuex', 'crypto-js/sha256', 'crypto-js/md5', - 'raven-js' - // 'vue-touch', - // 'vue-content-placeholder' - // 'vue-social-sharing' + 'raven-js', + 'countup', + 'marked', + 'vue-meta', + 'vue-social-sharing', + 'vue-content-placeholder' ] }, output: { @@ -26,10 +30,10 @@ module.exports = { library: '[name]_library' }, module: { - loaders: [ + rules: [ { test: /\.vue$/, - loader: 'vue' + loader: 'vue-loader' }, { test: /\.js$/, @@ -38,18 +42,27 @@ module.exports = { } ] }, + optimization: { + minimizer: [ + new UglifyJsPlugin({ + cache: true, + parallel: true, + sourceMap: false // set to true if you want JS source maps + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSAssetsPlugin({}) + ] + }, plugins: [ + /* + @desc: https://webpack.js.org/plugins/module-concatenation-plugin/ + "作用域提升(scope hoisting)",使代码体积更小[函数申明会产生大量代码](#webpack3) + */ new webpack.optimize.ModuleConcatenationPlugin(), - new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /zh-cn|en-gb/), new webpack.DllPlugin({ path: path.join(__dirname, '.', '[name]-manifest.json'), - libraryTarget: 'commonjs2', name: '[name]_library' - }), - new webpack.optimize.UglifyJsPlugin({ - compress: { - warnings: false - } }) ] } diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js index 67131c53..8e3c1953 100644 --- a/build/webpack.prod.conf.js +++ b/build/webpack.prod.conf.js @@ -5,15 +5,17 @@ const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf') +// const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') -const ExtractTextPlugin = require('extract-text-webpack-plugin') -const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') +const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin') +const MiniCssExtractPlugin = require('mini-css-extract-plugin') +const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') +const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin') +const loadMinified = require('./load-minified') const LodashModuleReplacementPlugin = require('lodash-webpack-plugin') const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin') -const loadMinified = require('./load-minified') - -const PUBLIC_PATH = 'https://nicelinks.site/' +const Jarvis = require('webpack-jarvis') const env = process.env.NODE_ENV === 'testing' ? require('../config/test.env') @@ -27,26 +29,85 @@ const webpackConfig = merge(baseWebpackConfig, { }) }, devtool: config.build.productionSourceMap ? '#source-map' : false, + // @desc: Documenttion: https://webpack.js.org/configuration/performance/ + performance: { + // Given an asset is created that is over 250kb;false | "error" | "warning"(Default) + hints: 'warning', + // The default value is 250000 (bytes). + maxEntrypointSize: 307200, // (300kb) + // This option controls when webpack emits a performance hint based on individual asset size. The default value is 250000 (bytes). + maxAssetSize: 307200 + }, output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') }, + optimization: { + minimizer: [ + new UglifyJsPlugin({ + cache: true, + parallel: true, + sourceMap: config.build.productionSourceMap // set to true if you want JS source maps + }), + // Compress extracted CSS. We are using this plugin so that possible + // duplicated CSS from different components can be deduped. + new OptimizeCSSAssetsPlugin({}) + ], + // @desc: Documentation:https://www.webpackjs.com/plugins/split-chunks-plugin/ + splitChunks: { + // chunks: "initial","async"和"all"分别是:初始块,按需块或所有块; + chunks: 'async', + // (默认值:30000)块的最小大小 + minSize: 25600, + // (默认值:1)分割前共享模块的最小块数 + minChunks: 1, + // (缺省值5)按需加载时的最大并行请求数 + maxAsyncRequests: 9, + // (默认值3)入口点上的最大并行请求数 + maxInitialRequests: 9, + // webpack 将使用块的起源和名称来生成名称: `vendors~main.js`,如项目与"~"冲突,则可通过此值修改,Eg: '-' + automaticNameDelimiter: '~', + // cacheGroups is an object where keys are the cache group names. + name: true, + cacheGroups: { + // 设置为 false 以禁用默认缓存组 + default: { + minChunks: 2, + // 默认组的优先级为负数,以允许任何自定义缓存组具有更高的优先级(默认值为0) + priority: -20, + // 选项 reuseExistingChunk 允许重复使用现有的块,而不是在模块完全匹配时创建新的块 + reuseExistingChunk: true, + }, + commons: { + name: "commons", + chunks: "initial", + minChunks: 2, + maxInitialRequests: 5 + }, + vendor: { + name: "vendor", + test: /[\\/]node_modules[\\/]/, + priority: -10 + }, + style: { + name: 'style', + test: /\.(scss|css)$/, + priority: 0, + enforce: true + } + } + } + // runtimeChunk: true, adds an additonal chunk to each entrypoint containing only the runtime. + // runtimeChunk: { + // name: 'manifest' + // } + }, plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: '"production"' - } + 'process.env': env }), - // new webpack.optimize.UglifyJsPlugin({ - // compress: { - // warnings: false, - // drop_console: true, - // pure_funcs: ['console.log'] - // }, - // sourceMap: true - // }), new ParallelUglifyPlugin({ cacheDir: '.cache/', uglifyJS: { @@ -61,15 +122,9 @@ const webpackConfig = merge(baseWebpackConfig, { } }), // extract css into its own file - new ExtractTextPlugin({ + new MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css') }), - // Optimize \ minimize CSS assets Using Webpack plugin - new OptimizeCSSPlugin({ - cssProcessorOptions: { - safe: true - } - }), // generate dist index.html with correct asset hash for caching. // you can customize output by editing /index.html // see https://github.com/ampedandwired/html-webpack-plugin @@ -86,41 +141,49 @@ const webpackConfig = merge(baseWebpackConfig, { // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, - // necessary to consistently work with multiple chunks via CommonsChunkPlugin + // necessary to consistently work with multiple chunks via splitChunks chunksSortMode: 'dependency', serviceWorkerLoader: `` }), - // split vendor js into its own file - new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor', - minChunks: function (module, count) { - // any required modules inside node_modules are extracted to vendor - return ( - module.resource && - /\.js$/.test(module.resource) && - module.resource.indexOf( - path.join(__dirname, '../node_modules') - ) === 0 - ) - } - }), - // extract webpack runtime and module manifest to its own file in order to - // prevent vendor hash from being updated whenever app bundle is updated - new webpack.optimize.CommonsChunkPlugin({ - name: 'manifest', - chunks: ['vendor'] + new AddAssetHtmlPlugin({ + filepath: path.resolve(__dirname, 'dist/*.dll.js') }), - // service worker caching + // copy custom static assets + // new CopyWebpackPlugin([ + // { + // from: path.resolve(__dirname, '../static'), + // to: config.build.assetsSubDirectory, + // ignore: ['.*'] + // } + // ]), + /* + @desc: service worker caching, More detailed configuration: + https://github.com/goldhand/sw-precache-webpack-plugin + */ new SWPrecacheWebpackPlugin({ - cacheId: 'nicelinksapp', + cacheId: 'your-app-name', filename: 'service-worker.js', staticFileGlobs: ['dist/**/*.{js,html,css}'], minify: true, - navigateFallback: PUBLIC_PATH + 'index.html', stripPrefix: 'dist/' }), - new LodashModuleReplacementPlugin() + new LodashModuleReplacementPlugin(), + /* + @desc: limit minChunkSize through MinChunkSizePlugin + @reference: https://webpack.js.org/plugins/min-chunk-size-plugin/ + */ + new webpack.optimize.MinChunkSizePlugin({ + minChunkSize: 25600 // Minimum number of characters (25kb) + }), + /* + @desc: 编译之后,您可能会注意到某些块太小 - 创建更大的HTTP开销,那么您可以处理像这样; + @reference: https://webpack.js.org/plugins/limit-chunk-count-plugin/ + */ + new webpack.optimize.LimitChunkCountPlugin({ + maxChunks: 10 // Must be greater than or equal to one + // minChunkSize: 1000 + }) ] }) @@ -147,4 +210,10 @@ if (config.build.bundleAnalyzerReport) { webpackConfig.plugins.push(new BundleAnalyzerPlugin()) } +if (config.build.bundleIntelligentDashboard) { + webpackConfig.plugins.push(new Jarvis({ + port: 1337 // optional: set a port. + })) +} + module.exports = webpackConfig diff --git a/index.ejs b/index.ejs index 3329a531..ddd34355 100644 --- a/index.ejs +++ b/index.ejs @@ -43,7 +43,7 @@
- + diff --git a/package.json b/package.json index 4c3998f6..2a518c15 100644 --- a/package.json +++ b/package.json @@ -38,43 +38,41 @@ "babel-polyfill": "^6.23.0", "countup": "^1.8.2", "crypto-js": "^3.1.9-1", - "element-ui": "^1.2.3", + "element-ui": "1.4.13", "js-cookie": "^2.1.3", "lodash": "^4.17.4", "marked": "^0.3.19", "q": "^1.4.1", "raven-js": "^3.19.1", - "sitemap-generator": "^8.0.0", "vue": "^2.1.10", "vue-content-placeholder": "^1.1.1", "vue-i18n": "^5.0.0", - "vue-meta": "^1.4.3", + "vue-meta": "^1.5.0", "vue-router": "^2.2.0", "vue-social-sharing": "^2.2.6", - "vue-touch": "^2.0.0-beta.4", "vuex": "^2.3.1" }, "devDependencies": { - "autoprefixer": "^6.7.6", + "add-asset-html-webpack-plugin": "^2.1.3", + "autoprefixer": "^6.7.2", "babel-core": "^6.22.1", "babel-eslint": "^7.1.1", "babel-loader": "^6.2.10", - "babel-plugin-component": "^0.9.0", "babel-plugin-istanbul": "^3.1.2", "babel-plugin-lodash": "^3.2.11", "babel-plugin-transform-runtime": "^6.22.0", - "babel-preset-es2015": "^6.22.0", + "babel-preset-env": "^1.2.1", "babel-preset-stage-2": "^6.22.0", "babel-register": "^6.22.0", "chai": "^3.5.0", - "chalk": "^2.3.2", + "chalk": "^1.1.3", "chromedriver": "^2.27.2", - "color": "^2.0.0", "connect-history-api-fallback": "^1.3.0", + "copy-webpack-plugin": "^4.0.1", "cross-env": "^3.1.4", "cross-spawn": "^5.0.1", + "css-hot-loader": "^1.3.9", "css-loader": "^0.26.1", - "cz-conventional-changelog": "^2.0.0", "eslint": "^3.14.1", "eslint-config-standard": "^6.2.1", "eslint-friendly-formatter": "^2.0.7", @@ -84,14 +82,13 @@ "eslint-plugin-standard": "^2.0.1", "eventsource-polyfill": "^0.9.6", "express": "^4.14.1", - "extract-text-webpack-plugin": "^2.1.0", "file-loader": "^0.10.0", "friendly-errors-webpack-plugin": "^1.1.3", "function-bind": "^1.1.0", - "happypack": "^3.0.3", - "html-webpack-plugin": "^2.28.0", + "handlebars": "^4.0.6", + "happypack": "^5.0.0-beta.1", + "html-webpack-plugin": "^3.2.0", "http-proxy-middleware": "^0.17.3", - "husky": "^0.13.3", "inject-loader": "^2.0.1", "karma": "^1.4.1", "karma-coverage": "^1.1.1", @@ -101,40 +98,48 @@ "karma-sourcemap-loader": "^0.3.7", "karma-spec-reporter": "0.0.26", "karma-webpack": "^2.0.2", - "lint-staged": "^3.4.0", + "lint-staged": "^3.6.1", "lodash-webpack-plugin": "^0.11.4", "lolex": "^1.5.2", + "mini-css-extract-plugin": "^0.4.0", "mocha": "^3.2.0", "nightwatch": "^0.9.12", - "node-sass": "^4.7.2", + "node-sass": "^3.13.0", "opn": "^4.0.2", - "optimize-css-assets-webpack-plugin": "^1.3.1", + "optimize-css-assets-webpack-plugin": "^1.3.0", "ora": "^1.1.0", - "phantomjs-prebuilt": "^2.1.15", + "phantomjs-prebuilt": "^2.1.14", + "postcss-loader": "^2.1.5", "pre-commit": "^1.2.2", "progress-bar-webpack-plugin": "^1.9.3", - "sass-loader": "^6.0.0", + "rimraf": "^2.6.0", + "sass-loader": "^4.0.2", + "scss-loader": "^0.0.1", "selenium-server": "^3.0.1", "semver": "^5.3.0", - "shelljs": "^0.7.6", + "shelljs": "^0.7.8", "sinon": "^1.17.7", "sinon-chai": "^2.8.0", - "style-loader": "^0.16.1", + "standard": "^9.0.1", + "style-loader": "^0.21.0", "svg-sprite-loader": "^0.3.0", - "svgo": "^0.7.2", - "svgo-loader": "^1.1.2", - "svgxuse": "^1.2.2", - "sw-precache-webpack-plugin": "^0.11.5", + "svgo": "^0.7.1", + "svgo-loader": "^1.1.0", + "svgxuse": "^1.1.16", + "sw-precache-webpack-plugin": "^0.11.4", "uglify-es": "^3.3.9", + "uglifyjs-webpack-plugin": "^1.2.5", "url-loader": "^0.5.7", - "validate-commit-msg": "^2.12.1", "vue-loader": "^11.0.0", "vue-style-loader": "^2.0.0", - "vue-template-compiler": "^2.1.10", - "webpack": "v3.3.0", + "vue-template-compiler": "^2.5.2", + "webpack": "^4.6.0", + "webpack-build-notifier": "^0.1.13", "webpack-bundle-analyzer": "^2.2.1", + "webpack-cli": "^2.0.14", "webpack-dev-middleware": "^1.10.0", "webpack-hot-middleware": "^2.16.1", + "webpack-jarvis": "^0.2.0", "webpack-merge": "^2.6.1", "webpack-parallel-uglify-plugin": "^1.0.0" }, diff --git a/src/assets/scss/bootstrap/_bootstrap.scss b/src/assets/scss/bootstrap/_bootstrap.scss index fd4697e7..5754013c 100755 --- a/src/assets/scss/bootstrap/_bootstrap.scss +++ b/src/assets/scss/bootstrap/_bootstrap.scss @@ -14,7 +14,7 @@ // Core CSS @import "bootstrap/scaffolding"; -@import "bootstrap/type"; +// @import "bootstrap/type"; // @import "bootstrap/code"; @import "bootstrap/grid"; // @import "bootstrap/tables"; @@ -51,5 +51,5 @@ // @import "bootstrap/carousel"; // Utility classes -@import "bootstrap/utilities"; -@import "bootstrap/responsive-utilities"; +// @import "bootstrap/utilities"; +// @import "bootstrap/responsive-utilities"; diff --git a/src/assets/scss/common.scss b/src/assets/scss/common.scss index 9481692f..b728b027 100644 --- a/src/assets/scss/common.scss +++ b/src/assets/scss/common.scss @@ -77,7 +77,6 @@ input:-ms-input-placeholder{ } .button{ - // @include absolute-center; position: relative; left: 50%; transform: translateX(-50%); diff --git a/src/assets/scss/style.scss b/src/assets/scss/style.scss index 27cced37..d2a3cd95 100644 --- a/src/assets/scss/style.scss +++ b/src/assets/scss/style.scss @@ -1,4 +1,4 @@ -@import 'bootstrap/bootstrap.scss'; +@import 'bootstrap/_bootstrap.scss'; @import "variables.scss"; @import 'mixins.scss'; @import 'common.scss'; diff --git a/src/components/CountUp.vue b/src/components/CountUp.vue index 259727ec..d9268fbd 100644 --- a/src/components/CountUp.vue +++ b/src/components/CountUp.vue @@ -2,7 +2,7 @@ -\\n"],"sourceRoot":"webpack://"}]);\n\n// exports\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvQ29udGVudFBsYWNlaG9sZGVyLnZ1ZT9hMzkxIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7OztBQUdBO0FBQ0Esa0RBQW1ELDJCQUEyQix1QkFBdUIsaUJBQWlCLHFCQUFxQiw0QkFBNEIscUJBQXFCLEdBQUcsd0JBQXdCLGdCQUFnQiwyQkFBMkIsa0JBQWtCLG1CQUFtQix3QkFBd0Isb0JBQW9CLEdBQUcsZ0NBQWdDLEtBQUssb0NBQW9DLE9BQU8scUNBQXFDLEdBQUcseUNBQXlDLDJCQUEyQixrQ0FBa0Msd0NBQXdDLHVDQUF1QyxzQ0FBc0Msd0JBQXdCLGdGQUFnRix1QkFBdUIsR0FBRyxVQUFVLHlGQUF5RixNQUFNLFdBQVcsV0FBVyxVQUFVLFdBQVcsV0FBVyxXQUFXLEtBQUssS0FBSyxVQUFVLFdBQVcsVUFBVSxVQUFVLFdBQVcsV0FBVyxLQUFLLEtBQUssS0FBSyxXQUFXLEtBQUssS0FBSyxXQUFXLEtBQUssS0FBSyxLQUFLLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxXQUFXLFdBQVcsV0FBVyxvSEFBb0gscUJBQXFCLHNDQUFzQyxtQkFBbUIseU9BQXlPLGFBQWEsbUNBQW1DLGFBQWEsY0FBYyxPQUFPLEtBQUssYUFBYSxhQUFhLGlEQUFpRCxjQUFjLG1EQUFtRCxLQUFLLGdCQUFnQix3QkFBd0IsMkNBQTJDLEtBQUssR0FBRyxxQ0FBcUMsMkJBQTJCLHVCQUF1QixpQkFBaUIscUJBQXFCLDRCQUE0QixxQkFBcUIsR0FBRyxTQUFTLGdCQUFnQiwyQkFBMkIsa0JBQWtCLG1CQUFtQix3QkFBd0Isb0JBQW9CLEdBQUcsa0NBQWtDLE9BQU8sc0NBQXNDLFNBQVMsdUNBQXVDLEdBQUcsMEJBQTBCLDJCQUEyQixrQ0FBa0Msd0NBQXdDLHVDQUF1QyxzQ0FBc0Msd0JBQXdCLGdGQUFnRix1QkFBdUIsR0FBRyx5Q0FBeUM7O0FBRXB0RiIsImZpbGUiOiI0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIi4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1wiKSgpO1xuLy8gaW1wb3J0c1xuXG5cbi8vIG1vZHVsZVxuZXhwb3J0cy5wdXNoKFttb2R1bGUuaWQsIFwiXFxuLmJveFtkYXRhLXYtNmFmOWJkZWNdIHtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBwb3NpdGlvbjogcmVsYXRpdmU7XFxuICBoZWlnaHQ6IDEwMCU7XFxuICBtYXJnaW4tYm90dG9tOiAwO1xcbiAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XFxuICBvdmVyZmxvdzogaGlkZGVuO1xcbn1cXG4ucm93W2RhdGEtdi02YWY5YmRlY117XFxuICB3aWR0aDogMTAwJTtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBkaXNwbGF5OiBmbGV4O1xcbiAgZmxleDogMCAxIGF1dG87XFxuICBmbGV4LWRpcmVjdGlvbjogcm93O1xcbiAgZmxleC13cmFwOiB3cmFwO1xcbn1cXG5Aa2V5ZnJhbWVzIHBsYWNlSG9sZGVyU2hpbW1lcntcXG4wJXtcXG4gICAgYmFja2dyb3VuZC1wb3NpdGlvbjogMTAwJSAwXFxufVxcbjEwMCV7XFxuICAgIGJhY2tncm91bmQtcG9zaXRpb246IC0xMDAlIDBcXG59XFxufVxcbi5hbmltYXRlZC1iYWNrZ3JvdW5kW2RhdGEtdi02YWY5YmRlY10ge1xcbiAgYW5pbWF0aW9uLWR1cmF0aW9uOiAxcztcXG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGZvcndhcmRzO1xcbiAgYW5pbWF0aW9uLWl0ZXJhdGlvbi1jb3VudDogaW5maW5pdGU7XFxuICBhbmltYXRpb24tbmFtZTogcGxhY2VIb2xkZXJTaGltbWVyO1xcbiAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogbGluZWFyO1xcbiAgYmFja2dyb3VuZDogI2Y2ZjdmODtcXG4gIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgI2VlZWVlZSA4JSwgI2RkZGRkZCAxOCUsICNlZWVlZWUgMzMlKTtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG59XFxuXCIsIFwiXCIsIHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIi8uL3NyYy9Db250ZW50UGxhY2Vob2xkZXIudnVlPzI5Zjk5NTMwXCJdLFwibmFtZXNcIjpbXSxcIm1hcHBpbmdzXCI6XCI7QUFxQ0E7RUFDQSx1QkFBQTtFQUNBLG1CQUFBO0VBQ0EsYUFBQTtFQUNBLGlCQUFBO0VBQ0Esd0JBQUE7RUFDQSxpQkFBQTtDQUNBO0FBRUE7RUFDQSxZQUFBO0VBQ0EsdUJBQUE7RUFDQSxjQUFBO0VBQ0EsZUFBQTtFQUNBLG9CQUFBO0VBQ0EsZ0JBQUE7Q0FDQTtBQUVBO0FBQ0E7SUFDQSwyQkFBQTtDQUNBO0FBQ0E7SUFDQSw0QkFBQTtDQUNBO0NBQ0E7QUFFQTtFQUNBLHVCQUFBO0VBQ0EsOEJBQUE7RUFDQSxvQ0FBQTtFQUNBLG1DQUFBO0VBQ0Esa0NBQUE7RUFDQSxvQkFBQTtFQUNBLDRFQUFBO0VBQ0EsbUJBQUE7Q0FDQVwiLFwiZmlsZVwiOlwiQ29udGVudFBsYWNlaG9sZGVyLnZ1ZVwiLFwic291cmNlc0NvbnRlbnRcIjpbXCI8dGVtcGxhdGU+XFxuICA8ZGl2IGNsYXNzPVxcXCJhbmltYXRlZC1iYWNrZ3JvdW5kXFxcIiA6c3R5bGU9XFxcIntiYWNrZ3JvdW5kU2l6ZTogc2l6ZX1cXFwiPlxcbiAgICA8ZGl2IGNsYXNzPVxcXCJyb3dcXFwiIDpzdHlsZT1cXFwie2hlaWdodDogcm93LmhlaWdodH1cXFwiIHYtZm9yPVxcXCJyb3cgaW4gZm9ybWF0dGVkUm93c1xcXCI+XFxuICAgICAgPGRpdiA6c3R5bGU9XFxcImJveC5zdHlsZVxcXCIgdi1mb3I9XFxcImJveCBpbiByb3cuYm94ZXNcXFwiPlxcbiAgICAgICAgPGRpdiB2LWlmPVxcXCJib3guc3ViQ2xhc3NcXFwiIDpjbGFzcz1cXFwiYm94LnN1YkNsYXNzXFxcIj48L2Rpdj5cXG4gICAgICA8L2Rpdj5cXG4gICAgPC9kaXY+XFxuICA8L2Rpdj5cXG48L3RlbXBsYXRlPlxcblxcbjxzY3JpcHQ+XFxuaW1wb3J0IHsgZm9ybWF0Um93cyB9IGZyb20gJy4vdXRpbHMnXFxuXFxuZXhwb3J0IGRlZmF1bHQge1xcbiAgZGF0YSAoKSB7XFxuICAgIHJldHVybiB7XFxuICAgIH1cXG4gIH0sXFxuICBwcm9wczoge1xcbiAgICByb3dzOiB7XFxuICAgICAgdHlwZTogQXJyYXksXFxuICAgICAgcmVxdWlyZWQ6IHRydWVcXG4gICAgfSxcXG4gICAgc2l6ZToge1xcbiAgICAgIHR5cGU6IFN0cmluZyxcXG4gICAgICBkZWZhdWx0OiAnMjUwJSdcXG4gICAgfVxcbiAgfSxcXG4gIGNvbXB1dGVkOiB7XFxuICAgIGZvcm1hdHRlZFJvd3MgKCkge1xcbiAgICAgIHJldHVybiBmb3JtYXRSb3dzKHRoaXMucm93cylcXG4gICAgfVxcbiAgfVxcbn1cXG48L3NjcmlwdD5cXG5cXG48c3R5bGUgc2NvcGVkPlxcbi5ib3gge1xcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG4gIGhlaWdodDogMTAwJTtcXG4gIG1hcmdpbi1ib3R0b206IDA7XFxuICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTtcXG4gIG92ZXJmbG93OiBoaWRkZW47XFxufVxcblxcbi5yb3d7XFxuICB3aWR0aDogMTAwJTtcXG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XFxuICBkaXNwbGF5OiBmbGV4O1xcbiAgZmxleDogMCAxIGF1dG87XFxuICBmbGV4LWRpcmVjdGlvbjogcm93O1xcbiAgZmxleC13cmFwOiB3cmFwO1xcbn1cXG5cXG5Aa2V5ZnJhbWVzIHBsYWNlSG9sZGVyU2hpbW1lcntcXG4gIDAle1xcbiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAxMDAlIDBcXG4gIH1cXG4gIDEwMCV7XFxuICAgIGJhY2tncm91bmQtcG9zaXRpb246IC0xMDAlIDBcXG4gIH1cXG59XFxuXFxuLmFuaW1hdGVkLWJhY2tncm91bmQge1xcbiAgYW5pbWF0aW9uLWR1cmF0aW9uOiAxcztcXG4gIGFuaW1hdGlvbi1maWxsLW1vZGU6IGZvcndhcmRzO1xcbiAgYW5pbWF0aW9uLWl0ZXJhdGlvbi1jb3VudDogaW5maW5pdGU7XFxuICBhbmltYXRpb24tbmFtZTogcGxhY2VIb2xkZXJTaGltbWVyO1xcbiAgYW5pbWF0aW9uLXRpbWluZy1mdW5jdGlvbjogbGluZWFyO1xcbiAgYmFja2dyb3VuZDogI2Y2ZjdmODtcXG4gIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCh0byByaWdodCwgI2VlZWVlZSA4JSwgI2RkZGRkZCAxOCUsICNlZWVlZWUgMzMlKTtcXG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcXG59XFxuPC9zdHlsZT5cXG5cIl0sXCJzb3VyY2VSb290XCI6XCJ3ZWJwYWNrOi8vXCJ9XSk7XG5cbi8vIGV4cG9ydHNcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyP3NvdXJjZU1hcCEuL34vdnVlLWxvYWRlci9saWIvc3R5bGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi02YWY5YmRlY1wiLFwic2NvcGVkXCI6dHJ1ZSxcImhhc0lubGluZUNvbmZpZ1wiOmZhbHNlfSEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT1zdHlsZXMmaW5kZXg9MCEuL3NyYy9Db250ZW50UGxhY2Vob2xkZXIudnVlXG4vLyBtb2R1bGUgaWQgPSA0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///4\n')},function(module,exports){eval('/*\r\n\tMIT License http://www.opensource.org/licenses/mit-license.php\r\n\tAuthor Tobias Koppers @sokra\r\n*/\r\n// css base code, injected by the css-loader\r\nmodule.exports = function() {\r\n\tvar list = [];\r\n\r\n\t// return the list of modules as css string\r\n\tlist.toString = function toString() {\r\n\t\tvar result = [];\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar item = this[i];\r\n\t\t\tif(item[2]) {\r\n\t\t\t\tresult.push("@media " + item[2] + "{" + item[1] + "}");\r\n\t\t\t} else {\r\n\t\t\t\tresult.push(item[1]);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn result.join("");\r\n\t};\r\n\r\n\t// import a list of modules into the list\r\n\tlist.i = function(modules, mediaQuery) {\r\n\t\tif(typeof modules === "string")\r\n\t\t\tmodules = [[null, modules, ""]];\r\n\t\tvar alreadyImportedModules = {};\r\n\t\tfor(var i = 0; i < this.length; i++) {\r\n\t\t\tvar id = this[i][0];\r\n\t\t\tif(typeof id === "number")\r\n\t\t\t\talreadyImportedModules[id] = true;\r\n\t\t}\r\n\t\tfor(i = 0; i < modules.length; i++) {\r\n\t\t\tvar item = modules[i];\r\n\t\t\t// skip already imported module\r\n\t\t\t// this implementation is not 100% perfect for weird media query combinations\r\n\t\t\t// when a module is imported multiple times with different media queries.\r\n\t\t\t// I hope this will never occur (Hey this way we have smaller bundles)\r\n\t\t\tif(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {\r\n\t\t\t\tif(mediaQuery && !item[2]) {\r\n\t\t\t\t\titem[2] = mediaQuery;\r\n\t\t\t\t} else if(mediaQuery) {\r\n\t\t\t\t\titem[2] = "(" + item[2] + ") and (" + mediaQuery + ")";\r\n\t\t\t\t}\r\n\t\t\t\tlist.push(item);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\treturn list;\r\n};\r\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L2Nzcy1sb2FkZXIvbGliL2Nzcy1iYXNlLmpzP2RhMDQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBO0FBQ0Esd0NBQXdDLGdCQUFnQjtBQUN4RCxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksb0JBQW9CO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiI1LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuXHRNSVQgTGljZW5zZSBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxyXG5cdEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcclxuKi9cclxuLy8gY3NzIGJhc2UgY29kZSwgaW5qZWN0ZWQgYnkgdGhlIGNzcy1sb2FkZXJcclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcclxuXHR2YXIgbGlzdCA9IFtdO1xyXG5cclxuXHQvLyByZXR1cm4gdGhlIGxpc3Qgb2YgbW9kdWxlcyBhcyBjc3Mgc3RyaW5nXHJcblx0bGlzdC50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xyXG5cdFx0dmFyIHJlc3VsdCA9IFtdO1xyXG5cdFx0Zm9yKHZhciBpID0gMDsgaSA8IHRoaXMubGVuZ3RoOyBpKyspIHtcclxuXHRcdFx0dmFyIGl0ZW0gPSB0aGlzW2ldO1xyXG5cdFx0XHRpZihpdGVtWzJdKSB7XHJcblx0XHRcdFx0cmVzdWx0LnB1c2goXCJAbWVkaWEgXCIgKyBpdGVtWzJdICsgXCJ7XCIgKyBpdGVtWzFdICsgXCJ9XCIpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHJlc3VsdC5wdXNoKGl0ZW1bMV0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gcmVzdWx0LmpvaW4oXCJcIik7XHJcblx0fTtcclxuXHJcblx0Ly8gaW1wb3J0IGEgbGlzdCBvZiBtb2R1bGVzIGludG8gdGhlIGxpc3RcclxuXHRsaXN0LmkgPSBmdW5jdGlvbihtb2R1bGVzLCBtZWRpYVF1ZXJ5KSB7XHJcblx0XHRpZih0eXBlb2YgbW9kdWxlcyA9PT0gXCJzdHJpbmdcIilcclxuXHRcdFx0bW9kdWxlcyA9IFtbbnVsbCwgbW9kdWxlcywgXCJcIl1dO1xyXG5cdFx0dmFyIGFscmVhZHlJbXBvcnRlZE1vZHVsZXMgPSB7fTtcclxuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHRcdHZhciBpZCA9IHRoaXNbaV1bMF07XHJcblx0XHRcdGlmKHR5cGVvZiBpZCA9PT0gXCJudW1iZXJcIilcclxuXHRcdFx0XHRhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzW2lkXSA9IHRydWU7XHJcblx0XHR9XHJcblx0XHRmb3IoaSA9IDA7IGkgPCBtb2R1bGVzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHRcdHZhciBpdGVtID0gbW9kdWxlc1tpXTtcclxuXHRcdFx0Ly8gc2tpcCBhbHJlYWR5IGltcG9ydGVkIG1vZHVsZVxyXG5cdFx0XHQvLyB0aGlzIGltcGxlbWVudGF0aW9uIGlzIG5vdCAxMDAlIHBlcmZlY3QgZm9yIHdlaXJkIG1lZGlhIHF1ZXJ5IGNvbWJpbmF0aW9uc1xyXG5cdFx0XHQvLyAgd2hlbiBhIG1vZHVsZSBpcyBpbXBvcnRlZCBtdWx0aXBsZSB0aW1lcyB3aXRoIGRpZmZlcmVudCBtZWRpYSBxdWVyaWVzLlxyXG5cdFx0XHQvLyAgSSBob3BlIHRoaXMgd2lsbCBuZXZlciBvY2N1ciAoSGV5IHRoaXMgd2F5IHdlIGhhdmUgc21hbGxlciBidW5kbGVzKVxyXG5cdFx0XHRpZih0eXBlb2YgaXRlbVswXSAhPT0gXCJudW1iZXJcIiB8fCAhYWxyZWFkeUltcG9ydGVkTW9kdWxlc1tpdGVtWzBdXSkge1xyXG5cdFx0XHRcdGlmKG1lZGlhUXVlcnkgJiYgIWl0ZW1bMl0pIHtcclxuXHRcdFx0XHRcdGl0ZW1bMl0gPSBtZWRpYVF1ZXJ5O1xyXG5cdFx0XHRcdH0gZWxzZSBpZihtZWRpYVF1ZXJ5KSB7XHJcblx0XHRcdFx0XHRpdGVtWzJdID0gXCIoXCIgKyBpdGVtWzJdICsgXCIpIGFuZCAoXCIgKyBtZWRpYVF1ZXJ5ICsgXCIpXCI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGxpc3QucHVzaChpdGVtKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH07XHJcblx0cmV0dXJuIGxpc3Q7XHJcbn07XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9jc3MtbG9hZGVyL2xpYi9jc3MtYmFzZS5qc1xuLy8gbW9kdWxlIGlkID0gNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///5\n')},function(module,exports){eval("// this module is a runtime utility for cleaner component module output and will\n// be included in the final webpack user bundle\n\nmodule.exports = function normalizeComponent (\n rawScriptExports,\n compiledTemplate,\n scopeId,\n cssModules\n) {\n var esModule\n var scriptExports = rawScriptExports = rawScriptExports || {}\n\n // ES6 modules interop\n var type = typeof rawScriptExports.default\n if (type === 'object' || type === 'function') {\n esModule = rawScriptExports\n scriptExports = rawScriptExports.default\n }\n\n // Vue.extend constructor export interop\n var options = typeof scriptExports === 'function'\n ? scriptExports.options\n : scriptExports\n\n // render functions\n if (compiledTemplate) {\n options.render = compiledTemplate.render\n options.staticRenderFns = compiledTemplate.staticRenderFns\n }\n\n // scopedId\n if (scopeId) {\n options._scopeId = scopeId\n }\n\n // inject cssModules\n if (cssModules) {\n var computed = Object.create(options.computed || null)\n Object.keys(cssModules).forEach(function (key) {\n var module = cssModules[key]\n computed[key] = function () { return module }\n })\n options.computed = computed\n }\n\n return {\n esModule: esModule,\n exports: scriptExports,\n options: options\n }\n}\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9+L3Z1ZS1sb2FkZXIvbGliL2NvbXBvbmVudC1ub3JtYWxpemVyLmpzP2Q0ZjMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUM7QUFDbkMsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjYuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0aGlzIG1vZHVsZSBpcyBhIHJ1bnRpbWUgdXRpbGl0eSBmb3IgY2xlYW5lciBjb21wb25lbnQgbW9kdWxlIG91dHB1dCBhbmQgd2lsbFxuLy8gYmUgaW5jbHVkZWQgaW4gdGhlIGZpbmFsIHdlYnBhY2sgdXNlciBidW5kbGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBub3JtYWxpemVDb21wb25lbnQgKFxuICByYXdTY3JpcHRFeHBvcnRzLFxuICBjb21waWxlZFRlbXBsYXRlLFxuICBzY29wZUlkLFxuICBjc3NNb2R1bGVzXG4pIHtcbiAgdmFyIGVzTW9kdWxlXG4gIHZhciBzY3JpcHRFeHBvcnRzID0gcmF3U2NyaXB0RXhwb3J0cyA9IHJhd1NjcmlwdEV4cG9ydHMgfHwge31cblxuICAvLyBFUzYgbW9kdWxlcyBpbnRlcm9wXG4gIHZhciB0eXBlID0gdHlwZW9mIHJhd1NjcmlwdEV4cG9ydHMuZGVmYXVsdFxuICBpZiAodHlwZSA9PT0gJ29iamVjdCcgfHwgdHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGVzTW9kdWxlID0gcmF3U2NyaXB0RXhwb3J0c1xuICAgIHNjcmlwdEV4cG9ydHMgPSByYXdTY3JpcHRFeHBvcnRzLmRlZmF1bHRcbiAgfVxuXG4gIC8vIFZ1ZS5leHRlbmQgY29uc3RydWN0b3IgZXhwb3J0IGludGVyb3BcbiAgdmFyIG9wdGlvbnMgPSB0eXBlb2Ygc2NyaXB0RXhwb3J0cyA9PT0gJ2Z1bmN0aW9uJ1xuICAgID8gc2NyaXB0RXhwb3J0cy5vcHRpb25zXG4gICAgOiBzY3JpcHRFeHBvcnRzXG5cbiAgLy8gcmVuZGVyIGZ1bmN0aW9uc1xuICBpZiAoY29tcGlsZWRUZW1wbGF0ZSkge1xuICAgIG9wdGlvbnMucmVuZGVyID0gY29tcGlsZWRUZW1wbGF0ZS5yZW5kZXJcbiAgICBvcHRpb25zLnN0YXRpY1JlbmRlckZucyA9IGNvbXBpbGVkVGVtcGxhdGUuc3RhdGljUmVuZGVyRm5zXG4gIH1cblxuICAvLyBzY29wZWRJZFxuICBpZiAoc2NvcGVJZCkge1xuICAgIG9wdGlvbnMuX3Njb3BlSWQgPSBzY29wZUlkXG4gIH1cblxuICAvLyBpbmplY3QgY3NzTW9kdWxlc1xuICBpZiAoY3NzTW9kdWxlcykge1xuICAgIHZhciBjb21wdXRlZCA9IE9iamVjdC5jcmVhdGUob3B0aW9ucy5jb21wdXRlZCB8fCBudWxsKVxuICAgIE9iamVjdC5rZXlzKGNzc01vZHVsZXMpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgdmFyIG1vZHVsZSA9IGNzc01vZHVsZXNba2V5XVxuICAgICAgY29tcHV0ZWRba2V5XSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG1vZHVsZSB9XG4gICAgfSlcbiAgICBvcHRpb25zLmNvbXB1dGVkID0gY29tcHV0ZWRcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZXNNb2R1bGU6IGVzTW9kdWxlLFxuICAgIGV4cG9ydHM6IHNjcmlwdEV4cG9ydHMsXG4gICAgb3B0aW9uczogb3B0aW9uc1xuICB9XG59XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdnVlLWxvYWRlci9saWIvY29tcG9uZW50LW5vcm1hbGl6ZXIuanNcbi8vIG1vZHVsZSBpZCA9IDZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///6\n")},function(module,exports,__webpack_require__){eval("module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;\n return _c('div', {\n staticClass: \"animated-background\",\n style: ({\n backgroundSize: _vm.size\n })\n }, _vm._l((_vm.formattedRows), function(row) {\n return _c('div', {\n staticClass: \"row\",\n style: ({\n height: row.height\n })\n }, _vm._l((row.boxes), function(box) {\n return _c('div', {\n style: (box.style)\n }, [(box.subClass) ? _c('div', {\n class: box.subClass\n }) : _vm._e()])\n }))\n }))\n},staticRenderFns: []}\nmodule.exports.render._withStripped = true\nif (false) {\n module.hot.accept()\n if (module.hot.data) {\n require(\"vue-hot-reload-api\").rerender(\"data-v-6af9bdec\", module.exports)\n }\n}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvQ29udGVudFBsYWNlaG9sZGVyLnZ1ZT8wZjA5Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGdCQUFnQixtQkFBbUIsYUFBYSwwQkFBMEI7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0gsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6IjcuanMiLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cz17cmVuZGVyOmZ1bmN0aW9uICgpe3ZhciBfdm09dGhpczt2YXIgX2g9X3ZtLiRjcmVhdGVFbGVtZW50O3ZhciBfYz1fdm0uX3NlbGYuX2N8fF9oO1xuICByZXR1cm4gX2MoJ2RpdicsIHtcbiAgICBzdGF0aWNDbGFzczogXCJhbmltYXRlZC1iYWNrZ3JvdW5kXCIsXG4gICAgc3R5bGU6ICh7XG4gICAgICBiYWNrZ3JvdW5kU2l6ZTogX3ZtLnNpemVcbiAgICB9KVxuICB9LCBfdm0uX2woKF92bS5mb3JtYXR0ZWRSb3dzKSwgZnVuY3Rpb24ocm93KSB7XG4gICAgcmV0dXJuIF9jKCdkaXYnLCB7XG4gICAgICBzdGF0aWNDbGFzczogXCJyb3dcIixcbiAgICAgIHN0eWxlOiAoe1xuICAgICAgICBoZWlnaHQ6IHJvdy5oZWlnaHRcbiAgICAgIH0pXG4gICAgfSwgX3ZtLl9sKChyb3cuYm94ZXMpLCBmdW5jdGlvbihib3gpIHtcbiAgICAgIHJldHVybiBfYygnZGl2Jywge1xuICAgICAgICBzdHlsZTogKGJveC5zdHlsZSlcbiAgICAgIH0sIFsoYm94LnN1YkNsYXNzKSA/IF9jKCdkaXYnLCB7XG4gICAgICAgIGNsYXNzOiBib3guc3ViQ2xhc3NcbiAgICAgIH0pIDogX3ZtLl9lKCldKVxuICAgIH0pKVxuICB9KSlcbn0sc3RhdGljUmVuZGVyRm5zOiBbXX1cbm1vZHVsZS5leHBvcnRzLnJlbmRlci5fd2l0aFN0cmlwcGVkID0gdHJ1ZVxuaWYgKG1vZHVsZS5ob3QpIHtcbiAgbW9kdWxlLmhvdC5hY2NlcHQoKVxuICBpZiAobW9kdWxlLmhvdC5kYXRhKSB7XG4gICAgIHJlcXVpcmUoXCJ2dWUtaG90LXJlbG9hZC1hcGlcIikucmVyZW5kZXIoXCJkYXRhLXYtNmFmOWJkZWNcIiwgbW9kdWxlLmV4cG9ydHMpXG4gIH1cbn1cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL34vdnVlLWxvYWRlci9saWIvdGVtcGxhdGUtY29tcGlsZXI/e1wiaWRcIjpcImRhdGEtdi02YWY5YmRlY1wifSEuL34vdnVlLWxvYWRlci9saWIvc2VsZWN0b3IuanM/dHlwZT10ZW1wbGF0ZSZpbmRleD0wIS4vc3JjL0NvbnRlbnRQbGFjZWhvbGRlci52dWVcbi8vIG1vZHVsZSBpZCA9IDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///7\n")},function(module,exports,__webpack_require__){eval('// style-loader: Adds some css to the DOM by adding a