thelounge/webpack.config.ts

204 lines
4.8 KiB
TypeScript
Raw Normal View History

import * as webpack from "webpack";
import * as path from "path";
import CopyPlugin from "copy-webpack-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import {VueLoaderPlugin} from "vue-loader";
import babelConfig from "./babel.config.cjs";
import Helper from "./server/helper";
2020-01-09 20:40:10 +00:00
const isProduction = process.env.NODE_ENV === "production";
const config: webpack.Configuration = {
2020-01-09 20:40:10 +00:00
mode: isProduction ? "production" : "development",
2016-12-18 15:53:28 +00:00
entry: {
"js/bundle.js": [path.resolve(__dirname, "client/js/vue.ts")],
2016-12-18 15:53:28 +00:00
},
devtool: "source-map",
output: {
clean: true, // Clean the output directory before emit.
2017-10-03 10:52:31 +00:00
path: path.resolve(__dirname, "public"),
filename: "[name]",
publicPath: "/",
2016-12-18 15:53:28 +00:00
},
2019-12-30 17:14:15 +00:00
performance: {
hints: false,
},
resolve: {
extensions: [".ts", ".js", ".vue"],
},
2016-12-18 15:53:28 +00:00
module: {
2017-02-17 15:01:20 +00:00
rules: [
{
test: /\.vue$/,
use: {
loader: "vue-loader",
options: {
compilerOptions: {
preserveWhitespace: false,
},
appendTsSuffixTo: [/\.vue$/],
},
},
},
{
test: /\.ts$/i,
include: [path.resolve(__dirname, "client")],
exclude: path.resolve(__dirname, "node_modules"),
use: {
loader: "babel-loader",
options: babelConfig,
},
},
2018-03-21 12:13:52 +00:00
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
2020-10-11 08:06:52 +00:00
esModule: false,
},
},
2018-03-21 12:13:52 +00:00
{
loader: "css-loader",
options: {
url: false,
2019-10-14 09:15:19 +00:00
importLoaders: 1,
sourceMap: true,
},
},
{
loader: "postcss-loader",
options: {
sourceMap: true,
2018-03-21 12:13:52 +00:00
},
},
],
},
],
2016-12-18 15:53:28 +00:00
},
2018-01-25 18:32:28 +00:00
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: "js/bundle.vendor.js",
chunks: "all",
},
},
},
},
2017-03-19 08:02:39 +00:00
externals: {
json3: "JSON", // socket.io uses json3.js, but we do not target any browsers that need it
},
2016-12-18 15:53:28 +00:00
plugins: [
new VueLoaderPlugin(),
new webpack.DefinePlugin({
__VUE_PROD_DEVTOOLS__: false,
__VUE_OPTIONS_API__: false,
}),
new MiniCssExtractPlugin({
filename: "css/style.css",
}),
2020-05-16 18:32:33 +00:00
new CopyPlugin({
patterns: [
{
from: path
.resolve(
__dirname,
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff*"
)
.replace(/\\/g, "/"),
2022-02-09 23:27:34 +00:00
to: "fonts/[name][ext]",
},
2020-05-16 18:32:33 +00:00
{
from: path.resolve(__dirname, "./client/js/loading-error-handlers.js"),
2022-02-09 23:27:34 +00:00
to: "js/[name][ext]",
2020-05-16 18:32:33 +00:00
},
{
from: path.resolve(__dirname, "./client/*").replace(/\\/g, "/"),
2022-02-09 23:27:34 +00:00
to: "[name][ext]",
2020-05-16 18:32:33 +00:00
globOptions: {
ignore: [
"**/index.html.tpl",
"**/service-worker.js",
"**/*.d.ts",
"**/tsconfig.json",
],
2020-05-16 18:32:33 +00:00
},
},
{
from: path.resolve(__dirname, "./client/service-worker.js"),
2022-02-09 23:27:34 +00:00
to: "[name][ext]",
2020-05-16 18:32:33 +00:00
transform(content) {
return content
.toString()
.replace(
"__HASH__",
isProduction ? Helper.getVersionCacheBust() : "dev"
);
},
},
{
from: path.resolve(__dirname, "./client/audio/*").replace(/\\/g, "/"),
2022-02-09 23:27:34 +00:00
to: "audio/[name][ext]",
2020-05-16 18:32:33 +00:00
},
{
from: path.resolve(__dirname, "./client/img/*").replace(/\\/g, "/"),
2022-02-09 23:27:34 +00:00
to: "img/[name][ext]",
2020-05-16 18:32:33 +00:00
},
{
from: path.resolve(__dirname, "./client/themes/*").replace(/\\/g, "/"),
2022-02-09 23:27:34 +00:00
to: "themes/[name][ext]",
2020-05-16 18:32:33 +00:00
},
],
}),
// socket.io uses debug, we don't need it
2019-07-17 09:33:59 +00:00
new webpack.NormalModuleReplacementPlugin(
/debug/,
path.resolve(__dirname, "scripts/noop.js")
),
],
2016-12-18 15:53:28 +00:00
};
export default (env: any, argv: any) => {
if (argv.mode === "development") {
config.target = "node";
config.devtool = "eval";
config.stats = "errors-only";
config.output!.path = path.resolve(__dirname, "test/public");
config.entry!["testclient.js"] = [path.resolve(__dirname, "test/client/index.ts")];
// Add the istanbul plugin to babel-loader options
for (const rule of config.module!.rules!) {
// @ts-expect-error Property 'use' does not exist on type 'RuleSetRule | "..."'.
if (rule.use.loader === "babel-loader") {
// @ts-expect-error Property 'use' does not exist on type 'RuleSetRule | "..."'.
rule.use.options.plugins = ["istanbul"];
}
}
// `optimization.splitChunks` is incompatible with a `target` of `node`. See:
// - https://github.com/zinserjan/mocha-webpack/issues/84
// - https://github.com/webpack/webpack/issues/6727#issuecomment-372589122
config.optimization!.splitChunks = false;
// Disable plugins like copy files, it is not required
config.plugins = [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: "css/style.css",
}),
// Client tests that require Vue may end up requireing socket.io
new webpack.NormalModuleReplacementPlugin(
/js(\/|\\)socket\.js/,
path.resolve(__dirname, "scripts/noop.js")
),
];
}
if (argv?.mode === "production") {
// ...
}
return config;
};