diff --git a/Rules b/Rules index 34f943b13..2305337ac 100644 --- a/Rules +++ b/Rules @@ -25,12 +25,10 @@ surahs = Ryo.from_json(path: File.join(dirs.content, "json", "surahs.json")) tidy = `which tidy || which tidy5`.chomp buildenv = ENV["buildenv"] || "development" etcdir = File.join(__dir__, "etc") +globals = {buildenv:, locales:, tidy:, tdata:, surahs:, name_by_id:} ## # Filters -Nanoc::Webpack - .default_argv - .replace([*Nanoc::Webpack.default_argv, "--config", File.join(etcdir, "webpack.#{buildenv}.js")].uniq) Nanoc::Tidy .default_argv .replace([*Nanoc::Tidy.default_argv, "-upper"].uniq) @@ -55,19 +53,21 @@ compile "/robots.txt" do write("/robots.txt") end -## -# /json/durations/*.json -passthrough "/json/durations/*.json" - ## # Rules -require_rules "nanoc/rules/assets" -require_rules "nanoc/rules/redirect", {locales:, tidy:} -require_rules "nanoc/rules/random", {locales:, tdata:, tidy:} -require_rules "nanoc/rules/surah-stream", {locales:, tdata:, surahs:, name_by_id:, tidy:} -require_rules "nanoc/rules/surah-index", {locales:, tdata:, tidy:} +passthrough "/json/durations/*.json" +require_rules "nanoc/rules/assets", globals +require_rules "nanoc/rules/redirect", globals +require_rules "nanoc/rules/random", globals +require_rules "nanoc/rules/surah-stream", globals +require_rules "nanoc/rules/surah-index", globals -## -# Catch-all +compile "/js/main/vendor.ts" do + filter :webpack, + argv: %w[--config etc/webpack.vendor.js] + write("/js/main/vendor.js") + filter :gzip + write("/js/main/vendor.js.gz") +end compile("/**/*") { write(nil) } layout("**/*", :erb) diff --git a/etc/webpack.vendor.js b/etc/webpack.vendor.js new file mode 100644 index 000000000..5d9ca513d --- /dev/null +++ b/etc/webpack.vendor.js @@ -0,0 +1,14 @@ +const path = require('path'); +const common = require('./webpack.common.js'); +const { merge } = require('webpack-merge'); + +module.exports = (env, argv) => { + return merge( + common, + { + output: { library: { type: 'umd' } }, + resolve: { extensions: ['.ts', '.tsx'] }, + optimization: { minimize: true } + } + ) +} diff --git a/nanoc/rules/random.rules b/nanoc/rules/random.rules index 5d7d4478d..ba899fcb9 100644 --- a/nanoc/rules/random.rules +++ b/nanoc/rules/random.rules @@ -15,7 +15,9 @@ locales.each do |locale| end compile "/js/main/random.ts" do - filter(:webpack, depend_on: ["/js/lib/"]) + filter :webpack, + argv: %W[--config etc/webpack.#{buildenv}.js], + depend_on: ["/js/lib/"] write("/js/main/random.js") filter(:gzip) write("/js/main/random.js.gz") diff --git a/nanoc/rules/redirect.rules b/nanoc/rules/redirect.rules index d2b707fb2..c029caa8f 100644 --- a/nanoc/rules/redirect.rules +++ b/nanoc/rules/redirect.rules @@ -12,7 +12,9 @@ compile "/html/main/redirect.html.erb" do end compile "/js/main/redirect.ts" do - filter(:webpack, depend_on: ["/js/lib/"]) + filter :webpack, + argv: %W[--config etc/webpack.#{buildenv}.js], + depend_on: ["/js/lib/"] write("/js/main/redirect.js") filter(:gzip) write("/js/main/redirect.js.gz") diff --git a/nanoc/rules/surah-index.rules b/nanoc/rules/surah-index.rules index c1d71389f..599de5a5c 100644 --- a/nanoc/rules/surah-index.rules +++ b/nanoc/rules/surah-index.rules @@ -15,19 +15,22 @@ locales.each do |locale| end compile "/js/main/surah-index.tsx" do - filter :webpack, depend_on: [ - "/js/components", - "/js/lib", - "/js/hooks", - "/css" - ] + filter :webpack, + argv: %W[--config etc/webpack.#{buildenv}.js], + depend_on: [ + "/js/components", + "/js/lib", + "/js/hooks", + "/css" + ] write "/js/main/surah-index.js" filter :gzip write "/js/main/surah-index.js.gz" end compile "/js/loaders/SurahIndexLoader.ts" do - filter :webpack + filter :webpack, + argv: %W[--config etc/webpack.#{buildenv}.js] write "/js/loaders/surah-index-loader.js" filter :gzip write "/js/loaders/surah-index-loader.js.gz" diff --git a/nanoc/rules/surah-stream.rules b/nanoc/rules/surah-stream.rules index dccc225b5..8449142f6 100644 --- a/nanoc/rules/surah-stream.rules +++ b/nanoc/rules/surah-stream.rules @@ -32,19 +32,22 @@ Ryo.each(name_by_id) do |id, slug| end compile "/js/main/surah-stream.tsx" do - filter :webpack, depend_on: [ - "/js/components", - "/js/lib", - "/js/hooks", - "/css" - ] + filter :webpack, + argv: %W[--config etc/webpack.#{buildenv}.js], + depend_on: [ + "/js/components", + "/js/lib", + "/js/hooks", + "/css" + ] write "/js/main/surah-stream.js" filter :gzip write "/js/main/surah-stream.js.gz" end compile "/js/loaders/SurahStreamLoader.ts" do - filter :webpack + filter :webpack, + argv: %W[--config etc/webpack.#{buildenv}.js] write "/js/loaders/surah-stream-loader.js" filter :gzip write "/js/loaders/surah-stream-loader.js.gz" diff --git a/package-lock.json b/package-lock.json index 810f4b861..4fe9b3c5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,8 +10,7 @@ ], "dependencies": { "classnames": "^2.3", - "react": "^18.2", - "react-dom": "^18.2" + "preact": "^10.23.2" }, "devDependencies": { "@types/css-font-loading-module": "^0.0.13", @@ -2638,12 +2637,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2780,18 +2773,6 @@ "dev": true, "license": "MIT" }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -3245,6 +3226,16 @@ "resolved": "packages/typescript/postman", "link": true }, + "node_modules/preact": { + "version": "10.23.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.23.2.tgz", + "integrity": "sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3345,31 +3336,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3572,15 +3538,6 @@ } } }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, "node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", diff --git a/package.json b/package.json index 917ccb21b..30df0fe73 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,7 @@ }, "dependencies": { "classnames": "^2.3", - "react": "^18.2", - "react-dom": "^18.2" + "preact": "^10.23.2" }, "devDependencies": { "@types/css-font-loading-module": "^0.0.13", diff --git a/rake/tasks/nanoc.rake b/rake/tasks/nanoc.rake index 314fe61ac..b63dc52c2 100644 --- a/rake/tasks/nanoc.rake +++ b/rake/tasks/nanoc.rake @@ -5,7 +5,7 @@ namespace :nanoc do task :clean do Dir.chdir(dirs.root) do sh "rm -rf node_modules/.cache/" - sh "rm -rf build/" + sh "rm -rf #{nanoc.output_dir}/*" sh "rm -rf tmp/" end end diff --git a/share/al-quran.reflectslight.io/CHANGELOG b/share/al-quran.reflectslight.io/CHANGELOG index 4ee1679d1..df92ee8d4 100644 --- a/share/al-quran.reflectslight.io/CHANGELOG +++ b/share/al-quran.reflectslight.io/CHANGELOG @@ -2,13 +2,24 @@ ** vNEXT +**** Add ~src/js/main/vendor.ts~ +The new vendor entry point bundles preact, and other +third party dependencies in a single file. This change +is an improvement imported from the ~kaios/main~ branch + +**** Replace React with preact +The preact library is a lightweight alternative to React, +with a smaller footprint. This change is an improvement +imported from the ~kaios/main~ branch + **** Change default ~audio.base_url~ This change sets the default audio URL to -https://audio1.al-quran.reflectslight.io/rifai +https://audio.al-quran.reflectslight.io/rifai **** Improve KaiOS support This change optimizes the layout for KaiOS devices through -specialized media queries +specialized media queries. A new branch (~kaios/main~) will +focus on KaiOS support **** Add ~etc/~ This change moves a large portion of the website's configuration diff --git a/src/html/main/random.html.erb b/src/html/main/random.html.erb index 171f8fb52..0d4990ad5 100644 --- a/src/html/main/random.html.erb +++ b/src/html/main/random.html.erb @@ -18,6 +18,7 @@ <%= erb("_favicon.html.erb") %> + diff --git a/src/html/main/redirect.html.erb b/src/html/main/redirect.html.erb index 27484624d..ebf6d2d20 100644 --- a/src/html/main/redirect.html.erb +++ b/src/html/main/redirect.html.erb @@ -15,6 +15,7 @@ <%= erb("_favicon.html.erb") %> + diff --git a/src/html/main/surah-index.html.erb b/src/html/main/surah-index.html.erb index f8b993c08..a8a670c1b 100644 --- a/src/html/main/surah-index.html.erb +++ b/src/html/main/surah-index.html.erb @@ -22,6 +22,7 @@ <%= erb("_postman.html.erb", {locale: context.locale, dir: context.dir}) %>
+ diff --git a/src/html/main/surah-stream.html.erb b/src/html/main/surah-stream.html.erb index ecf1ca2c7..91600c450 100644 --- a/src/html/main/surah-stream.html.erb +++ b/src/html/main/surah-stream.html.erb @@ -25,6 +25,7 @@ data-surah-id="<%= context.surah.id %>" data-audio-base-url="<%= audio_base_url %>"> + diff --git a/src/js/components/AudioControl.tsx b/src/js/components/AudioControl.tsx index 34fd63164..d7cd0c240 100644 --- a/src/js/components/AudioControl.tsx +++ b/src/js/components/AudioControl.tsx @@ -1,4 +1,3 @@ -import React, { useEffect, useState } from "react"; import type { Surah, Ayah } from "Quran"; import { SoundOnIcon, SoundOffIcon } from "~/components/Icon"; diff --git a/src/js/components/Head.tsx b/src/js/components/Head.tsx index 1c762a40f..3813ca0d5 100644 --- a/src/js/components/Head.tsx +++ b/src/js/components/Head.tsx @@ -1,4 +1,3 @@ -import React from "react"; import type { ReactNode } from "react"; import { LanguageSelect, ThemeSelect } from "~/components/Select"; import type { TLocale } from "Quran"; diff --git a/src/js/components/Icon.tsx b/src/js/components/Icon.tsx index 3afc2309a..b7c264687 100644 --- a/src/js/components/Icon.tsx +++ b/src/js/components/Icon.tsx @@ -1,6 +1,3 @@ -import React from "react"; -import classNames from "classnames"; - type Props = { onClick: () => void; }; diff --git a/src/js/components/Select/LanguageSelect.tsx b/src/js/components/Select/LanguageSelect.tsx index 9a96b29f6..81e75b1f3 100644 --- a/src/js/components/Select/LanguageSelect.tsx +++ b/src/js/components/Select/LanguageSelect.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { Quran, TLocale } from "Quran"; import { Select } from "~/components/Select"; import classNames from "classnames"; diff --git a/src/js/components/Select/Option.tsx b/src/js/components/Select/Option.tsx index f7fba6e20..3a73a0f16 100644 --- a/src/js/components/Select/Option.tsx +++ b/src/js/components/Select/Option.tsx @@ -1,5 +1,3 @@ -import React, { ReactNode, AnchorHTMLAttributes } from "react"; - type Rest = AnchorHTMLAttributes; type Props = { value: string; diff --git a/src/js/components/Select/ThemeSelect.tsx b/src/js/components/Select/ThemeSelect.tsx index db4cc3a9b..ef70e8df3 100644 --- a/src/js/components/Select/ThemeSelect.tsx +++ b/src/js/components/Select/ThemeSelect.tsx @@ -1,7 +1,5 @@ -import React from "react"; import { Select } from "~/components/Select"; import type { Theme } from "~/hooks/useTheme"; -import classNames from "classnames"; type Props = { theme: string; diff --git a/src/js/components/Select/index.tsx b/src/js/components/Select/index.tsx index 80944c8f2..3dbff9706 100644 --- a/src/js/components/Select/index.tsx +++ b/src/js/components/Select/index.tsx @@ -1,5 +1,3 @@ -import React, { useState, useEffect } from "react"; -import classNames from "classnames"; import { Option } from "./Option"; import { ThemeSelect } from "./ThemeSelect"; import { LanguageSelect } from "./LanguageSelect"; diff --git a/src/js/components/SurahIndex/Filter.tsx b/src/js/components/SurahIndex/Filter.tsx index 841d538dc..3c164f797 100644 --- a/src/js/components/SurahIndex/Filter.tsx +++ b/src/js/components/SurahIndex/Filter.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { TFunction, formatNumber } from "~/lib/t"; import type { Surah, TLocale } from "Quran"; diff --git a/src/js/components/SurahIndex/index.tsx b/src/js/components/SurahIndex/index.tsx index 52c4e683e..b047c7cc0 100644 --- a/src/js/components/SurahIndex/index.tsx +++ b/src/js/components/SurahIndex/index.tsx @@ -1,11 +1,9 @@ -import React, { useRef, useState, useEffect } from "react"; import type { Surah, TLocale } from "Quran"; import { useTheme } from "~/hooks/useTheme"; import { formatNumber, TFunction } from "~/lib/t"; import { Arrow } from "~/components/Icon"; import { Head } from "~/components/Head"; import { Filter } from "./Filter"; -import classNames from "classnames"; import "@css/main/SurahIndex.scss"; type Props = { diff --git a/src/js/components/SurahStream/Stream.tsx b/src/js/components/SurahStream/Stream.tsx index e66108047..1d26e4103 100644 --- a/src/js/components/SurahStream/Stream.tsx +++ b/src/js/components/SurahStream/Stream.tsx @@ -1,4 +1,3 @@ -import React, { useEffect, useMemo, useRef } from "react"; import type { Surah, Ayah, TAyat, TLocale } from "Quran"; import { AudioControl } from "~/components/AudioControl"; import { formatNumber, TFunction } from "~/lib/t"; diff --git a/src/js/components/SurahStream/index.tsx b/src/js/components/SurahStream/index.tsx index 6425f5697..ced81457f 100644 --- a/src/js/components/SurahStream/index.tsx +++ b/src/js/components/SurahStream/index.tsx @@ -1,5 +1,3 @@ -import React, { useState, useEffect, useMemo, useRef } from "react"; -import classNames from "classnames"; import type { Surah, Ayah, TAyat, TLocale } from "Quran"; import { useTheme } from "~/hooks/useTheme"; import { AudioControl, TAudioStatus } from "~/components/AudioControl"; diff --git a/src/js/components/Timer/index.tsx b/src/js/components/Timer/index.tsx index 5f262df9a..863bf1404 100644 --- a/src/js/components/Timer/index.tsx +++ b/src/js/components/Timer/index.tsx @@ -1,4 +1,3 @@ -import React, { useEffect, useState } from "react"; import type { Surah, Ayah, TLocale } from "Quran"; import { formatNumber } from "~/lib/t"; diff --git a/src/js/hooks/useTheme.ts b/src/js/hooks/useTheme.ts index d6d68c8fa..e00c379ef 100644 --- a/src/js/hooks/useTheme.ts +++ b/src/js/hooks/useTheme.ts @@ -1,5 +1,3 @@ -import { useState } from "react"; - export type Theme = "blue" | "green"; type Result = [Theme, (t: Theme) => void]; const THEMES: Theme[] = ["blue", "green"]; diff --git a/src/js/main/surah-index.tsx b/src/js/main/surah-index.tsx index e453558f3..2d6a899c8 100644 --- a/src/js/main/surah-index.tsx +++ b/src/js/main/surah-index.tsx @@ -1,6 +1,4 @@ import { Surah, TSurah, Quran } from "Quran"; -import React from "react"; -import ReactDOM from "react-dom/client"; import { T } from "~/lib/t"; import { SurahIndex } from "~/components/SurahIndex"; @@ -16,7 +14,8 @@ import { SurahIndex } from "~/components/SurahIndex"; (e: TSurah) => new Surah(e), ); - ReactDOM.createRoot(root).render( + render( , + root ); })(); diff --git a/src/js/main/surah-stream.tsx b/src/js/main/surah-stream.tsx index 7571cf5ab..fc2e16f4d 100644 --- a/src/js/main/surah-stream.tsx +++ b/src/js/main/surah-stream.tsx @@ -1,6 +1,4 @@ import { Quran, Surah, Ayah, TSurah } from "Quran"; -import React from "react"; -import ReactDOM from "react-dom/client"; import { T } from "~/lib/t"; import { SurahStream } from "~/components/SurahStream"; @@ -32,7 +30,8 @@ import { SurahStream } from "~/components/SurahStream"; ayah.ms = ms * 1000; } - ReactDOM.createRoot(root).render( + render( , + root ); })(); diff --git a/src/js/main/vendor.ts b/src/js/main/vendor.ts new file mode 100644 index 000000000..89cabbe66 --- /dev/null +++ b/src/js/main/vendor.ts @@ -0,0 +1,15 @@ +import { render } from "preact"; +import { useState, useEffect, useMemo, useRef } from "preact/hooks"; +import * as React from "preact/compat"; +import classNames from "classnames"; + +const exports = { + React, + render, + useState, + useEffect, + useMemo, + useRef, + classNames, +}; +Object.assign(window, exports);