Vue-SSR-Koa2-Scaffold/config/webpack.base.config.js
2018-11-11 23:47:41 +08:00

169 lines
3.9 KiB
JavaScript

const path = require('path')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader')
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
mode: isProd ? 'production' : 'development',
output: {
path: path.resolve(__dirname, '../dist/web'),
publicPath: '/',
filename: '[name].[chunkhash:8].js',
chunkFilename: '[id].js'
},
resolve: {
alias: {
'@': path.join(__dirname, '../src/web'),
'~': path.join(__dirname, '../src/api'),
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['.js', '.vue', '.json', '.css']
},
module: {
rules: [{
test: /\.(js|jsx)$/,
include: [path.resolve(__dirname, '../src/web')],
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: [
'transform-vue-jsx',
'@babel/plugin-syntax-jsx',
'@babel/plugin-syntax-dynamic-import'
]
}
}
},
// {
// test: /\.(js|jsx|vue)$/,
// enforce: 'pre',
// exclude: /node_modules/,
// use: {
// loader: 'eslint-loader'
// }
// },
{
test: /\.json$/,
use: 'json-loader'
},
{
test: /\.pug$/,
use: {
loader: 'pug-plain-loader'
}
},
{
test: /\.css$/,
use: [
isProd ? MiniCssExtractPlugin.loader : 'vue-style-loader',
'css-loader'
]
},
// {
// test: /\.styl(us)?$/,
// use: [
// isProd ? MiniCssExtractPlugin.loader : 'vue-style-loader',
// 'css-loader',
// 'stylus-loader'
// ]
// },
// {
// test: /\.less$/,
// use: [
// isProd ? MiniCssExtractPlugin.loader : 'vue-style-loader',
// 'css-loader',
// 'less-loader'
// ]
// },
{
test: /\.html$/,
use: 'vue-html-loader',
exclude: /node_modules/
},
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader',
options: {
preserveWhitespace: false
}
}
]
},
{
test: /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'assets/images/[name].[hash:8].[ext]'
}
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'assets/images/[name].[hash:8].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'assets/font/[name].[hash:8].[ext]'
}
}
}
]
},
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
minChunks: 2,
maxAsyncRequests: 5,
maxInitialRequests: 3
// cacheGroups: {
// commons: {
// name: 'manifest',
// chunks: 'initial',
// minChunks: 2
// }
// }
}
},
performance: {
maxEntrypointSize: 400000,
hints: isProd ? 'warning' : false
},
plugins: [
new CaseSensitivePathsPlugin(),
new CopyWebpackPlugin([{
from: path.join(__dirname, '../public'),
to: path.join(__dirname, '../dist/web'),
ignore: ['.*', 'index.html']
}]),
new FriendlyErrorsPlugin(),
new VueLoaderPlugin(),
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 15
}),
new MiniCssExtractPlugin({
filename: isProd ? '[name].[hash].css' : '[name].css',
chunkFilename: isProd ? '[id].[hash].css' : '[id].css'
})
]
}