splatoon2.ink/webpack.config.js
Matt Isenhower 8f2bc6d5cd Reorganize source files in preparation for transition to vue-cli
The biggest changes here include splitting the server-side JS into multiple directories (under /src/app), moving all web content to /src/web, and compiling the web app to /dist instead of /public. This layout makes more sense overall, and more closely mirrors what is used for vue-cli v3 projects.
2018-07-27 11:40:27 -07:00

141 lines
5.0 KiB
JavaScript

require('dotenv').config();
const path = require('path');
const glob = require('glob');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const PurifyCSSPlugin = require('purifycss-webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = function(env) {
const production = (env === 'production');
return {
resolve: { alias: { '@': path.resolve(__dirname, './src') } },
entry: {
main: [
'./src/web/main.js',
'./src/web/assets/css/main.scss',
],
screenshots: [
'./src/web/screenshots.js',
'./src/web/assets/css/screenshots.scss',
],
},
output: {
path: path.resolve(__dirname, './dist'),
filename: 'assets/js/[name].[hash:6].js',
chunkFilename: 'assets/js/[name].[hash:6].js',
},
devtool: (production) ? false : '#cheap-module-eval-source-map',
devServer: {
overlay: true,
historyApiFallback: true,
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
extractCSS: true,
},
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
publicPath: '../../',
use: [
{
loader: 'css-loader',
options: { sourceMap: !production },
},
{
loader: 'postcss-loader',
options: { sourceMap: !production },
},
{
loader: 'sass-loader',
options: { sourceMap: !production },
},
],
}),
},
{
test: /\.(woff2?|ttf|eot)$/,
loader: 'file-loader?name=assets/fonts/[name].[hash:6].[ext]',
},
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'file-loader?name=assets/img/[name].[hash:6].[ext]',
},
{
test: /favicon\.ico$/,
loader: 'file-loader?name=favicon.ico',
}
],
},
plugins: [
// Remove old files
// new CleanWebpackPlugin([
// 'dist/assets/css/*',
// 'dist/assets/js/*',
// ]),
new webpack.DefinePlugin({
'GOOGLE_ANALYTICS_ID': JSON.stringify(process.env.GOOGLE_ANALYTICS_ID),
}),
// Extract CSS to a separate file
new ExtractTextPlugin({
filename: 'assets/css/[name].[contenthash:6].css',
disable: !production,
}),
// Remove unused CSS styles
new PurifyCSSPlugin({
paths: [
...glob.sync(path.join(__dirname, 'public/**/*.html')),
...glob.sync(path.join(__dirname, 'src/web/components/**/*.vue')),
],
minimize: production,
purifyOptions: {
whitelist: [
'.title:not(.is-spaced)+.subtitle', // Fix subtitle spacing
// Dynamic merchandise types
'.merchandise-box.shoes',
'.merchandise-box.head',
'.merchandise-box.clothes',
],
cleanCssOptions: {
rebase: false, // Leave relative paths alone when minifying CSS
},
},
}),
// Build main public HTML
new HtmlWebpackPlugin({
inject: false,
filename: 'index.html',
template: 'public/index.html',
minify: { collapseWhitespace: true },
}),
// Build HTML used for screenshot generation
new HtmlWebpackPlugin({
inject: false,
filename: 'screenshots.html',
template: 'public/screenshots.html',
minify: { collapseWhitespace: true },
}),
// Copy additional favicons
new CopyWebpackPlugin([
{ from: 'public' },
]),
],
}
}