summaryrefslogtreecommitdiff
path: root/index.js
diff options
context:
space:
mode:
authorSam Light <samlight1994@gmail.com>2024-09-01 15:55:23 +0100
committerSam Light <samlight1994@gmail.com>2024-09-01 15:55:23 +0100
commit51630d11784f37c52142122a5a45be7ca6127b3a (patch)
treec0d4acd5005cddcd0130972d6f30024cbda701d0 /index.js
Initial commit
Diffstat (limited to 'index.js')
-rw-r--r--index.js137
1 files changed, 137 insertions, 0 deletions
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..7b08b36
--- /dev/null
+++ b/index.js
@@ -0,0 +1,137 @@
+import * as path from 'path';
+import MiniCssExtractPlugin from 'mini-css-extract-plugin';
+import NotifierPlugin from 'webpack-notifier';
+import ManifestPlugin from 'webpack-assets-manifest';
+import StylelintPlugin from 'stylelint-webpack-plugin';
+import EsLintPlugin from 'eslint-webpack-plugin';
+import WebpackbarPlugin from 'webpackbar';
+import CleanTerminalPlugin from 'clean-terminal-webpack-plugin';
+import {CleanWebpackPlugin} from 'clean-webpack-plugin';
+import SvgChunkWebpackPlugin from 'svg-chunk-webpack-plugin';
+
+
+export class Paths {
+ #jsSourcePath;
+ #scssSourcePath;
+
+ constructor({dir, source, target, js, scss}) {
+ this.sourcePath = path.resolve(dir, source);
+ this.targetPath = path.resolve(dir, target);
+ this.jsSourcePath = js;
+ this.scssSourcePath = scss;
+ }
+
+ jsEntry(path) {
+ return `${this.jsSourcePath}/${path}`;
+ }
+
+ scssEntry(path) {
+ return `${this.scssSourcePath}/${path}`;
+ }
+};
+
+export const makeConfig = (env, argv, options) => {
+ const isProd = argv.mode === 'production',
+ isDev = argv.mode === 'development',
+ isWatch = typeof argv.watch !== 'undefined' && argv.watch === true,
+ {paths, entry, plugins = [], manifestCustomize = (e) => e} = options;
+
+ return {
+ entry,
+ output: {
+ filename: 'js/[name].[contenthash:8].js',
+ path: paths.targetPath,
+ },
+ context: paths.sourcePath,
+ devtool: isDev ? 'source-map' : false,
+ watchOptions: {
+ ignored: ['node_modules/**']
+ },
+ performance: {
+ hints: false
+ },
+ plugins: [
+ new ManifestPlugin({
+ customize(entry) {
+
+ if (
+ entry.key.startsWith('svg/') ||
+ entry.key.endsWith('.map')
+ ) return false;
+
+ const srcdir = path.dirname(entry.key),
+ destdir = path.dirname(entry.value);
+
+ if (srcdir !== destdir) {
+ entry.key = destdir + '/' + path.basename(entry.key);
+ }
+
+ return manifestCustomize(entry);
+ }
+ }),
+ new CleanWebpackPlugin({
+ cleanStaleWebpackAssets: !isWatch
+ }),
+ new MiniCssExtractPlugin({
+ filename: 'css/[name].[contenthash:8].css',
+ chunkFilename: '[id].[contenthash:8].css'
+ }),
+ new StylelintPlugin({
+ failOnError: !isWatch,
+ }),
+ new EsLintPlugin({
+ overrideConfig: {
+ rules: {
+ "no-console": isProd ? 2 : 1,
+ "no-debugger": isProd ? 2 : 1,
+ "no-empty": isProd ? 2 : 1,
+ "no-unused-vars": isProd ? 2 : 1,
+ "no-constant-condition": isProd ? 2 : 1,
+ }
+ }
+ }),
+ new NotifierPlugin(),
+ new WebpackbarPlugin(),
+ new CleanTerminalPlugin(),
+ new SvgChunkWebpackPlugin({
+ filename: '[name].[contenthash].svg',
+ svgstoreConfig: {inline: false},
+ }),
+
+ ...plugins,
+ ],
+
+ externals: {
+ },
+
+ module: {
+ rules: [
+ {
+ test: /\.js$/i,
+ include: paths.sourcePath,
+ use: [
+ 'babel-loader'
+ ]
+ },
+ {
+ test: /\.s[ac]ss$/i,
+ include: paths.sourcePath,
+ use: [
+ MiniCssExtractPlugin.loader,
+ 'css-loader',
+ 'postcss-loader',
+ 'sass-loader',
+ ],
+ },
+ {
+ test: /.svg$/i,
+ include: paths.sourcePath,
+ use: [
+ {loader: SvgChunkWebpackPlugin.loader}
+ ]
+ }
+ ],
+ },
+
+ };
+};