diff --git a/frontend/.babelrc b/frontend/.babelrc index 3a280ba..43636c3 100644 --- a/frontend/.babelrc +++ b/frontend/.babelrc @@ -1,12 +1,4 @@ { - "presets": [ - ["env", { - "modules": false, - "targets": { - "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] - } - }], - "stage-2" - ], - "plugins": ["transform-vue-jsx", "transform-runtime"] + "presets": ["@babel/preset-env"], + "plugins": ["@vue/babel-plugin-transform-vue-jsx", "@babel/plugin-transform-runtime"] } diff --git a/frontend/build/utils.js b/frontend/build/utils.js index e534fb0..1533d94 100644 --- a/frontend/build/utils.js +++ b/frontend/build/utils.js @@ -1,7 +1,7 @@ 'use strict' const path = require('path') const config = require('../config') -const ExtractTextPlugin = require('extract-text-webpack-plugin') +const MiniCssExtractPlugin = require('mini-css-extract-plugin') const packageConfig = require('../package.json') exports.assetsPath = function (_path) { @@ -25,13 +25,30 @@ exports.cssLoaders = function (options) { const postcssLoader = { loader: 'postcss-loader', options: { - sourceMap: options.sourceMap + sourceMap: options.sourceMap, + plugins: () => [ + require('autoprefixer') + ], } } // generate loader string to be used with extract text plugin function generateLoaders (loader, loaderOptions) { - const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] + const loaders = [] + + // Extract CSS when that option is specified + // (which is the case during production build) + if (options.extract) { + loaders.push(MiniCssExtractPlugin.loader) + } else { + loaders.push('vue-style-loader') + } + + loaders.push(cssLoader) + + if (options.usePostCSS) { + loaders.push(postcssLoader) + } if (loader) { loaders.push({ @@ -42,16 +59,7 @@ exports.cssLoaders = function (options) { }) } - // Extract CSS when that option is specified - // (which is the case during production build) - if (options.extract) { - return ExtractTextPlugin.extract({ - use: loaders, - fallback: 'vue-style-loader' - }) - } else { - return ['vue-style-loader'].concat(loaders) - } + return loaders } // https://vue-loader.vuejs.org/en/configurations/extract-css.html diff --git a/frontend/build/webpack.base.conf.js b/frontend/build/webpack.base.conf.js index 1f4f47e..8904e70 100644 --- a/frontend/build/webpack.base.conf.js +++ b/frontend/build/webpack.base.conf.js @@ -3,6 +3,7 @@ const path = require('path') const utils = require('./utils') const config = require('../config') const vueLoaderConfig = require('./vue-loader.conf') +const { VueLoaderPlugin } = require('vue-loader') function resolve (dir) { return path.join(__dirname, '..', dir) @@ -31,6 +32,9 @@ module.exports = { ? config.build.assetsPublicPath : config.dev.assetsPublicPath }, + plugins: [ + new VueLoaderPlugin(), + ], resolve: { extensions: ['.js', '.vue', '.json'], alias: { @@ -49,7 +53,10 @@ module.exports = { { test: /\.js$/, loader: 'babel-loader', - include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')], + exclude: file => ( + /node_modules/.test(file) && !/\.vue\.js/.test(file) + ), }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, diff --git a/frontend/build/webpack.prod.conf.js b/frontend/build/webpack.prod.conf.js index d9f99f6..b7b1afb 100644 --- a/frontend/build/webpack.prod.conf.js +++ b/frontend/build/webpack.prod.conf.js @@ -7,13 +7,14 @@ 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 MiniCssExtractPlugin = require('mini-css-extract-plugin') const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') -const UglifyJsPlugin = require('uglifyjs-webpack-plugin') +const TerserPlugin = require('terser-webpack-plugin'); const env = require('../config/prod.env') const webpackConfig = merge(baseWebpackConfig, { + mode: 'production', module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, @@ -32,23 +33,9 @@ const webpackConfig = merge(baseWebpackConfig, { new webpack.DefinePlugin({ 'process.env': env }), - new UglifyJsPlugin({ - uglifyOptions: { - compress: { - warnings: false - } - }, - sourceMap: config.build.productionSourceMap, - parallel: true - }), // extract css into its own file - new ExtractTextPlugin({ - filename: utils.assetsPath('css/[name].[contenthash].css'), - // Setting the following option to `false` will not extract CSS from codesplit chunks. - // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack. - // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`, - // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110 - allChunks: true, + new MiniCssExtractPlugin({ + filename: utils.assetsPath('css/[name].[contenthash].css') }), // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. @@ -74,40 +61,10 @@ const webpackConfig = merge(baseWebpackConfig, { // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), + new webpack.NamedChunksPlugin(), // keep module.id stable when vendor modules does not change new webpack.HashedModuleIdsPlugin(), - // enable scope hoisting - new webpack.optimize.ModuleConcatenationPlugin(), - // split vendor js into its own file - new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor', - minChunks (module) { - // 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', - minChunks: Infinity - }), - // This instance extracts shared chunks from code splitted chunks and bundles them - // in a separate chunk, similar to the vendor chunk - // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk - new webpack.optimize.CommonsChunkPlugin({ - name: 'app', - async: 'vendor-async', - children: true, - minChunks: 3 - }), - // copy custom static assets new CopyWebpackPlugin([ { @@ -116,7 +73,29 @@ const webpackConfig = merge(baseWebpackConfig, { ignore: ['.*'] } ]) - ] + ], + optimization: { + splitChunks: { + chunks: 'all', + cacheGroups: { + vendor: { + name: 'vendor', + test: /[\\/]node_modules[\\/]/, + enforce: true, + }, + }, + }, + runtimeChunk: 'single', + minimizer: [ + new TerserPlugin({ + parallel: true, + sourceMap: true, + terserOptions: { + sourceMap: config.build.productionSourceMap, + }, + }), + ], + }, }) if (config.build.productionGzip) { diff --git a/frontend/package.json b/frontend/package.json index c32c8b6..950f600 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "preferGlobal": true, "name": "figure-speaker-frontend", - "version": "1.0.5", + "version": "1.1.0", "description": "Speaker which reacts to NFC tags and streams music", "author": "Nils_Hirsekorn@online.de", "repository": "git@github.com:Kkoile/figure-speaker.git", @@ -13,63 +13,64 @@ "build": "node build/build.js" }, "dependencies": { - "axios": "^0.18.0", - "vue": "^2.5.2", - "vue-i18n": "^8.0.0", - "vue-material": "^1.0.0-beta-10.2", - "vue-router": "^3.0.1", - "vuex": "^3.0.1" + "axios": "0", + "vue": "2", + "vue-i18n": "8", + "vue-material": "1.0.0-beta-11", + "vue-router": "3", + "vuex": "3" }, "devDependencies": { - "autoprefixer": "^7.1.2", - "babel-core": "^6.22.1", - "babel-eslint": "^8.2.1", - "babel-helper-vue-jsx-merge-props": "^2.0.3", - "babel-loader": "^7.1.1", - "babel-plugin-syntax-jsx": "^6.18.0", - "babel-plugin-transform-runtime": "^6.22.0", - "babel-plugin-transform-vue-jsx": "^3.5.0", - "babel-preset-env": "^1.3.2", - "babel-preset-stage-2": "^6.22.0", - "chalk": "^2.0.1", - "copy-webpack-plugin": "^4.0.1", - "css-loader": "^0.28.0", - "eslint": "^4.15.0", - "eslint-config-standard": "^10.2.1", - "eslint-friendly-formatter": "^3.0.0", - "eslint-loader": "^1.7.1", - "eslint-plugin-import": "^2.7.0", - "eslint-plugin-node": "^5.2.0", - "eslint-plugin-promise": "^3.4.0", - "eslint-plugin-standard": "^3.0.1", - "eslint-plugin-vue": "^4.3.0", - "extract-text-webpack-plugin": "^3.0.0", - "file-loader": "^1.1.4", - "friendly-errors-webpack-plugin": "^1.6.1", - "html-webpack-plugin": "^2.30.1", - "node-notifier": "^5.1.2", - "optimize-css-assets-webpack-plugin": "^3.2.0", - "ora": "^1.2.0", - "portfinder": "^1.0.13", - "postcss-import": "^11.0.0", - "postcss-loader": "^2.0.8", - "postcss-url": "^7.2.1", - "rimraf": "^2.6.0", - "semver": "^5.3.0", - "shelljs": "^0.7.6", - "uglifyjs-webpack-plugin": "^1.1.1", - "url-loader": "^0.5.8", - "vue-loader": "^13.3.0", - "vue-style-loader": "^3.0.1", - "vue-template-compiler": "^2.5.2", - "webpack": "^3.6.0", - "webpack-bundle-analyzer": "^3.6.0", - "webpack-dev-server": "^2.9.1", - "webpack-merge": "^4.1.0" + "@babel/core": "^7", + "@babel/plugin-transform-runtime": "^7.8.3", + "@babel/preset-env": "^7", + "@babel/preset-stage-2": "7", + "@babel/runtime": "^7.8.3", + "@vue/babel-plugin-transform-vue-jsx": "^1.1.2", + "autoprefixer": "9", + "babel-eslint": "10", + "babel-helper-vue-jsx-merge-props": "2", + "babel-loader": "^8.0.6", + "babel-plugin-syntax-jsx": "6", + "chalk": "3", + "copy-webpack-plugin": "5", + "css-loader": "3", + "eslint": "6", + "eslint-config-standard": "14", + "eslint-friendly-formatter": "4", + "eslint-loader": "3", + "eslint-plugin-import": "2", + "eslint-plugin-node": "11", + "eslint-plugin-promise": "4", + "eslint-plugin-standard": "4", + "eslint-plugin-vue": "6", + "file-loader": "5", + "friendly-errors-webpack-plugin": "1", + "html-webpack-plugin": "3", + "mini-css-extract-plugin": "^0.9.0", + "node-notifier": "6", + "optimize-css-assets-webpack-plugin": "5", + "ora": "4", + "portfinder": "1", + "postcss-import": "12", + "postcss-loader": "3", + "postcss-url": "8", + "rimraf": "3", + "semver": "7", + "shelljs": "0", + "terser-webpack-plugin": "^2.3.2", + "url-loader": "3", + "vue-loader": "15", + "vue-style-loader": "4", + "vue-template-compiler": "2", + "webpack": "4", + "webpack-bundle-analyzer": "3", + "webpack-dev-server": "3", + "webpack-merge": "4" }, "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" + "node": ">= 12.0.0", + "npm": ">= 6.0.0" }, "browserslist": [ "> 1%", diff --git a/frontend/src/components/Main.vue b/frontend/src/components/Main.vue index eaea923..fcfd34b 100644 --- a/frontend/src/components/Main.vue +++ b/frontend/src/components/Main.vue @@ -1,5 +1,6 @@