const path = require("path"); const webpack = require("webpack"); const userscriptMeta = require("./Extensions/UserScript/userscript.meta"); const { USERSCRIPT_ARTIFACT_RELATIVE_PATH, USERSCRIPT_BUILD_RECEIPT_RELATIVE_PATH, USERSCRIPT_LIVE_ARTIFACT_RELATIVE_PATH, USERSCRIPT_LIVE_BUILD_RECEIPT_RELATIVE_PATH, UserscriptBuildReceiptPlugin, } = require("./userscript-build-receipt"); const { LiveBuildMarkerPlugin, createLiveBuildId } = require("./webpack.live-build-marker"); const USERSCRIPT_ASSET_NAME = "Return Youtube Dislike.user.js"; class StripWebpackBootstrapWhitespacePlugin { apply(compiler) { compiler.hooks.thisCompilation.tap("StripWebpackBootstrapWhitespacePlugin", (compilation) => { compilation.hooks.processAssets.tap( { name: "StripWebpackBootstrapWhitespacePlugin", stage: webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE, }, () => { const asset = compilation.getAsset(USERSCRIPT_ASSET_NAME); if (!asset) return; const source = asset.source.source().toString(); const normalized = source.replace(/^(\/\*{6}\/)[ \t]+(?=\r?$)/gm, "$1"); if (normalized === source) return; compilation.updateAsset(USERSCRIPT_ASSET_NAME, new webpack.sources.RawSource(normalized)); }, ); }); } } function buildUserscriptBanner(liveTestBuild) { const metadata = [ "// ==UserScript==", `// @name ${userscriptMeta.name}${liveTestBuild ? " [Live Test]" : ""}`, `// @namespace ${userscriptMeta.namespace}`, `// @homepage ${userscriptMeta.homepage}`, `// @version ${userscriptMeta.version}`, `// @encoding ${userscriptMeta.encoding}`, `// @description ${userscriptMeta.description}`, `// @icon ${userscriptMeta.icon}`, `// @author ${userscriptMeta.author}`, ...userscriptMeta.match.map((value) => `// @match ${value}`), ...userscriptMeta.exclude.map((value) => `// @exclude ${value}`), ...userscriptMeta.compatible.map((value) => `// @compatible ${value}`), ...(liveTestBuild ? [] : [`// @downloadURL ${userscriptMeta.downloadURL}`, `// @updateURL ${userscriptMeta.updateURL}`]), ...userscriptMeta.grants.map((value) => `// @grant ${value}`), `// @run-at ${userscriptMeta.runAt}`, "// ==/UserScript==", "", "// This file is generated by `npm run build:userscript`.", "// Edit Extensions/UserScript/src instead of the generated file.", ]; return metadata.join("\n"); } module.exports = (env = {}, argv = {}) => { const liveTestBuild = env.liveTest === true || env.liveTest === "true"; const liveBuildId = createLiveBuildId(liveTestBuild); const mode = argv.mode ?? "production"; const artifactRelativePath = liveTestBuild ? USERSCRIPT_LIVE_ARTIFACT_RELATIVE_PATH : USERSCRIPT_ARTIFACT_RELATIVE_PATH; const receiptRelativePath = liveTestBuild ? USERSCRIPT_LIVE_BUILD_RECEIPT_RELATIVE_PATH : USERSCRIPT_BUILD_RECEIPT_RELATIVE_PATH; return { name: "userscript", mode, entry: path.resolve(__dirname, "Extensions/UserScript/src/userscript-entry.js"), output: { path: liveTestBuild ? path.resolve(__dirname, "test-results/live-build/userscript") : path.resolve(__dirname, "Extensions/UserScript"), filename: USERSCRIPT_ASSET_NAME, clean: false, iife: true, }, cache: false, optimization: { minimize: false, }, plugins: [ new webpack.DefinePlugin({ __RYD_LIVE_BUILD_ID__: JSON.stringify(liveBuildId), __RYD_LIVE_TEST_BUILD__: JSON.stringify(liveTestBuild), }), ...(liveTestBuild ? [new LiveBuildMarkerPlugin(liveBuildId, ["live-build.json"])] : []), new StripWebpackBootstrapWhitespacePlugin(), new UserscriptBuildReceiptPlugin({ artifactPath: path.resolve(__dirname, artifactRelativePath), buildId: liveBuildId, liveTestBuild, mode, receiptPath: path.resolve(__dirname, receiptRelativePath), repositoryRoot: __dirname, }), new webpack.BannerPlugin({ banner: buildUserscriptBanner(liveTestBuild), raw: true, entryOnly: true, }), ], devtool: false, performance: { hints: false, }, }; };