// vue.config.js const path = require('path') const webpack = require('webpack') const RemoveStrictPlugin = require('remove-strict-webpack-plugin') const fs = require('fs') const SentryPlugin = require('@sentry/webpack-plugin') const TerserPlugin = require('terser-webpack-plugin') const merge = require('webpack-merge') const VueConfigPages = require('./vue.config.pages') const ImageminPlugin = require('imagemin-webpack-plugin').default const MiniCssExtractPlugin = require('mini-css-extract-plugin') const CompressionPlugin = require('compression-webpack-plugin') const exportEnv = require('./src/helpers/export-env') const os = require('os') const devMode = process.env.NODE_ENV !== 'production' const publicPath = process.env.VUE_APP_PUBLIC_PATH || false const sourceMap = process.env.VUE_APP_ENABLE_SOURCEMAP ? process.env.VUE_APP_ENABLE_SOURCEMAP === 'true' : false const devTool = process.env.VUE_APP_DEVTOOL ? process.env.VUE_APP_DEVTOOL : 'cheap-source-map' const isEvo = process.env.VUE_APP_APPLICATION_NAME === 'EVO' const pwaConfigs = { manifestPath: isEvo ? 'evo-manifest.json' : 'ibs-manifest.json', manifestOptions: require(`./public/${isEvo ? 'evo' : 'ibs'}-manifest.json`), } function resolve(dir) { return path.join(__dirname, dir) } module.exports = { // Vue cli MultiPage setup publicPath: !devMode && publicPath ? publicPath : '/', pages: VueConfigPages.getPages(), productionSourceMap: true, configureWebpack: config => { config = { devtool: devTool, resolve: { // load vue-loader read .js .vue .json files extensions: ['.js', '.vue', '.json'], // add alias alias: { vue$: 'vue/dist/vue.esm.js', '@': resolve('src'), '@@': resolve('src/thirdparty/eshop'), '@@@': resolve('src/thirdparty/placement-tree-viewer'), '@@@@': resolve('src/thirdparty/payment'), '@AppCenter': resolve('src/thirdparty/elken-app-center'), vue: 'vue/dist/vue.esm.js', }, }, // use jquery plugins: [ new exportEnv({ filename: 'env-vars.js' }), new webpack.ProvidePlugin({ $: 'jquery', jquery: 'jquery', 'window.jQuery': 'jquery', jQuery: 'jquery', }), new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i, disable: devMode, }), new MiniCssExtractPlugin({ filename: devMode ? '[name].css' : '[name].[hash].css', chunkFilename: devMode ? '[name].[id].css' : '[name].[id].[hash].css', }), ], } // Development ----------------------------------------------------------------------------------------------------- if (devMode) { config.devServer = { host: process.env.VUE_APP_HOST || '0.0.0.0', port: process.env.VUE_APP_PORT || '8080', open: true, disableHostCheck: true, hot: true, inline: false, // Todo enabled if history mode // historyApiFallback: { // rewrites: [ // { from: /^\/products\/?.*/, to: path.posix.join('/', '/products/index.html') }, // { from: /^\/checkout\/?.*/, to: path.posix.join('/', '/checkout/index.html') }, // { from: /./, to: path.posix.join('/', 'index.html') }, // ], // }, allowedHosts: [process.env.VUE_APP_HOST], } if (process.env.VUE_APP_HTTPS === 'true') { config.devServer = merge(config.devServer, { https: { key: fs.readFileSync(resolve('certs/localhost.key'), 'utf8'), cert: fs.readFileSync(resolve('certs/localhost.crt'), 'utf8'), }, }) } } // PRODUCTION ------------------------------------------------------------------------------------------------------ if (!devMode) { config.optimization = { // minimize: false, // Enable to debug code in production minimizer: [ new TerserPlugin({ sourceMap: sourceMap, parallel: true, extractComments: true, cache: true, terserOptions: { output: { comments: false, }, safari10: true, compress: { inline: 0, }, mangle: false, }, }), ], } config.plugins.push( // Remove strict on build. Support for safari 8 or old browsers new RemoveStrictPlugin() ) } // enable gzip (experimental) if (process.env.VUE_APP_ENABLE_GZIP === 'true') { config.plugins.push( new CompressionPlugin({ filename: '[path].gz[query]', algorithm: 'gzip', test: /\.(js|css|html|svg)$/, cache: true, minRatio: 0.6, compressionOptions: { level: 11 }, }) ) } // add sentry login if (process.env.VUE_APP_LOG_SENTRY === 'true') { config.plugins.push( new SentryPlugin({ release: require(path.join(__dirname, '/package.json')).version, include: './dist', ignore: ['node_modules', 'webpack.config.js'], }) ) } return config }, chainWebpack: config => { // Webpack chunks optimizations config.optimization.splitChunks({ cacheGroups: VueConfigPages.getPagesSplitChunkCacheGroupsOptimizations(), }) // Change the sass loader from vue-style-loader to fast-sass-loader for build // performance, however fast-sass-loader dose this by merging all the code into // one file and caching the file. Which leverages the ability to produce // sourcemaps config.module.rules.delete('scss') let scssRule = config.module.rule('scss').test(/\.scss$/) ;[ { name: MiniCssExtractPlugin.loader }, { name: 'css-loader' }, { name: 'postcss-loader' }, { name: 'fast-sass-loader' }, ].forEach(load => { scssRule .use(load.name) .loader(load.loader || load.name) .options(load.options || {}) }) // GraphQL Loader to dynamically generate responsive images config.module .rule('responsive-loader') .test(/\.(jpe?g|png)\?$/i) .use('responsive-loader') .loader('responsive-loader') .end() // Remove the default typescript loader to allow .ts and .js to co-exist const rule = config.module.rule('ts') rule.uses.delete('thread-loader') rule .use('ts-loader') .loader('ts-loader') .tap(options => { options.transpileOnly = false options.happyPackMode = false return options }) if (!devMode) { // remove type checking on production config.plugins.delete('fork-ts-checker') } else { // increase memory for type checking on dev config.plugin('fork-ts-checker').tap(args => { let totalmem = Math.floor(os.totalmem() / 1024 / 1024) //get OS mem size args[0].memoryLimit = totalmem > 4200 ? 4096 : 2048 return args }) } }, transpileDependencies: [ 'bootstrap-vue', // not being transpile to ES5 causes failing in Safari 8 'vue-bootstrap-slider', // not being transpile to ES5 causes failing in Safari 8 ], css: { // sourceMap: process.env.NODE_ENV === 'development' && process.env.VUE_APP_CSS_SOURCE_MAP !== 'false', loaderOptions: { // pass options to sass-loader sass: { // @/ is an alias to src/ // so this assumes you have a file named `src/variables.scss` data: ``, sassOptions: { outputStyle: 'compressed', }, }, }, }, pwa: { themeColor: '#071241', msTileColor: '#071241', appleMobileWebAppCapable: 'yes', workboxPluginMode: 'InjectManifest', workboxOptions: { swSrc: 'src/service-worker.js', exclude: [/\.map$/, /manifest\.json$/, '.htaccess', '.gitkeep', 'gitignore'], }, ...pwaConfigs, }, }