cygnal/build/webpack.base.conf.js

262 lines
9.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict'
const path = require('path')
const svg2png = require('svg2png')
const webpack = require('webpack')
const AppManifestWebpackPlugin = require('app-manifest-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const ServiceWorkerWebpackPlugin = require("serviceworker-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const utils = require('./utils')
const config = require('../config')
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js',
},
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].js'),
chunkFilename: utils.assetsPath('js/[name].js'),
publicPath: config.build.assetsPublicPath,
},
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true
}),
new OptimizeCSSAssetsPlugin({})
],
splitChunks: {
// Required for webpack to respect the vendor chunk. See
// https://medium.com/dailyjs/webpack-4-splitchunks-plugin-d9fbbe091fd0
// for more details.
chunks: 'initial',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]|[\\/]css\/vendor[\\/]/,
},
},
},
},
resolve: {
alias: {
'@': utils.resolve('src'),
},
extensions: ['.js', '.vue', '.json'],
// Load mock_gpx.json from tests first, tests/default then
modules: ['tests/', 'tests/default', 'node_modules'],
},
stats: {
children: false,
},
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [utils.resolve('src')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: true,
},
},
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: file => (
/node_modules/.test(file) &&
!/\.vue\.js/.test(file)
),
},
{
test: /\.css$/,
use: [
process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
// PostCSS is run before, see
// https://github.com/webpack-contrib/css-loader#importloaders
options: { importLoaders: 1 },
},
{
loader: 'postcss-loader',
options: {
plugins: () => [require("postcss-preset-env")()],
},
},
],
},
{
test: /\.styl(us)?/,
use: [
process.env.NODE_ENV !== 'production'
? 'vue-style-loader'
: MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: { importLoaders: 1 },
},
{
loader: 'postcss-loader',
options: {
plugins: () => [require("autoprefixer")()],
},
},
'stylus-loader',
],
},
{
test: /\.(jpe?g|png|gif)$/,
use: [
{
loader: 'url-loader',
options: {
name: utils.assetsPath('images/[name].[hash:4].[ext]'),
// Images larger than 10 KB wont be inlined
limit: 10 * 1024,
}
},
{
loader: 'image-webpack-loader',
options: {
disable: process.env.NODE_ENV !== 'production',
},
},
],
},
{
test: /\.svg$/,
use: [
{
loader: "svg-url-loader",
options: {
name: utils.assetsPath('images/[name].[hash:4].[ext]'),
// Images larger than 10 KB wont be inlined
limit: 10 * 1024,
noquotes: true,
},
},
{
loader: 'image-webpack-loader',
options: {
disable: process.env.NODE_ENV !== 'production',
},
},
],
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: utils.assetsPath('media/[name].[hash:4].[ext]'),
},
},
{
test: /\.(woff2?|eot|ttf|otf)$/,
loader: 'url-loader',
options: {
limit: 10 * 1024,
name: utils.assetsPath('fonts/[name].[hash:4].[ext]'),
},
},
],
},
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',
},
plugins: [
new ServiceWorkerWebpackPlugin({
entry: path.join(__dirname, '../src/sw.js'),
}),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[contenthash:4].css'),
chunkFilename: utils.assetsPath('css/[name].[contenthash:4].css'),
}),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
ogURL: config.build.ogURL,
ogImage: config.build.ogImage,
inject: true,
minify: (
process.env.NODE_ENV === 'production'
? {
collapseBooleanAttributes: true,
collapseWhitespace: true,
html5: true,
removeAttributeQuotes: true,
removeComments: true,
}
: {}
),
}),
new AppManifestWebpackPlugin({
logo: path.resolve(__dirname, '../src/assets/logo.svg'),
prefix: '/',
output: '/static/icons-[hash:8]/',
inject: true,
persistentCache: true,
config: {
appName: 'Cyclassist',
appDescription: "Track and share issues (work, interruption in routes, parked cars) on bike lanes in realtime.",
developerName: 'Phyks (Lucas Verney)',
developerURL: 'https://phyks.me',
}
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../src/assets/logo.svg'),
to: path.join(config.build.assetsSubDirectory, 'ogIcon.png'),
transform (content, path) {
return Promise.resolve(svg2png(content, { width: 400, height: 400 }));
}
},
{
from: path.resolve(__dirname, '../humans.txt'),
to: config.build.assetsRoot,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../robots.txt'),
to: config.build.assetsRoot,
ignore: ['.*']
}
]),
// Only keep the useful locales from Moment.
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
}