2018-08-21 05:02:21 +08:00
|
|
|
import path from 'path'
|
|
|
|
import webpack from 'webpack'
|
2019-02-06 18:41:05 +08:00
|
|
|
import DartSass from 'dart-sass'
|
2018-08-21 05:02:21 +08:00
|
|
|
import { VueLoaderPlugin } from 'vue-loader'
|
|
|
|
import SvgStore from 'webpack-svgstore-plugin'
|
|
|
|
import CopyWebpackPlugin from 'copy-webpack-plugin'
|
|
|
|
import HtmlWebpackPlugin from 'html-webpack-plugin'
|
|
|
|
import ManifestPlugin from 'webpack-manifest-plugin'
|
|
|
|
import ImageminWebpackPlugin from 'imagemin-webpack-plugin'
|
|
|
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin'
|
|
|
|
import OptimizeCssAssetsPlugin from 'optimize-css-assets-webpack-plugin'
|
|
|
|
import { ifDev, ifProd, removeEmpty } from './utilities'
|
2018-08-22 16:01:51 +08:00
|
|
|
import { rootPath, srcPath, buildPath } from './paths'
|
2018-08-21 05:02:21 +08:00
|
|
|
|
|
|
|
export default {
|
|
|
|
|
2018-11-09 05:03:10 +08:00
|
|
|
mode: ifDev('development', 'production'),
|
|
|
|
|
|
|
|
entry: {
|
|
|
|
app: removeEmpty([
|
|
|
|
ifDev('webpack-hot-middleware/client?reload=true'),
|
|
|
|
`${srcPath}/assets/sass/main.scss`,
|
|
|
|
`${srcPath}/main.js`,
|
|
|
|
]),
|
|
|
|
},
|
|
|
|
|
|
|
|
output: {
|
|
|
|
path: `${buildPath}/`,
|
|
|
|
filename: `assets/js/[name]${ifProd('.[hash]', '')}.js`,
|
|
|
|
chunkFilename: `assets/js/[name]${ifProd('.[chunkhash]', '')}.js`,
|
|
|
|
publicPath: '/',
|
|
|
|
},
|
|
|
|
|
|
|
|
resolve: {
|
|
|
|
extensions: ['.js', '.scss', '.vue'],
|
|
|
|
alias: {
|
|
|
|
vue$: 'vue/dist/vue.esm.js',
|
|
|
|
modules: path.resolve(rootPath, '../node_modules'),
|
|
|
|
images: `${srcPath}/assets/images`,
|
|
|
|
fonts: `${srcPath}/assets/fonts`,
|
|
|
|
variables: `${srcPath}/assets/sass/variables`,
|
|
|
|
tiptap: path.resolve(rootPath, '../packages/tiptap/src'),
|
|
|
|
'tiptap-commands': path.resolve(rootPath, '../packages/tiptap-commands/src'),
|
|
|
|
'tiptap-utils': path.resolve(rootPath, '../packages/tiptap-utils/src'),
|
|
|
|
'tiptap-models': path.resolve(rootPath, '../packages/tiptap-models/src'),
|
|
|
|
'tiptap-extensions': path.resolve(rootPath, '../packages/tiptap-extensions/src'),
|
|
|
|
},
|
|
|
|
modules: [
|
|
|
|
srcPath,
|
|
|
|
path.resolve(rootPath, '../node_modules'),
|
|
|
|
],
|
|
|
|
},
|
|
|
|
|
|
|
|
devtool: ifDev('eval-source-map', 'source-map'),
|
|
|
|
|
|
|
|
module: {
|
|
|
|
rules: [
|
|
|
|
{
|
|
|
|
test: /\.vue$/,
|
|
|
|
loader: 'vue-loader',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test: /\.js$/,
|
|
|
|
exclude: [/node_modules/],
|
|
|
|
use: {
|
|
|
|
loader: ifDev('babel-loader?cacheDirectory=true', 'babel-loader'),
|
|
|
|
options: {
|
|
|
|
presets: [
|
|
|
|
'@babel/preset-env',
|
|
|
|
],
|
|
|
|
plugins: [
|
|
|
|
'@babel/plugin-syntax-dynamic-import',
|
|
|
|
],
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test: /\.css$/,
|
|
|
|
use: removeEmpty([
|
|
|
|
ifDev('vue-style-loader', MiniCssExtractPlugin.loader),
|
|
|
|
'css-loader',
|
|
|
|
'postcss-loader',
|
|
|
|
]),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test: /\.scss$/,
|
|
|
|
use: removeEmpty([
|
|
|
|
ifDev('vue-style-loader', MiniCssExtractPlugin.loader),
|
|
|
|
'css-loader',
|
|
|
|
'postcss-loader',
|
2019-02-06 18:41:05 +08:00
|
|
|
{
|
|
|
|
loader: 'sass-loader',
|
|
|
|
options: {
|
|
|
|
implementation: DartSass,
|
|
|
|
},
|
|
|
|
},
|
2018-11-09 05:03:10 +08:00
|
|
|
]),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test: /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/,
|
|
|
|
use: {
|
|
|
|
loader: 'file-loader',
|
|
|
|
options: {
|
|
|
|
name: `assets/images/[name]${ifProd('.[hash]', '')}.[ext]`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
|
|
|
use: {
|
|
|
|
loader: 'file-loader',
|
|
|
|
options: {
|
|
|
|
name: `assets/fonts/[name]${ifProd('.[hash]', '')}.[ext]`,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
|
|
|
|
// splitting out the vendor
|
|
|
|
optimization: {
|
|
|
|
namedModules: true,
|
|
|
|
splitChunks: {
|
|
|
|
name: 'vendor',
|
|
|
|
minChunks: 2,
|
|
|
|
},
|
|
|
|
noEmitOnErrors: true,
|
|
|
|
// concatenateModules: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
plugins: removeEmpty([
|
|
|
|
|
|
|
|
// create manifest file for server-side asset manipulation
|
|
|
|
new ManifestPlugin({
|
|
|
|
fileName: 'assets/manifest.json',
|
|
|
|
writeToFileEmit: true,
|
|
|
|
}),
|
|
|
|
|
|
|
|
// define env
|
|
|
|
// new webpack.DefinePlugin({
|
|
|
|
// 'process.env': {},
|
|
|
|
// }),
|
|
|
|
|
|
|
|
// copy static files
|
|
|
|
new CopyWebpackPlugin([
|
|
|
|
{
|
|
|
|
context: `${srcPath}/assets/static`,
|
|
|
|
from: { glob: '**/*', dot: false },
|
|
|
|
to: `${buildPath}/assets`,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
context: `${srcPath}/assets/static`,
|
|
|
|
from: { glob: '**/*', dot: false },
|
|
|
|
to: `${buildPath}/assets/[path][name].[hash].[ext]`,
|
|
|
|
},
|
|
|
|
]),
|
|
|
|
|
|
|
|
// enable hot reloading
|
|
|
|
ifDev(new webpack.HotModuleReplacementPlugin()),
|
|
|
|
|
|
|
|
// html
|
|
|
|
new HtmlWebpackPlugin({
|
|
|
|
filename: 'index.html',
|
|
|
|
template: `${srcPath}/index.html`,
|
|
|
|
inject: true,
|
|
|
|
minify: ifProd({
|
|
|
|
removeComments: true,
|
|
|
|
collapseWhitespace: true,
|
|
|
|
removeAttributeQuotes: true,
|
|
|
|
}),
|
|
|
|
buildVersion: new Date().valueOf(),
|
|
|
|
chunksSortMode: 'none',
|
|
|
|
}),
|
|
|
|
|
|
|
|
new VueLoaderPlugin(),
|
|
|
|
|
|
|
|
// create css files
|
|
|
|
ifProd(new MiniCssExtractPlugin({
|
|
|
|
filename: `assets/css/[name]${ifProd('.[hash]', '')}.css`,
|
|
|
|
chunkFilename: `assets/css/[name]${ifProd('.[hash]', '')}.css`,
|
|
|
|
})),
|
|
|
|
|
|
|
|
// minify css files
|
|
|
|
ifProd(new OptimizeCssAssetsPlugin({
|
|
|
|
cssProcessorOptions: {
|
|
|
|
reduceIdents: false,
|
|
|
|
autoprefixer: false,
|
|
|
|
zindex: false,
|
|
|
|
discardComments: {
|
|
|
|
removeAll: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})),
|
|
|
|
|
|
|
|
// svg icons
|
|
|
|
new SvgStore({
|
|
|
|
prefix: 'icon--',
|
|
|
|
svgoOptions: {
|
|
|
|
plugins: [
|
|
|
|
{ cleanupIDs: false },
|
|
|
|
{ collapseGroups: false },
|
|
|
|
{ removeTitle: true },
|
|
|
|
],
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
|
|
|
|
// image optimization
|
|
|
|
new ImageminWebpackPlugin({
|
|
|
|
optipng: ifDev(null, {
|
|
|
|
optimizationLevel: 3,
|
|
|
|
}),
|
|
|
|
jpegtran: ifDev(null, {
|
|
|
|
progressive: true,
|
|
|
|
quality: 80,
|
|
|
|
}),
|
|
|
|
svgo: ifDev(null, {
|
|
|
|
plugins: [
|
|
|
|
{ cleanupIDs: false },
|
|
|
|
{ removeViewBox: false },
|
|
|
|
{ removeUselessStrokeAndFill: false },
|
|
|
|
{ removeEmptyAttrs: false },
|
|
|
|
],
|
|
|
|
}),
|
|
|
|
}),
|
|
|
|
|
|
|
|
]),
|
|
|
|
|
|
|
|
node: {
|
|
|
|
fs: 'empty',
|
|
|
|
},
|
2018-08-21 05:02:21 +08:00
|
|
|
|
|
|
|
}
|