var path = require('path'); var CopyPlugin = require('copy-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); var webpack = require('webpack'); var fs = require('fs'); var package = require('./package.json'); function allReplace(str, obj, quote = true) { for (const x in obj) { str = str.replace(new RegExp(x, 'g'), quote ? `"${obj[x]}"` : obj[x]); } return str; }; const defines = { EXTENSION_NAME: package.name, __EXTENSION_NAME: JSON.stringify(package.name), EXTENSION_AUTHOR: package.author, EXTENSION_DESCRIPTION: package.description, EXTENSION_VERSION: package.version, __VERSION__: JSON.stringify(package.version), } module.exports = [ // WebExtension { devtool: "source-map", entry: { content: './src/content/content.ts', background: './src/background/background.ts', style: './src/content/style.css' }, module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules|GM_fetch/, }, { test: /\.css$/i, use: [ { loader: MiniCssExtractPlugin.loader, options: { publicPath: '/', // Adjust if needed for relative path resolution }, }, { loader: 'css-loader', options: { url: true, // Ensures url() in CSS is processed }, }, { loader: 'postcss-loader', options: { postcssOptions: { plugins: { 'postcss-url': { url: (asset) => { // Transform relative URLs to extension-style URLs const relativePath = asset.url.replace(/^\.\.\//, '') // Remove leading ../resources part return `chrome-extension://__MSG_@@extension_id__/${relativePath}`; }, }, }, }, }, }, ], }, { test: /\.(jpe?g|png|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, type: 'asset/resource', generator: { filename: 'resources/[name][ext]', }, }, ], }, externals: { './src/content/GM_fetch': 'commonjs2 null' }, optimization: { minimize: true }, output: { path: path.resolve(__dirname, "dist/extension"), filename: "[name]/[name].js" }, resolve: { extensions: [".ts", ".tsx", ".js", ".json"] }, plugins: [ new webpack.DefinePlugin({ ...defines, __ENV_WEBEXTENSION: true, __ENV_USERSCRIPT: false}), new CopyPlugin({ patterns: [ { from: './src/manifest.json', to: 'manifest.json', transform(content, absoluteFrom) { return allReplace(content.toString(), defines) }, } ]}), new CopyPlugin({ patterns: [ { from: './src/icons', to: 'icons/[file]'}, { from: './src/resources/*.png', to: 'resources/[name][ext]' }, ]}), new MiniCssExtractPlugin({ filename: 'lib/style.css' }), ], }, // Userscript { entry: { content: ['./src/content/content.ts', './src/content/GM_fetch/index.js' ] }, module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, { test: /\.css$/i, use: ['style-loader', 'css-loader'] }, { test: /\.(jpe?g|png|ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, type: 'asset/inline' }, ], }, optimization: { minimize: true, }, devtool: false, output: { path: path.resolve(__dirname, 'dist/userscript'), filename: `tf2wikipricing.user.js` }, resolve: { extensions: [".ts", ".tsx", ".js", ".json", ".css"] }, plugins: [ new webpack.DefinePlugin({ ...defines, __ENV_USERSCRIPT: true, __ENV_WEBEXTENSION: false }), new webpack.BannerPlugin({ raw: true, banner: () => { const header = fs.readFileSync(path.resolve(__dirname, 'src/userscript_header.js'), 'utf8') return allReplace(header, defines, false) }, stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT }), ], } ];