Files
tf2wikipricing/webpack.config.js
xenticore 95ce637892 feat: enable webextension builds
Currently only supports Chrome due to no `chrome` -> `browser` polyfill
2025-05-01 15:27:14 -04:00

159 lines
4.5 KiB
JavaScript
Executable File

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
}),
],
}
];