diff --git a/.gitignore b/.gitignore index 6d50c5d..b868513 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ versions archive node_modules/ flow/ +tests diff --git a/CLI_ANNOUNCE.md b/CLI_ANNOUNCE.md index f752978..bef219c 100644 --- a/CLI_ANNOUNCE.md +++ b/CLI_ANNOUNCE.md @@ -1,3 +1,5 @@ +# v1.8.0 port RangeStart can be specified via --port for serving apps +# v1.7.2 *NEW* # v1.7.1 Do: sergeant create app_builder myawesomeapp # v1.7.0 Added windows support. Stable version. # v1.6.0 Support for data: svg url import resolution Stable version diff --git a/README.md b/README.md index 53215d3..30d3bdb 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,18 @@ # About Sergeant -A lightweight micro-services producing deno-[p]react SSG-first SEO-friendly framework. +A lightweight micro-services producing deno-[p]react SSG-first SEO-friendly +framework. -For a new era of frontend development with NO node_modules (Save GB+ files on disk). +For a new era of frontend development with NO node_modules (Save GB+ files on +disk). -+ Produces bundles within seconds for 100s of apps. -+ Cross-compile from multiple projects -+ Supports scss -+ Scaffolding -+ Has livereload -+ denocacheusage: 10MB only, bundle sizes less than 20KB (if u use preact), and 200KB for react. +- Produces bundles within seconds for 100s of apps. +- Cross-compile from multiple projects +- Supports scss +- Scaffolding +- Has livereload +- denocacheusage: 10MB only, bundle sizes less than 20KB (if u use preact), and + 200KB for react. Compare this with 200MB-400MB node_modules for a react hello world project. @@ -17,7 +20,7 @@ Finally, you can `rimraf node_modules`. # Sergeant is production ready from Day-1 -✨ Sergeant 🫡 A front-end microservices framework! +✨ Sergeant 🫡 A front-end microservices framework! ``` ███████╗███████╗██████╗ ██████╗ ███████╗ █████╗ ███╗ ██╗████████╗ @@ -52,15 +55,18 @@ Done ``` ## Philosophy + 1. No breaking changes (versioned imports) 2. SSG over SSR 3. Always bundle to one-file for 1-SPA ### More... + 4. Support bundling multiple apps, SPAs via micro-services / app-routing 5. Support progressive and offline apps # Commands + ``` sergeant sergeant build @@ -69,46 +75,50 @@ sergeant serve --dev ``` # Install + Only need deno to install sergeant (esbuild is automatically imported): ## sergeant ``` -deno install -A -f https://cdn.jsdelivr.net/gh/scriptmaster/sergeant@1.7.1/sergeant.ts +deno install -A -f https://cdn.jsdelivr.net/gh/scriptmaster/sergeant@1.8.0/sergeant.ts ``` Only need deno and sergeant and you can do `sergeant` or `sergeant serve` ### Build All apps: + `sergeant build` ### Live Dev Server all apps: -`sergeant serve` +`sergeant serve` ### Build specific app: + `sergeant build` ### Live Dev Server specific app: -`sergeant serve` +`sergeant serve` ## Installing Deno + https://docs.deno.com/runtime/manual/getting_started/installation -### Windows x64: -Using PowerShell (Windows): -irm https://deno.land/install.ps1 | iex +### Windows x64: + +Using PowerShell (Windows): irm https://deno.land/install.ps1 | iex #### Or Using Chocolatey: + choco install deno ### MacOS: brew install deno - # Deno Plugins: -Uses: -https://github.com/scriptmaster/esbuild_deno_loader + +Uses: https://github.com/scriptmaster/esbuild_deno_loader https://deno.land/x/esbuild_plugin_sass_deno https://github.com/esbuild/community-plugins#plugins-for-deno @@ -116,17 +126,20 @@ https://github.com/esbuild/community-plugins#plugins-for-deno How packages are downloaded? -Packages are primarily downloaded as ESM modules from https://esm.sh/package/ (instead of registry.npmjs.org). - + It can be swapped to use enterprise ESM packages repository. - + Packages +Packages are primarily downloaded as ESM modules from https://esm.sh/package/ +(instead of registry.npmjs.org). -The package can be looked up in ./vendor/ and ./node_modules/ in the format mod.ts index.mjs index.cjs index.js +- It can be swapped to use enterprise ESM packages repository. +- Packages +The package can be looked up in ./vendor/ and ./node_modules/ in the format +mod.ts index.mjs index.cjs index.js # DI -React Context API is an incorrect implementation of a simple DI with prop drilling. -In apps containing 20+ dependencies to provider, the context pattern could become 20+ nested nodes. +React Context API is an incorrect implementation of a simple DI with prop +drilling. In apps containing 20+ dependencies to provider, the context pattern +could become 20+ nested nodes. DI enables you to directly provide the service/implementation for the consumer. @@ -136,12 +149,12 @@ Extra watch dirs Create app level deno.json and configure watching extra deps: -{ - "watch": "emeraldcss" -} +{ "watch": "emeraldcss" } # mithril -if an app dir contains mithril dir, its files (i.e., apps/appname/mithril/*.html or src/mithril/*.html) will be compiled as mithril files. + +if an app dir contains mithril dir, its files (i.e., apps/appname/mithril/_.html +or src/mithril/_.html) will be compiled as mithril files. # web framework diff --git a/deno.json b/deno.json index 10cd36e..ba256cb 100644 --- a/deno.json +++ b/deno.json @@ -1,36 +1,37 @@ { - "imports": { - "react": "https://esm.sh/react@18.2.0?prod", - "react-dom": "https://esm.sh/react-dom@18.2.0?prod", - "preact": "https://esm.sh/preact@10.17.1", - "preact-router": "https://esm.sh/preact-router@4.1.2", - "preact-render-to-string/jsx": "https://esm.sh/preact-render-to-string@6.2.1/jsx", - "@preact/compat": "https://esm.sh/@preact/compat@17.1.2", - "react-redux": "./vendor/github.com/react-redux/src/index.ts", - "vue": "https://esm.sh/vue@3.3.4", - "d3": "https://esm.sh/d3@7.8.5", - "emeraldcss": "https://unpkg.com/emeraldcss@1.0.1", - "emeraldcss/": "https://unpkg.com/emeraldcss@1.0.1/", - "antd": "https://esm.sh/antd", - "@angular/cli": "https://esm.sh/@angular/cli", - "vendor": "https://esm.sh/vendor", - "react-router-dom": "https://esm.sh/react-router-dom" - }, - "compilerOptions": { - "jsx": "react-jsx" - }, - "tasks": { - "build": "deno run -A sergeant.ts", - "install": "deno install -A -f -n sergeant sergeant.ts", - "install_vendor": "deno install -A -f -n vendor vendor.ts", - "debug": "deno run -A sergeant.ts nn", - "ssg": "deno task build ssg; denoliver dist/ssg/static/ -p 3300" - }, - "deploy": { - "project": "8ced75ac-cfa0-4a9b-9783-c8a8e1b3aaf9", - "exclude": [ - "**/node_modules" - ], - "entrypoint": "https://deno.land/std@0.217.0/http/file_server.ts" - } -} \ No newline at end of file + "imports": { + "react": "https://esm.sh/react@18.3.1", + "react-dom": "https://esm.sh/react-dom@18.3.1", + "react-dom/": "https://esm.sh/react-dom@18.3.1/", + "preact": "https://esm.sh/preact@10.17.1", + "preact-router": "https://esm.sh/preact-router@4.1.2", + "preact-render-to-string/jsx": "https://esm.sh/preact-render-to-string@6.2.1/jsx", + "@preact/compat": "https://esm.sh/@preact/compat@17.1.2", + "react-redux": "./vendor/github.com/react-redux/src/index.ts", + "vue": "https://esm.sh/vue@3.3.4", + "d3": "https://esm.sh/d3@7.8.5", + "emeraldcss": "https://unpkg.com/emeraldcss@1.0.1", + "emeraldcss/": "https://unpkg.com/emeraldcss@1.0.1/", + "antd": "https://esm.sh/antd", + "@angular/cli": "https://esm.sh/@angular/cli", + "vendor": "https://esm.sh/vendor", + "react-router-dom": "https://esm.sh/react-router-dom" + }, + "compilerOptions": { + "jsx": "react-jsx" + }, + "tasks": { + "build": "deno run -A sergeant.ts", + "install": "deno install -A -f -n sergeant sergeant.ts", + "install_vendor": "deno install -A -f -n vendor vendor.ts", + "debug": "deno run -A sergeant.ts nn", + "ssg": "deno task build ssg; denoliver dist/ssg/static/ -p 3300" + }, + "deploy": { + "project": "8ced75ac-cfa0-4a9b-9783-c8a8e1b3aaf9", + "exclude": [ + "**/node_modules" + ], + "entrypoint": "https://deno.land/std@0.217.0/http/file_server.ts" + } +} diff --git a/deno.lock b/deno.lock index 5121429..501aca5 100644 --- a/deno.lock +++ b/deno.lock @@ -4,10 +4,7 @@ "https://esm.sh/@esbuild-plugins/esm-externals": "https://esm.sh/@esbuild-plugins/esm-externals@0.1.2", "https://esm.sh/@esbuild-plugins/node-globals-polyfill": "https://esm.sh/@esbuild-plugins/node-globals-polyfill@0.2.3", "https://esm.sh/@esbuild-plugins/node-modules-polyfill": "https://esm.sh/@esbuild-plugins/node-modules-polyfill@0.2.2", - "https://esm.sh/brain.js": "https://esm.sh/brain.js@2.0.0-beta.23", - "https://esm.sh/mithril": "https://esm.sh/mithril@2.2.2", - "https://esm.sh/nano-time": "https://esm.sh/nano-time@1.0.0", - "https://esm.sh/v135/@types/mithril@~2.2/index.d.ts": "https://esm.sh/v135/@types/mithril@2.2.6/index.d.ts" + "https://esm.sh/nano-time": "https://esm.sh/nano-time@1.0.0" }, "remote": { "https://deno.land/std@0.131.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", @@ -229,27 +226,13 @@ "https://esm.sh/@esbuild-plugins/esm-externals@0.1.2": "7659390c51a050c793e4569dc5be2f1feb178099d9d2a527e0ebc51e0e3bf09a", "https://esm.sh/@esbuild-plugins/node-globals-polyfill@0.2.3": "08386c2ab8f0a2af723eeb63808dbc9738ddd19561b776bd13a6d1339faeb35f", "https://esm.sh/@esbuild-plugins/node-modules-polyfill@0.2.2": "36f6fe1feaa352f37d5b974edf0ac5d818f30ee877150bb13736cfb83c31c407", - "https://esm.sh/brain.js@2.0.0-beta.23": "dee27460688fc572280af4a772326d71c3033d566406f50a8422c710023ee060", - "https://esm.sh/mithril@2.2.2": "b534d1279e423f5a19ce251317a4511263e6d449cb9376c6a754f0ed327ba6f9", - "https://esm.sh/nano-time@1.0.0": "1d401c8f37d9c2a86e7931afdd55f537e1b98b147cf34c835ef824c1ec293edf", + "https://esm.sh/nano-time@1.0.0": "d8fe32c105e4a81fccb34efeb940ae03dad849562f9a6d05d19bd03a35f24df4", "https://esm.sh/v135/@babel/standalone@7.23.10/denonext/standalone.mjs": "b45b46e16592f669bad127680782a4816fb4b890a7c1eb7739ab8adb7f8c8fd4", "https://esm.sh/v135/@esbuild-plugins/esm-externals@0.1.2/denonext/esm-externals.mjs": "30a6ed920cc68626e189d21f9fd417ecb57c660c14f1138eec9059da222a58a5", "https://esm.sh/v135/@esbuild-plugins/node-globals-polyfill@0.2.3/denonext/node-globals-polyfill.mjs": "0a79699f1dc304831be8aaaed525720d4e62dab6b92bc4e13282fcb74b107839", "https://esm.sh/v135/@esbuild-plugins/node-modules-polyfill@0.2.2/denonext/node-modules-polyfill.mjs": "b046d06154e905e0a79e9c47bb8af6102f95b60f18a9edde5d3989fa26868bcc", "https://esm.sh/v135/big-integer@1.6.51/denonext/big-integer.mjs": "f35cd654bd00974380bfcda29cf735fb67cbd4461337c89a8fecba7062d7320f", - "https://esm.sh/v135/big-integer@1.6.52/denonext/big-integer.mjs": "e19d1a50baedc8fe96134f5103b2d20552d59f4ba28bdee3cc546f27d629cdbc", - "https://esm.sh/v135/brain.js@2.0.0-beta.23/denonext/brain.mjs": "48050ab3b59c08143a243f4cbd2badd9f7fe259df046970e8c5b4c3d8259f1b9", "https://esm.sh/v135/escape-string-regexp@4.0.0/denonext/escape-string-regexp.mjs": "4bebd5b21a97ea88f1b93f2851c077053d3cc323ac2b2eefc835ff3d7dab8ae9", - "https://esm.sh/v135/mithril@2.2.2/denonext/mithril.mjs": "3d36ab52d61c8ebc54cffcf4ab53626742b4d38a8672c3157d9df35b278ec5ba", "https://esm.sh/v135/nano-time@1.0.0/denonext/nano-time.mjs": "5d319b3b3f5ac56aa39e5cd2296033bb614c0beccbe888e5d2f0449c29539e88" - }, - "workspace": { - "packageJson": { - "dependencies": [ - "npm:react-dom@^18.2.0", - "npm:react@^18.2.0", - "npm:scheduler@^0.23.0" - ] - } } } diff --git a/sergeant.ts b/sergeant.ts index 66f3ee4..94cc557 100644 --- a/sergeant.ts +++ b/sergeant.ts @@ -56,8 +56,8 @@ import { // To get started: // deno install -f -A sergeant.ts; sergeant serve -const portRangeStart = 3000; -const VERSION = "v1.7.2"; +const port = { RangeStart: 3000 }; +const VERSION = "v1.8.0"; const ESBUILD_MODE = Deno.env.get("ESBUILD_PLATFORM") || Deno.env.get("ESBUILD_MODE") || "neutral"; const ESBUILD_FORMAT = Deno.env.get("ESBUILD_FORMAT") || "esm"; @@ -266,14 +266,28 @@ async function buildApps(appName = "") { } async function serveApps(appName: string) { + if (args.includes("--port")) { + const portIndex = args.indexOf("--port"); + if (args[portIndex + 1] && parseInt(args[portIndex + 1], 10)) { + port.RangeStart = parseInt(args[portIndex + 1], 10); + // console.log("port RangeStart:", port.RangeStart); + } + } + if (args.includes("-p")) { + const portIndex = args.indexOf("-p"); + if (args[portIndex + 1] && parseInt(args[portIndex + 1], 10)) { + port.RangeStart = parseInt(args[portIndex + 1], 10); + // console.log("port RangeStart:", port.RangeStart); + } + } if (appName && appName[0] != "-") { //do not mistake for a flag like: --dev if (!existsSync(app(appName))) { return console.log("No such app: ", app(appName)); } - return await serveRefresh(appName, portRangeStart); + return await serveRefresh(appName, port.RangeStart); } else if (appsDir == "src") { console.log("Serving ."); - await serveRefresh(".", portRangeStart); + await serveRefresh(".", port.RangeStart); return; } @@ -283,7 +297,7 @@ async function serveApps(appName: string) { for await (const dirEntry of Deno.readDir(appsDir)) { if (dirEntry.isDirectory && dirEntry.name[0] != ".") { // const appDir = join(appsDir, dirEntry.name); - await serveRefresh(dirEntry.name, portRangeStart + servers); + await serveRefresh(dirEntry.name, port.RangeStart + servers); servers++; } }