const os = require('os') const path = require('path') const glob = require('glob') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const PurgeCSSPlugin = require('purgecss-webpack-plugin') const svgToMiniDataURI = require('mini-svg-data-uri') const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') const CSSMQPackerPlugin = require('css-mqpacker-webpack-plugin') let mode = 'development', target = 'web', isProd = false const babelExclude = /(node_modules|bower_components)/ if (process.env.NODE_ENV === 'production') { mode = 'development' target = 'browserslist' isProd = true } const isDev = process.env.NODE_ENV !== 'production' const plugins = [ new CleanWebpackPlugin(), new MiniCssExtractPlugin(), new PurgeCSSPlugin({ paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`, { nodir: true }), //only: ['bundle', 'vendor'] }), new HtmlWebpackPlugin({ template: './src/index.html', inject: 'body', }), ] const stylesLoaders = loader => { const loaders = [ isDev ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', { loader: 'postcss-loader', options: { postcssOptions: { ident: 'postcss', plugins: [ require('postcss-preset-env'), ], }, }, }, ] if (loader) { loaders.push(loader) } return loaders } module.exports = { mode: mode, target: target, module: { rules: [ { test: /\.css$/i, use: stylesLoaders(), }, { test: /\.s[ac]ss$/i, use: stylesLoaders('sass-loader'), }, { test: /\.m?js$/i, exclude: babelExclude, use: { loader: 'babel-loader', options: { presets: [ '@babel/preset-env', ], plugins: [ '@babel/plugin-proposal-class-properties', ], }, }, }, { test: /\.(jpe?g|webp|png|gif|svg)$/i, type: 'asset/resource', }, { test: /\.(svg)$/i, type: 'asset/inline', generator: { dataUrl: content => { content = content.toString() return svgToMiniDataURI(content) }, }, }, ], }, // entry: { faker: './src/faker', app: './src/index' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[hash].js', }, plugins: plugins, devtool: mode !== 'production' ? (process.env.SOURCE_MAP_ENV ? 'eval-cheap-module-source-map' : false) : false, // devtool: 'source-map', optimization: { minimize: isProd, splitChunks: { chunks: 'all', }, minimizer: [ `...`, new CssMinimizerPlugin({ parallel: os.cpus().length, minimizerOptions: { preset: [ 'default', // for advanced need to run `npm i -D cssnano-preset-advanced` { discardComments: { removeAll: true }, }, ], }, }), new CSSMQPackerPlugin({ test: /\.css$/i, sort: true, }), ], }, devServer: { static: path.resolve(__dirname, 'dist'), compress: true, port: 1976, //disableHostCheck: true, allowedHosts: [ 'dev.amok.space', ], liveReload: true, historyApiFallback: true, }, }