Recommended Way to Do Web Development
- UUID: 17c800a5-74a0-4d7f-a7e5-547bac717953
- Remarks
- 20231123, written to help myself to sort things better (mark a decision snapshot) as well as contributing to the progress of web development in public
Proper wording or definition helps understanding, therefore, a bit explanation for web development comes there. Web development has been a name mainly for web browser application development since quite some time, but web development literally not really just means web browser application development or web frontend development, and it does not really mean the "web" which is a subconcept of the Internet or a synonyme of the Internet. But in this article, I intend the web development means using technologies such as C/S or B/S architecture, HTTP (TCP/IP), HTML, CSS, JavaScript and related technology to do software development. Worth pointing out the related technology is vague concept to contain many different other technologies such as TypeScript, Webpack, Node.js, C#, .NET Core, Python, Flask, as well as many further technologies used to do web backend development.
Because of the huge community of web development, web technologies are commonly thought to be the most flexible way to do great GUI. The architecture of logical tree structure, visual layout or styling, and dynamic user interaction represented by HTML, CSS and JavaScript makes web GUI logically easy to understand. With the advent of web components, namespace conflict in stylesheet also gets dealt without the need a backend to serve parts in iframe for the purpose of isolation.
Web also has arrived in the "native" worlds represented by technologies such as webview, webview2, Electron and so on, which further makes GUI in web a very universal option and choice. However, web on many different platforms results in many differences which also means a relatively limited common parts, especially when it comes to new technologies in web such as web modules, web workers and so on.
The multiple instances and separate taskbar/dock icons issue
In recent years, I like one app especially, which is Notion. So let me take Notion as an example. It is not a perfect app, but one of the best considering the certain use case. Better to point out some drawbacks before going to feel too ritual. Notion in comparison with Apple Notes is almost unusable when it comes to be offline - or in terms of offline accessibility, because of the centralized data storage architecture in comparison to the decentralized data storage architeture of Apple Notes. Apple Notes wins hugely which can be the Go decision for Apple Notes or No-Go decision for Notion in certain use case. Because, as of 2023, Internet in Germany on trains for example is very broken which makes Notion almost unusable when traveling on trains in Germany. Imperfect as set, let's look at goodies.
Notion as an web application is great in many aspects. Around multiple instances, being an web app allows one human user to have multiple accounts which can be used simultaneously on different web browsers, which means 1 user versus N accounts which is not usually possible for applications like native Apple Notes (which doesn't even decouple with the OS account - but to be fair Apple Notes also has web version, so not a perfect example here but as it was mentioned above, let's assume there is no web version of Apple Notes - also because the web version of Apple Notes is very broken in terms of features comparing to the native version on iPhone OS, iPad OS or Mac OS). Of course, being a note app, Notion allow multiple notes let alone multiple workspaces. The point here is that a user sometimes needs to open multiple notes or same notes multiple times at the same time for comparison (A with B or A upper with A lower) or any other purposes. It is doable on Notion, because of being an web app, and web browsers supports multiple tabs naturally. Worth mentioning, Notion supports this need very well because of its support for collaboration - which mean, updates on different tabs (A upper and A lower) are synchronized automatically. If multiple notes should be visible at the same time, web browser also typically support multiple windows at the same time. If multiple task bar icons are needed for quick switch, using different web browsers also comes in handy. But there comes an issue, it is limited by how many different web browsers are available to use for this purpose. Although with this theoritical limitation, typical common use case would not really be limited by such an limitation, because most people most commonly only just open two notes at the same time if multi-tasking.
The multiple instance (1 user versus N accounts, 1 users version N notes at the same time) is specifically the reason I like Notion much besides the support for Markdown on both input and export asepcts. But it is not alway available, thinking about the no Internet condition. So I also especially like another app, which is Obsidian. Obsidian solves the multiple notes at the same in another way. It is essentially an web app but not accessed via web browsers. It makes sense because the unique feature I like about Obsidian is its directly work on plan Markdown files on my disk. Working on files via web browsers up to today is still very much limited. Obsidian solves the multiple notes at the same time by allowing mutliple in-app panes or tabs. However, there is another shortcoming comparing to Notion, comparable to the concept of Workspace in Notion, Obsidian has the concept of Vault. If two notes in two different vaults are intended to be visible at the same time. Obsidian also allows two windows. But, unlike Notion, there seems to be no way to get two taskbar icons as there is no way to use multiple web browsers. It is an OS thing but also indeed a user experience thing. Is there a way out?
The way out for multiple taskbar icons for disk file-based applications
This is the initial idea why I started this article - because I am thinking about making my own Markdown file-based note app which support multiple notes at the same time as well as mutliple taskbar icons. Combining Notion and Obsidian, I am thinking about to regard Obsidian as the server without the mandatory need of a GUI while Notion as the client which interfaces the notes served by the server. Looks promissing? Yes and no. Thinking as an end user, the biggest uncertainty is the need of an HTTP port for the server to listen to. And there is no garantee that the port is not occupied by another application which has already been running on the user's computer. So the sever still needs a way to get the usable port. And providing the unknown port to the application is not always easy for end users. The best solution I can think of (to now) is that the server or the backend application part also has a GUI to allow user to set a port in case the pre-set port conflicts with another already running application. So the user can still have browser bookmarks to use.
The recommended way of how
The server part of the web
It is also commonly known as the backend part of the web. Cross-platform is the key consideration point. As of today, there has already been quite some technologies which allows cross-desktop-platform web server applications. But as described above, the special need is that the server also needs a GUI to let the end user set the port. What options left? Possibly Java, Python and C#. Because Node.js has no easy GUI and Swift does not work on Windows. Java is great as it is native to web servers, desktop platforms as well as Android, but C# is my favorite for this use.
The client part of the web
It is also commonly known as the frontend part of the web. Cross-platform is still the key consideration point. As of today, there is still not good enough and easy enough way to separate the server and client on mobile platforms. So for basic use, combining the server and client into one on mobile platform would be necessary. What does this mean for the client part? On mobile platforms, the server may not be able to run as headless (GUI-less) service daemon process and the client runs on a standard web browser application. The client needs reside on an in-app webview which is rather limited in my opinon. So the client part is kind of as the embedded client. This is kind of the context setting.
So what in more details? When it is about web client, it is about JavaScript. When it is about JavaScript, it needs more details. Why so? Because JavaScript is just so universal, so popular, and so many variants. Things matter here include the consideration of batteries/libraries to use, as well as general module aspects. JavaScript has web browsers as one runtime as well as Node.js as the other. JavaScript modules have Node.js CommonJS as one big name as well as ESM as the other standard name. ESM comes later and it is not backward compatible. And NPM (initially Node Package Manager) is still be most popular place to share and find modules as library packages. Web client part does not accept CommonJS modules. But there are many great JavaScript modules written primarily for Node.js or distributed as CommonJS modules which also work in web browsers if only the few module definition lines are updated. Personally, I know the CommonJS better than ESM. As CommonJS feels cleaner or lighter. The require('crypto')
or require('./my')
or module.exports
feels just good, not too much or too little. (As I may write source code in TypeScript instead of JavaScript or I can append something like var module = { exports: {} }
in case for backword compatibility.) So what is my recommendation? I value existing things a lot. So I value more about backward compatibility. But I would also like to take use of new endeavors provided by the community. So taking use of compiling or transpiling tools becomes necessary. Unfortunitly, just works is no longer just as easy. Modules just work in web browsers may not just work in Node.js. Even worse, modules just work in web browsers with script[type="module"]
do not work in web browsers with script
with no [type="module"]
. I like Webpack. So I would suggest to write in Webpack-style JavaScript modules and to compile into a single UMD module. What is the Webpack-style modules? Using import ... from 'path'
but better that the path has no extension such as '.js' and distinguish path with ./
or without. (Webpack allows for interop among different module systems.) Also be awere that import ... from
allow one more import than require
which is the default export (workaround as require(...).default
).
For more about the modules, there are the following reference links.
- https://nodejs.org/api/modules.html
- https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
- https://web.dev/articles/es-modules-in-sw
And for modules which work in both web browsers and Node.js. There is also other nuances to be awere, such as crypto
comes as a separated module to require('crypto')
in Node.js but as a global accessor in browsers as window.crypto
or self.crypto
, Buffer
as built-in module in Node.js but not in web browsers. Any idea to unify the use? Maybe, having a pre-running context.js part, porting the global
of Node.js to web browsers as const global = globalThis || window || self
and setting the global.cryto
to require('crypto')
in Node.js.
Or maybe, at last, use multiple modules but always only distribute one single UMD module. Then it is possible for users to use in Node.js just as require('the-one-single-umd-moduel')
and in web browsers as <script src="the-one-single-umd-module"></script>
and it works. The idea also indicates that do not use modules in web browsers, use multiple <script>
and still just one global scope. What best of this way? Web application served with file protocol also works. Which means a web server is not needed. (Which is needed when using script[type="module"]
.)
Some extras
- For modules/libraries
- Webpack for multiple ESM-alike Webpack-style modules into one UMD module
- TypeScript (tsc) for TypeScript (including React JSX) modules to ESM JavaScript modules
- do not use
require()
orimport()
in runtime code as they are runtime/path dependent, but use context.js instead.
- For applications
- choose targetted platforms first and use what are reasonable
- also consider using managed frameworks such as Angular, Create-React-App, Next.js, ASP.NET, Electron and so on (This is just related to this article but not in the scope as it is another totally different way of thinking.)
* cached version, generated at 2024-01-11 04:08:42 UTC.
Subscribe by RSS