207 lines
5.1 KiB
JavaScript
207 lines
5.1 KiB
JavaScript
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
|
|
import { globbySync } from 'globby';
|
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
|
import path from 'path';
|
|
import sass from 'sass';
|
|
import TsConfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
|
|
import VueLoaderPlugin from 'vue-loader/lib/plugin.js';
|
|
import VuetifyLoaderPlugin from 'vuetify-loader/lib/plugin.js';
|
|
import LiveReloadPlugin from 'webpack-livereload-plugin';
|
|
|
|
const isProd = process.env.NODE_ENV === 'production';
|
|
const __dirname = path.resolve();
|
|
|
|
const config = (name) => {
|
|
const entry = globbySync('*/main.ts', {cwd: `src/${name}`})
|
|
.reduce((prev, curr) => {
|
|
prev[path.basename(path.dirname(curr))] = `./${curr}`;
|
|
return prev;
|
|
}, {});
|
|
|
|
let plugins = [];
|
|
if (!isProd) {
|
|
plugins.push(
|
|
new LiveReloadPlugin({
|
|
port: 0,
|
|
appendScriptTag: true,
|
|
})
|
|
);
|
|
}
|
|
plugins = plugins.concat(
|
|
[
|
|
new VueLoaderPlugin(),
|
|
...Object.keys(entry).map(
|
|
(entryName) =>
|
|
new HtmlWebpackPlugin({
|
|
filename: `${entryName}.html`,
|
|
chunks: [entryName],
|
|
title: entryName,
|
|
template: 'template.html',
|
|
}),
|
|
),
|
|
new ForkTsCheckerWebpackPlugin({
|
|
typescript: {
|
|
extensions: {
|
|
vue: true,
|
|
},
|
|
},
|
|
}),
|
|
]
|
|
);
|
|
if (isProd) {
|
|
plugins.push(
|
|
new MiniCssExtractPlugin({
|
|
filename: 'css/[name].css',
|
|
ignoreOrder: name === 'dashboard', // To ignore Vuetify issues, good idea or not?
|
|
})
|
|
);
|
|
}
|
|
if (name === 'dashboard') {
|
|
plugins.push(
|
|
new VuetifyLoaderPlugin(),
|
|
);
|
|
}
|
|
|
|
return {
|
|
context: path.resolve(__dirname, `src/${name}`),
|
|
mode: isProd ? 'production' : 'development',
|
|
target: 'web',
|
|
// devtool: isProd ? undefined : 'cheap-source-map',
|
|
entry,
|
|
output: {
|
|
path: path.resolve(__dirname, name),
|
|
filename: 'js/[name].js',
|
|
},
|
|
resolve: {
|
|
extensions: ['.js', '.ts', '.tsx', '.json'],
|
|
alias: {
|
|
// vue: 'vue/dist/vue.esm.js',
|
|
vue: path.resolve(__dirname, 'node_modules/vue/dist/vue.esm.js'),
|
|
},
|
|
plugins: [
|
|
new TsConfigPathsPlugin({
|
|
configFile: 'tsconfig.browser.json',
|
|
}),
|
|
],
|
|
},
|
|
module: {
|
|
rules: [
|
|
{
|
|
test: /\.vue$/,
|
|
loader: 'vue-loader',
|
|
},
|
|
{
|
|
test: /\.css$/,
|
|
exclude: /\.theme.css$/,
|
|
use: [
|
|
(isProd) ? MiniCssExtractPlugin.loader : 'vue-style-loader',
|
|
{
|
|
loader: 'css-loader',
|
|
options: {
|
|
esModule: false,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.theme\.css$/,
|
|
use: [
|
|
{
|
|
loader: 'style-loader',
|
|
options: {
|
|
injectType: 'lazyStyleTag',
|
|
},
|
|
},
|
|
{
|
|
loader: 'css-loader',
|
|
options: {
|
|
esModule: false,
|
|
},
|
|
},
|
|
]
|
|
},
|
|
{
|
|
test: /\.s(c|a)ss$/,
|
|
use: [
|
|
(isProd) ? MiniCssExtractPlugin.loader : 'vue-style-loader',
|
|
{
|
|
loader: 'css-loader',
|
|
options: {
|
|
esModule: false,
|
|
},
|
|
},
|
|
{
|
|
loader: 'sass-loader',
|
|
options: {
|
|
implementation: sass,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
test: /\.(woff(2)?|ttf|eot)$/,
|
|
type: 'asset/resource',
|
|
generator: {
|
|
filename: 'font/[name][ext]',
|
|
},
|
|
},
|
|
{
|
|
test: /\.svg?$/,
|
|
type: 'asset/resource',
|
|
generator: {
|
|
filename: 'font/[name][ext]',
|
|
},
|
|
include: [
|
|
path.resolve(__dirname, `src/${name}/_misc/fonts`),
|
|
],
|
|
},
|
|
{
|
|
test: /\.(png|svg|gif)?$/,
|
|
type: 'asset/resource',
|
|
generator: {
|
|
filename: 'img/[name]-[contenthash][ext]',
|
|
},
|
|
exclude: [
|
|
path.resolve(__dirname, `src/${name}/_misc/fonts`),
|
|
],
|
|
},
|
|
{
|
|
test: /\.tsx?$/,
|
|
loader: 'ts-loader',
|
|
options: {
|
|
transpileOnly: true, // ForkTsCheckerWebpackPlugin will do type checking
|
|
appendTsSuffixTo: [/\.vue$/],
|
|
},
|
|
},
|
|
{
|
|
test: /\.mp3?$/,
|
|
type: 'asset/resource',
|
|
generator: {
|
|
filename: 'sfx/[name][ext]',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
plugins,
|
|
optimization: (isProd) ? {
|
|
// v5 migration guide says to reconsider this, so maybe change in the future?
|
|
splitChunks: {
|
|
chunks: 'all',
|
|
cacheGroups: {
|
|
common: {
|
|
minChunks: 2,
|
|
},
|
|
defaultVendors: false,
|
|
default: false,
|
|
},
|
|
},
|
|
} : undefined,
|
|
};
|
|
}
|
|
|
|
export default [
|
|
config('dashboard'),
|
|
config('graphics'),
|
|
];
|