mirror of
				https://github.com/monkeytypegame/monkeytype.git
				synced 2025-10-31 19:26:22 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			305 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			305 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| const { task, src, dest, series, watch } = require("gulp");
 | |
| const axios = require("axios");
 | |
| const browserify = require("browserify");
 | |
| const babelify = require("babelify");
 | |
| const concat = require("gulp-concat");
 | |
| const del = require("del");
 | |
| const source = require("vinyl-source-stream");
 | |
| const buffer = require("vinyl-buffer");
 | |
| const vinylPaths = require("vinyl-paths");
 | |
| const eslint = require("gulp-eslint");
 | |
| var sass = require("gulp-sass")(require("dart-sass"));
 | |
| const replace = require("gulp-replace");
 | |
| // sass.compiler = require("dart-sass");
 | |
| 
 | |
| let eslintConfig = {
 | |
|   parser: "babel-eslint",
 | |
|   globals: [
 | |
|     "jQuery",
 | |
|     "$",
 | |
|     "firebase",
 | |
|     "moment",
 | |
|     "html2canvas",
 | |
|     "ClipboardItem",
 | |
|     "grecaptcha",
 | |
|   ],
 | |
|   envs: ["es6", "browser", "node"],
 | |
|   plugins: ["json"],
 | |
|   extends: ["plugin:json/recommended"],
 | |
|   rules: {
 | |
|     "json/*": ["error"],
 | |
|     "constructor-super": "error",
 | |
|     "for-direction": "error",
 | |
|     "getter-return": "error",
 | |
|     "no-async-promise-executor": "error",
 | |
|     "no-case-declarations": "error",
 | |
|     "no-class-assign": "error",
 | |
|     "no-compare-neg-zero": "error",
 | |
|     "no-cond-assign": "error",
 | |
|     "no-const-assign": "error",
 | |
|     "no-constant-condition": "error",
 | |
|     "no-control-regex": "error",
 | |
|     "no-debugger": "error",
 | |
|     "no-delete-var": "error",
 | |
|     "no-dupe-args": "error",
 | |
|     "no-dupe-class-members": "error",
 | |
|     "no-dupe-else-if": "warn",
 | |
|     "no-dupe-keys": "error",
 | |
|     "no-duplicate-case": "error",
 | |
|     "no-empty": ["warn", { allowEmptyCatch: true }],
 | |
|     "no-empty-character-class": "error",
 | |
|     "no-empty-pattern": "error",
 | |
|     "no-ex-assign": "error",
 | |
|     "no-extra-boolean-cast": "error",
 | |
|     "no-extra-semi": "error",
 | |
|     "no-fallthrough": "error",
 | |
|     "no-func-assign": "error",
 | |
|     "no-global-assign": "error",
 | |
|     "no-import-assign": "error",
 | |
|     "no-inner-declarations": "error",
 | |
|     "no-invalid-regexp": "error",
 | |
|     "no-irregular-whitespace": "warn",
 | |
|     "no-misleading-character-class": "error",
 | |
|     "no-mixed-spaces-and-tabs": "error",
 | |
|     "no-new-symbol": "error",
 | |
|     "no-obj-calls": "error",
 | |
|     "no-octal": "error",
 | |
|     "no-prototype-builtins": "error",
 | |
|     "no-redeclare": "error",
 | |
|     "no-regex-spaces": "error",
 | |
|     "no-self-assign": "error",
 | |
|     "no-setter-return": "error",
 | |
|     "no-shadow-restricted-names": "error",
 | |
|     "no-sparse-arrays": "error",
 | |
|     "no-this-before-super": "error",
 | |
|     "no-undef": "error",
 | |
|     "no-unexpected-multiline": "warn",
 | |
|     "no-unreachable": "error",
 | |
|     "no-unsafe-finally": "error",
 | |
|     "no-unsafe-negation": "error",
 | |
|     "no-unused-labels": "error",
 | |
|     "no-unused-vars": ["warn", { argsIgnorePattern: "e|event" }],
 | |
|     "no-use-before-define": "warn",
 | |
|     "no-useless-catch": "error",
 | |
|     "no-useless-escape": "error",
 | |
|     "no-with": "error",
 | |
|     "require-yield": "error",
 | |
|     "use-isnan": "error",
 | |
|     "valid-typeof": "error",
 | |
|   },
 | |
| };
 | |
| 
 | |
| //refactored files, which should be es6 modules
 | |
| //once all files are moved here, then can we use a bundler to its full potential
 | |
| const refactoredSrc = [
 | |
|   "./src/js/axios-instance.js",
 | |
|   "./src/js/db.js",
 | |
|   "./src/js/misc.js",
 | |
|   "./src/js/layouts.js",
 | |
|   "./src/js/sound.js",
 | |
|   "./src/js/theme-colors.js",
 | |
|   "./src/js/chart-controller.js",
 | |
|   "./src/js/theme-controller.js",
 | |
|   "./src/js/config.js",
 | |
|   "./src/js/tag-controller.js",
 | |
|   "./src/js/preset-controller.js",
 | |
|   "./src/js/ui.js",
 | |
|   "./src/js/commandline.js",
 | |
|   "./src/js/commandline-lists.js",
 | |
|   "./src/js/commandline.js",
 | |
|   "./src/js/challenge-controller.js",
 | |
|   "./src/js/mini-result-chart.js",
 | |
|   "./src/js/account-controller.js",
 | |
|   "./src/js/simple-popups.js",
 | |
|   "./src/js/settings.js",
 | |
|   "./src/js/input-controller.js",
 | |
|   "./src/js/route-controller.js",
 | |
|   "./src/js/ready.js",
 | |
|   "./src/js/monkey-power.js",
 | |
| 
 | |
|   "./src/js/account/all-time-stats.js",
 | |
|   "./src/js/account/pb-tables.js",
 | |
|   "./src/js/account/result-filters.js",
 | |
|   "./src/js/account/verification-controller.js",
 | |
|   "./src/js/account.js",
 | |
| 
 | |
|   "./src/js/elements/monkey.js",
 | |
|   "./src/js/elements/notifications.js",
 | |
|   "./src/js/elements/leaderboards.js",
 | |
|   "./src/js/elements/account-button.js",
 | |
|   "./src/js/elements/loader.js",
 | |
|   "./src/js/elements/sign-out-button.js",
 | |
|   "./src/js/elements/about-page.js",
 | |
|   "./src/js/elements/psa.js",
 | |
|   "./src/js/elements/new-version-notification.js",
 | |
|   "./src/js/elements/mobile-test-config.js",
 | |
|   "./src/js/elements/loading-page.js",
 | |
|   "./src/js/elements/scroll-to-top.js",
 | |
| 
 | |
|   "./src/js/popups/custom-text-popup.js",
 | |
|   "./src/js/popups/pb-tables-popup.js",
 | |
|   "./src/js/popups/quote-search-popup.js",
 | |
|   "./src/js/popups/quote-submit-popup.js",
 | |
|   "./src/js/popups/quote-approve-popup.js",
 | |
|   "./src/js/popups/rate-quote-popup.js",
 | |
|   "./src/js/popups/version-popup.js",
 | |
|   "./src/js/popups/support-popup.js",
 | |
|   "./src/js/popups/contact-popup.js",
 | |
|   "./src/js/popups/custom-word-amount-popup.js",
 | |
|   "./src/js/popups/custom-test-duration-popup.js",
 | |
|   "./src/js/popups/word-filter-popup.js",
 | |
|   "./src/js/popups/result-tags-popup.js",
 | |
|   "./src/js/popups/edit-tags-popup.js",
 | |
|   "./src/js/popups/edit-preset-popup.js",
 | |
|   "./src/js/popups/custom-theme-popup.js",
 | |
|   "./src/js/popups/import-export-settings-popup.js",
 | |
|   "./src/js/popups/custom-background-filter.js",
 | |
| 
 | |
|   "./src/js/settings/language-picker.js",
 | |
|   "./src/js/settings/theme-picker.js",
 | |
|   "./src/js/settings/settings-group.js",
 | |
| 
 | |
|   "./src/js/test/custom-text.js",
 | |
|   "./src/js/test/british-english.js",
 | |
|   "./src/js/test/lazy-mode.js",
 | |
|   "./src/js/test/shift-tracker.js",
 | |
|   "./src/js/test/out-of-focus.js",
 | |
|   "./src/js/test/caret.js",
 | |
|   "./src/js/test/manual-restart-tracker.js",
 | |
|   "./src/js/test/test-stats.js",
 | |
|   "./src/js/test/focus.js",
 | |
|   "./src/js/test/practise-words.js",
 | |
|   "./src/js/test/test-ui.js",
 | |
|   "./src/js/test/keymap.js",
 | |
|   "./src/js/test/result.js",
 | |
|   "./src/js/test/live-wpm.js",
 | |
|   "./src/js/test/caps-warning.js",
 | |
|   "./src/js/test/live-acc.js",
 | |
|   "./src/js/test/live-burst.js",
 | |
|   "./src/js/test/timer-progress.js",
 | |
|   "./src/js/test/test-logic.js",
 | |
|   "./src/js/test/funbox.js",
 | |
|   "./src/js/test/pace-caret.js",
 | |
|   "./src/js/test/pb-crown.js",
 | |
|   "./src/js/test/test-timer.js",
 | |
|   "./src/js/test/test-config.js",
 | |
|   "./src/js/test/layout-emulator.js",
 | |
|   "./src/js/test/poetry.js",
 | |
|   "./src/js/test/wikipedia.js",
 | |
|   "./src/js/test/today-tracker.js",
 | |
|   "./src/js/test/weak-spot.js",
 | |
|   "./src/js/test/wordset.js",
 | |
|   "./src/js/test/tts.js",
 | |
|   "./src/js/replay.js",
 | |
| ];
 | |
| 
 | |
| //legacy files
 | |
| //the order of files is important
 | |
| const globalSrc = ["./src/js/global-dependencies.js", "./src/js/exports.js"];
 | |
| 
 | |
| //concatenates and lints legacy js files and writes the output to dist/gen/index.js
 | |
| task("cat", function () {
 | |
|   return src(globalSrc)
 | |
|     .pipe(concat("index.js"))
 | |
|     .pipe(eslint(eslintConfig))
 | |
|     .pipe(eslint.format())
 | |
|     .pipe(eslint.failAfterError())
 | |
|     .pipe(dest("./dist/gen"));
 | |
| });
 | |
| 
 | |
| task("sass", function () {
 | |
|   return src("./src/sass/*.scss")
 | |
|     .pipe(concat("style.scss"))
 | |
|     .pipe(sass({ outputStyle: "compressed" }).on("error", sass.logError))
 | |
|     .pipe(dest("dist/css"));
 | |
| });
 | |
| 
 | |
| task("static", function () {
 | |
|   return src("./static/**/*", { dot: true }).pipe(dest("./dist/"));
 | |
| });
 | |
| 
 | |
| //copies refactored js files to dist/gen so that they can be required by dist/gen/index.js
 | |
| task("copy-modules", function () {
 | |
|   return src(refactoredSrc, { allowEmpty: true }).pipe(dest("./dist/gen"));
 | |
| });
 | |
| 
 | |
| //bundles the refactored js files together with index.js (the concatenated legacy js files)
 | |
| //it's odd that the entry point is generated, so we should seek a better way of doing this
 | |
| task("browserify", function () {
 | |
|   const b = browserify({
 | |
|     //index.js is generated by task "cat"
 | |
|     entries: "./dist/gen/index.js",
 | |
|     //a source map isn't very useful right now because
 | |
|     //the source files are concatenated together
 | |
|     debug: false,
 | |
|   });
 | |
|   return b
 | |
|     .transform(
 | |
|       babelify.configure({
 | |
|         presets: ["@babel/preset-env"],
 | |
|         plugins: ["@babel/transform-runtime"],
 | |
|       })
 | |
|     )
 | |
|     .bundle()
 | |
|     .pipe(source("monkeytype.js"))
 | |
|     .pipe(buffer())
 | |
|     .pipe(dest("./dist/js"));
 | |
| });
 | |
| 
 | |
| //lints only the refactored files
 | |
| task("lint", function () {
 | |
|   let filelist = refactoredSrc;
 | |
|   filelist.push("./static/**/*.json");
 | |
|   return src(filelist)
 | |
|     .pipe(eslint(eslintConfig))
 | |
|     .pipe(eslint.format())
 | |
|     .pipe(eslint.failAfterError());
 | |
| });
 | |
| 
 | |
| task("clean", function () {
 | |
|   return src("./dist/", { allowEmpty: true }).pipe(vinylPaths(del));
 | |
| });
 | |
| 
 | |
| task("updateSwCacheName", function () {
 | |
|   let date = new Date();
 | |
|   let dateString =
 | |
|     date.getFullYear() +
 | |
|     "-" +
 | |
|     (date.getMonth() + 1) +
 | |
|     "-" +
 | |
|     date.getDate() +
 | |
|     "-" +
 | |
|     date.getHours() +
 | |
|     "-" +
 | |
|     date.getMinutes() +
 | |
|     "-" +
 | |
|     date.getSeconds();
 | |
|   return src(["static/sw.js"])
 | |
|     .pipe(
 | |
|       replace(
 | |
|         /const staticCacheName = .*;/g,
 | |
|         `const staticCacheName = "sw-cache-${dateString}";`
 | |
|       )
 | |
|     )
 | |
|     .pipe(dest("./dist/"))
 | |
|     .pipe(dest("static/"));
 | |
| });
 | |
| 
 | |
| task(
 | |
|   "compile",
 | |
|   series(
 | |
|     "lint",
 | |
|     "cat",
 | |
|     "copy-modules",
 | |
|     "browserify",
 | |
|     "static",
 | |
|     "sass",
 | |
|     "updateSwCacheName"
 | |
|   )
 | |
| );
 | |
| 
 | |
| task("watch", function () {
 | |
|   watch(["./static/**/*", "./src/**/*"], series("compile"));
 | |
| });
 | |
| 
 | |
| task("build", series("clean", "compile"));
 |