'use strict'; const path = require('path'); const config = require('../config'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const { VueLoaderPlugin } = require('vue-loader'); const ESLintPlugin = require('eslint-webpack-plugin'); const { isDev, assetsPath } = require('./utils'); function resolve(dir) { return path.join(__dirname, '..', dir); } const eslintOptions = { formatter: require('eslint-formatter-friendly'), emitWarning: !config.dev.showEslintErrorsInOverlay, extensions: ['js', 'ts', 'vue'], }; //todo: mini-css-extract-plugin? upgrade to webpack 4, then use this //https://github.com/webpack-contrib/mini-css-extract-plugin //todo: do we need postcss? module.exports = { context: path.resolve(__dirname, '../'), entry: { app: './src/main.js', }, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: isDev ? config.dev.assetsPublicPath : config.build.assetsPublicPath, }, optimization: { splitChunks: { chunks: 'all', }, }, resolve: { extensions: ['.js', '.ts', '.vue', '.json', '.gql', '.graphql', '.scss'], alias: { '@': resolve('src'), styles: resolve('src/styles'), gql: resolve('src/graphql/gql'), vue: '@vue/compat', }, }, module: { rules: [ // ...(config.dev.useEslint ? [createLintingRule()] : []), { test: /\.vue$/, loader: 'vue-loader', options: { transformAssetUrls: { video: ['src', 'poster'], source: 'src', img: 'src', image: 'xlink:href', }, compilerOptions: { compatConfig: { MODE: 3, }, }, }, }, { test: /\.tsx?$/, loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/], }, exclude: /node_modules/, }, { test: /\.js$/, loader: 'babel-loader', options: { presets: ['@babel/preset-env'], }, include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')], }, { test: /\.(gql|graphql)$/, loader: 'graphql-tag/loader', exclude: /node_modules/, }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: assetsPath('img/[name].[hash:7].[ext]'), }, }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: assetsPath('media/[name].[hash:7].[ext]'), }, }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: assetsPath('fonts/[name].[hash:7].[ext]'), }, }, { test: /\.s?css$/, use: [ isDev ? 'vue-style-loader' : MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', { loader: 'sass-loader', options: { additionalData: process.env.THEME ? `@import "styles/themes/_${process.env.THEME}.scss";` : '', sourceMap: isDev, }, }, ], }, // styleRule(false), // css rule // styleRule(true), // sass rule ], }, plugins: [new VueLoaderPlugin(), new ESLintPlugin(eslintOptions)], // node: { // // prevent webpack from injecting useless setImmediate polyfill because Vue // // source contains it (although only uses it if it's native). // setImmediate: false, // // prevent webpack from injecting mocks to Node native modules // // that does not make sense for the client // dgram: 'empty', // fs: 'empty', // net: 'empty', // tls: 'empty', // child_process: 'empty', // }, };