Bladeren bron

feat: add .env for build config

Sv443 1 jaar geleden
bovenliggende
commit
32c0da0b2b
10 gewijzigde bestanden met toevoegingen van 83 en 22 verwijderingen
  1. 11 0
      .env.template
  2. 2 1
      .gitignore
  3. 3 0
      .vscode/settings.json
  4. 7 3
      README.md
  5. 1 1
      dist/BetterYTM.user.js
  6. 19 0
      package-lock.json
  7. 3 1
      package.json
  8. 26 11
      src/tools/post-build.ts
  9. 4 2
      src/tools/serve.ts
  10. 7 3
      webpack.config.js

+ 11 - 0
.env.template

@@ -0,0 +1,11 @@
+# "production" enables minification for small file size, on "development" the code stays readable and debuggable - default is development
+NODE_ENV="development" # "production" or "development"
+
+# HTTP port of the dev server where the userscript will be served (when using `npm run watch`) - defaults to 8710 if empty
+DEV_SERVER_PORT=
+
+# Whether to trigger the bell sound in some terminals when the code has finished compiling - default is false
+RING_BELL=false
+
+# optional suffix to add just before the .user.js of the output file (for use with CI or build scripts to build the file as BetterYTM.min.user.js)
+# OUTFILE_SUFFIX=".min"

+ 2 - 1
.gitignore

@@ -1,7 +1,8 @@
-node_modules/
 test.js
+.env
 test.ts
 
+node_modules/
 dist/*.map
 dist/out/
 dist/*.css

+ 3 - 0
.vscode/settings.json

@@ -3,4 +3,7 @@
     "search.exclude": {
         "**/BetterYTM.user.js": true,
     },
+    "files.associations": {
+        "*.env.template": "dotenv"
+    }
 }

+ 7 - 3
README.md

@@ -62,9 +62,13 @@ Note: the `unsafeWindow` grant is required due to limitations in some browsers,
 | `npm run watch` | Watches, rebuilds and serves the userscript on port 8710, so it can be updated live if set up correctly in the userscript manager. Configure request logging and more in `src/tools/serve.ts` |
 <!-- first column uses non-breaking space U+00A0 (' ') -->
 
-When using ViolentMonkey, after running the command `npm run watch`, open [`http://localhost:8710/dist/BetterYTM.user.js`](http://localhost:8710/dist/BetterYTM.user.js) and select the `Track local file` option.  
-This makes it so the userscript automatically updates when the code changes.  
-Note: the tab needs to stay open on Firefox or the script will not update itself.
+<br>
+
+- Copy the file `.env.template` to `.env` and change the `NODE_ENV` variable to enable or disable minification.  
+  If on `development` the code is readable and debuggable but also has a much bigger file size than on `production`
+- When using ViolentMonkey, after running the command `npm run watch`, open [`http://localhost:8710/dist/BetterYTM.user.js`](http://localhost:8710/dist/BetterYTM.user.js) and select the `Track local file` option.  
+  This makes it so the userscript automatically updates when the code changes.  
+  Note: the tab needs to stay open on Firefox or the script will not update itself.
 
 
 <br><br>

+ 1 - 1
dist/BetterYTM.user.js

@@ -486,7 +486,7 @@ const scriptInfo = Object.freeze({
     name: GM.info.script.name,
     version: GM.info.script.version,
     namespace: GM.info.script.namespace,
-    lastCommit: "a89eef8", // assert as generic string instead of union
+    lastCommit: "dfc65aa", // assert as generic string instead of union
 });
 
 

+ 19 - 0
package-lock.json

@@ -20,6 +20,7 @@
         "concurrently": "^8.1.0",
         "css-loader": "^6.8.1",
         "css-minimizer-webpack-plugin": "^5.0.0",
+        "dotenv": "^16.1.4",
         "eslint": "^7.32.0",
         "express": "^4.18.2",
         "html-loader": "^4.2.0",
@@ -2398,6 +2399,18 @@
         "tslib": "^2.0.3"
       }
     },
+    "node_modules/dotenv": {
+      "version": "16.1.4",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz",
+      "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/motdotla/dotenv?sponsor=1"
+      }
+    },
     "node_modules/ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -7795,6 +7808,12 @@
         "tslib": "^2.0.3"
       }
     },
+    "dotenv": {
+      "version": "16.1.4",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz",
+      "integrity": "sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==",
+      "dev": true
+    },
     "ee-first": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",

+ 3 - 1
package.json

@@ -40,6 +40,7 @@
     "concurrently": "^8.1.0",
     "css-loader": "^6.8.1",
     "css-minimizer-webpack-plugin": "^5.0.0",
+    "dotenv": "^16.1.4",
     "eslint": "^7.32.0",
     "express": "^4.18.2",
     "html-loader": "^4.2.0",
@@ -61,7 +62,8 @@
     "watch": [
       "src/**",
       "tools/**",
-      "webpack.config.js"
+      "webpack.config.js",
+      ".env"
     ],
     "ext": "ts,js,json,html,css",
     "ignore": [

+ 26 - 11
src/tools/post-build.ts

@@ -1,11 +1,17 @@
-import { readFile, writeFile, stat } from "fs/promises";
-import { dirname, join } from "path";
+import { readFile, writeFile } from "fs/promises";
+import { dirname, join, relative } from "path";
 import { fileURLToPath } from "url";
 import { exec } from "child_process";
+import dotenv from "dotenv";
 import pkg from "../../package.json" assert { type: "json" };
 
+const { env, exit } = process;
+dotenv.config();
+
+const outFileSuffix = env.OUTFILE_SUFFIX ?? "";
+
 const repo = "Sv443/BetterYTM";
-const userscriptDistFile = "BetterYTM.user.js";
+const userscriptDistFile = `BetterYTM${outFileSuffix}.user.js`;
 const distFolderPath = "./dist/";
 const scriptUrl = `https://raw.githubusercontent.com/${repo}/main/dist/${userscriptDistFile}`;
 /** Which URLs should the userscript be active on - see https://wiki.greasespot.net/Metadata_Block#%40match */
@@ -13,7 +19,7 @@ const matchUrls = [
   "https://music.youtube.com/*", "https://www.youtube.com/*"
 ];
 /** Whether to trigger the bell sound in some terminals when the code has finished compiling */
-const ringBell = true;
+const ringBell = env.RING_BELL && (env.RING_BELL.length > 0 && env.RING_BELL.trim().toLowerCase() !== "false");
 
 const matchDirectives = matchUrls.reduce((a, c) => a + `// @match           ${c}\n`, "");
 
@@ -63,27 +69,36 @@ ${matchDirectives}\
 
     const scriptPath = join(rootPath, distFolderPath, userscriptDistFile);
     const globalStylePath = join(rootPath, distFolderPath, "main.css");
-    const globalStyle = String(await readFile(globalStylePath)).replace(/\n\s*\/\*.+\*\//gm, "");
+    const globalStyle = String(await readFile(globalStylePath))
+      .replace(/\n\s*\/\*.+\*\//gm, ""); // remove comment-only lines
 
-    // read userscript and inject build number
+    // read userscript and inject build number and global CSS
     const userscript = String(await readFile(scriptPath))
       .replace(/\/?\*?{{BUILD_NUMBER}}\*?\/?/gm, lastCommitSha)
       .replace(/"\/?\*?{{GLOBAL_STYLE}}\*?\/?"/gm, `\`${globalStyle}\``);
 
-    await writeFile(scriptPath, `${header}\n${userscript}${userscript.endsWith("\n") ? "" : "\n"}`);
+    // insert userscript header and final newline
+    const finalUserscript = `${header}\n${userscript}${userscript.endsWith("\n") ? "" : "\n"}`;
+
+    await writeFile(scriptPath, finalUserscript);
+
+    const envText = env.NODE_ENV === "production" ? "\x1b[32mproduction" : "\x1b[33mdevelopment";
+    const sizeKiB = (Buffer.byteLength(finalUserscript, "utf8") / 1024).toFixed(2);
 
-    console.info(`Successfully added the userscript header. Last commit SHA is ${lastCommitSha}`);
-    console.info(`Final size is \x1b[32m${((await stat(scriptPath)).size / 1024).toFixed(2)} KiB\x1b[0m\n`);
+    console.info(`Successfully built for ${envText}\x1b[0m - build number (last commit SHA): \x1b[34m${lastCommitSha}\x1b[0m`);
+    console.info(`Outputted file '${relative("./", scriptPath)}' with a size of \x1b[32m${sizeKiB} KiB\x1b[0m\n`);
 
     ringBell && process.stdout.write("\u0007");
 
-    setImmediate(() => process.exit(0));
+    // schedule exit after I/O finishes
+    setImmediate(() => exit(0));
   }
   catch(err) {
     console.error("Error while adding userscript header:");
     console.error(err);
 
-    setImmediate(() => process.exit(1));
+    // schedule exit after I/O finishes
+    setImmediate(() => exit(1));
   }
 })();
 

+ 4 - 2
src/tools/serve.ts

@@ -3,8 +3,10 @@ import { resolve } from "path";
 import { fileURLToPath } from "url";
 import webpackCfg from "../../webpack.config.js";
 
+const envPort = Number(process.env.DEV_SERVER_PORT);
+
 /** HTTP port of the dev server */
-const devServerPort = 8710;
+const devServerPort = isNaN(envPort) || envPort === 0 ? 8710 : envPort;
 /** Whether to log requests to the console */
 const enableLogging = false;
 
@@ -26,7 +28,7 @@ app.use(express.static(
   resolve(fileURLToPath(import.meta.url), "../../", webpackCfg.output.path),
   {
     etag: false,
-    maxAge: 5_000,
+    maxAge: 0,
   }
 ));
 

+ 7 - 3
webpack.config.js

@@ -1,16 +1,20 @@
 import { dirname, join } from "path";
 import { exec } from "child_process";
 import { fileURLToPath } from "url";
+import dotenv from "dotenv";
 
 import MiniCssExtractPlugin from "mini-css-extract-plugin";
 import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
 
-const minify = false;
+dotenv.config();
+
+const mode = ["development", "production"].includes(process.env.NODE_ENV) ? process.env.NODE_ENV : "development";
+const outFileSuffix = process.env.OUTFILE_SUFFIX ?? "";
 
 export default {
   entry: "./src/BetterYTM.user.ts",
   output: {
-    filename: "BetterYTM.user.js",
+    filename: `BetterYTM${outFileSuffix}.user.js`,
     path: join(dirname(fileURLToPath(import.meta.url)), "/dist"),
     clean: true,
     module: true,
@@ -19,7 +23,7 @@ export default {
     // userscripts are automatically wrapped in an IIFE by the browser extension, so this can be enabled
     outputModule: true,
   },
-  mode: minify ? "production" : "development",
+  mode,
   resolve: {
     extensions: [
       ".ts",