<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ourai L.</title>
    <description>The latest articles on DEV Community by Ourai L. (@ourai).</description>
    <link>https://dev.to/ourai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F473938%2F8be773a3-24ff-4ca6-897c-11a48b1fe060.jpeg</url>
      <title>DEV Community: Ourai L.</title>
      <link>https://dev.to/ourai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ourai"/>
    <language>en</language>
    <item>
      <title>I Submitted Two Pull Requests to the Answer Platform</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Fri, 31 Jan 2025 15:45:14 +0000</pubDate>
      <link>https://dev.to/ourai/i-submitted-two-pull-requests-to-the-answer-platform-1c04</link>
      <guid>https://dev.to/ourai/i-submitted-two-pull-requests-to-the-answer-platform-1c04</guid>
      <description>&lt;p&gt;It seems that the OpenBuild community ecosystem project has been on hold for quite some time. The initiator wants to quickly advance it, but there hasn't been much progress so far, and it's hard to find other suitable people for the job—so I had to take it over.&lt;/p&gt;

&lt;p&gt;The project aims to develop a plugin for the open-source Q&amp;amp;A platform &lt;a href="https://answer.dev/" rel="noopener noreferrer"&gt;Answer&lt;/a&gt; that supports login via Web3 wallets. From the perspective of the functionality to be implemented, this should be a relatively small project, with an estimated total of 1.5 to 3 person-days for both front-end and back-end development and integration.&lt;/p&gt;

&lt;p&gt;However, reality has given me a hard time...&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirement Analysis
&lt;/h2&gt;

&lt;p&gt;Initially, based on the &lt;a href="https://answer.dev/docs/development/plugins" rel="noopener noreferrer"&gt;official plugin development documentation&lt;/a&gt;, what we need to build is a &lt;strong&gt;connector-backend plugin&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;With this in mind, I reviewed the code of &lt;a href="https://github.com/apache/incubator-answer-plugins" rel="noopener noreferrer"&gt;several existing connectors&lt;/a&gt; and found that each plugin can only specify one type, and back-end plugins do not directly support UIs—they all redirect to external authorization URLs.&lt;/p&gt;

&lt;p&gt;However, there is no ready-made external authorization URL for Web3 wallet login. To meet the requirement, we might need to develop an additional &lt;strong&gt;router-standard UI plugin&lt;/strong&gt; to create a page that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Displays a "Connect Wallet" button;&lt;/li&gt;
&lt;li&gt;After the wallet is connected, prompts the user to sign:

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Retrieve a nonce from the back-end&lt;/strong&gt;, with the front end providing the wallet address;&lt;/li&gt;
&lt;li&gt;The front end invokes the wallet to get the user's signature;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Call the back-end authorization interface&lt;/strong&gt; after the signature is obtained, with the front end passing the user's signature information and wallet address;&lt;/li&gt;

&lt;li&gt;Return to the main interface upon successful request.&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;The parts in bold above require data interaction with the back-end, meaning we need two back-end APIs.&lt;/p&gt;

&lt;p&gt;The process seems simple, right? And it really is!&lt;/p&gt;

&lt;h2&gt;
  
  
  Development Process
&lt;/h2&gt;

&lt;p&gt;The back-end part was largely completed months ago, with only the front-end interface and integration remaining.&lt;/p&gt;

&lt;p&gt;Since the project is not developed with a front-end and back-end separation, to run it fully, according to the official documentation, I would need to install Docker, a database, and other tools.&lt;/p&gt;

&lt;p&gt;However, I had not installed these on my local machine before, and I have no plans to use them for other projects in the near future. I couldn't justify installing software that I would hardly use, just to save some disk space on my computer.&lt;/p&gt;

&lt;p&gt;Therefore, I decided to first develop the front-end interface layout, styles, and functionality in a pure front-end manner, even though the back-end API requests would fail. Including the time spent reading the documentation and familiarizing myself with the basic plugin mechanism, it took me about 1 person-day to complete.&lt;/p&gt;

&lt;p&gt;I scheduled a full-day integration session with the back-end developer over the weekend, hoping to finalize and deliver the project, but we encountered many setbacks...&lt;/p&gt;

&lt;p&gt;Since I didn't have the back-end environment installed and configured on my local machine, I couldn't follow the normal plugin loading and running process. Some issues that I didn't encounter during the development phase emerged when the back-end developer tried to run the entire process with my code.&lt;/p&gt;

&lt;p&gt;Initially, whenever we encountered a front-end issue, we would start a video call to see how he was operating, and I would guide him on how to solve it. After a few times, I suddenly realized—this is what people call "pair programming"! 😂😂😂&lt;/p&gt;

&lt;p&gt;Later, I thought to myself: "This is not sustainable; it's too inefficient!"&lt;/p&gt;

&lt;p&gt;Eventually, I decided to let go of my hesitation and let him guide me on how to set up the back-end environment so that I could test and adjust the front-end code myself.&lt;/p&gt;

&lt;p&gt;After being guided, I found out that I actually only needed to install Go, and I could use the SQLite database that comes with macOS—no need for Docker at all. I really should have let him be my "navigator" from the beginning!&lt;/p&gt;

&lt;p&gt;Although things didn't go smoothly afterwards, we no longer needed to hold video calls. We could just send a screenshot and a brief description via WeChat whenever we encountered a problem, which greatly improved our efficiency!&lt;/p&gt;

&lt;p&gt;While testing the plugin I developed, I also discovered a bug in the plugin loading mechanism and &lt;a href="https://github.com/apache/incubator-answer/pull/1140" rel="noopener noreferrer"&gt;fixed it with a PR&lt;/a&gt;, earning an extra achievement! 😁😁😁&lt;/p&gt;

&lt;p&gt;After a day or two of final touches, we delivered the plugin. Under the guidance and suggestions of the official reviewer, we merged the original two plugins into one &lt;a href="https://github.com/apache/incubator-answer-plugins/pull/235" rel="noopener noreferrer"&gt;here&lt;/a&gt;—it appears to be a "router-standard UI plugin", but it is also a "connector-backend plugin" in reality.&lt;/p&gt;

&lt;p&gt;In just three to five days, we managed to resolve the "constipation" issue, and it's time to celebrate! 🎉🎉🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  Pitfalls and Experiences
&lt;/h2&gt;

&lt;p&gt;This project was developed based on the main project version &lt;a href="https://github.com/apache/incubator-answer/tree/v1.4.0" rel="noopener noreferrer"&gt;1.4.0&lt;/a&gt;. The incomplete official documentation, the plugin system, and my own somewhat awkward mindset led me to encounter some pitfalls. Below, I share some key points for local debugging for front-end developers to avoid unnecessary detours!&lt;/p&gt;

&lt;p&gt;Firstly, for those who, like me, are concerned about this—&lt;strong&gt;you only need to install Go additionally, and you can use the SQLite database that comes with macOS!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Taking the plugin we developed as an example, let's assume the plugin is named &lt;code&gt;connector-wallet&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Back-end Environment
&lt;/h3&gt;

&lt;p&gt;Ensure that the plugin package is imported in the main project's &lt;code&gt;cmd/answer/main.go&lt;/code&gt;, even if it does not exist yet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;answercmd&lt;/span&gt; &lt;span class="s"&gt;"github.com/apache/incubator-answer/cmd"&lt;/span&gt;

  &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="s"&gt;"github.com/apache/incubator-answer-plugins/connector-wallet"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whether it is a pure front-end plugin or a plugin that appears to be a front-end plugin, when debugging, the code generated by the template should be placed in the &lt;code&gt;ui/src/plugins&lt;/code&gt; folder, and a &lt;code&gt;go.work&lt;/code&gt; file should be created in the root folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go 1.22.0

toolchain go1.23.2

use (
    .
    ./ui/src/plugins/connector-wallet
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;make ui&lt;/code&gt; to build the front-end code, and then compile the back-end code with &lt;code&gt;go build -o answer ./cmd/answer/main.go&lt;/code&gt;, which will generate the &lt;code&gt;answer&lt;/code&gt; file. All subsequent operations will use this file.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;./answer init -C ./answer-data/&lt;/code&gt; to initialize the system. You need to visit &lt;code&gt;http://localhost&lt;/code&gt; in the browser to fill in the information, where the database should be selected as SQLite, and the file storage path should replace &lt;code&gt;/data&lt;/code&gt; with the absolute path of the &lt;code&gt;answer-data&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;./answer run -C ./answer-data/&lt;/code&gt; to start the back-end service. Visit &lt;code&gt;http://localhost&lt;/code&gt; again to log in with the initial account and enable the plugin you want to debug in the back-end!&lt;/p&gt;

&lt;p&gt;Finally, change the &lt;code&gt;REACT_APP_API_URL&lt;/code&gt; in &lt;code&gt;ui/.env.development&lt;/code&gt; to &lt;code&gt;http://localhost:80/&lt;/code&gt;, and you can start the front-end development server to access the back-end API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Front-end Environment
&lt;/h3&gt;

&lt;p&gt;After installing the dependencies, you need to delete several folders in the &lt;strong&gt;plugin folder&lt;/strong&gt; to avoid issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete the &lt;code&gt;dist&lt;/code&gt; folder and the &lt;code&gt;main&lt;/code&gt;, &lt;code&gt;module&lt;/code&gt;, &lt;code&gt;types&lt;/code&gt;, and &lt;code&gt;exports&lt;/code&gt; fields in the &lt;code&gt;package.json&lt;/code&gt;, otherwise the page will render the compiled files, and changes to the source files will not trigger a refresh;&lt;/li&gt;
&lt;li&gt;Delete the &lt;code&gt;node_modules&lt;/code&gt; folder, otherwise the i18n configuration read by the plugin may not be from the main project, possibly due to &lt;code&gt;react-i18next&lt;/code&gt; not using a singleton pattern, resulting in two separate configurations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Publishing the Plugin
&lt;/h3&gt;

&lt;p&gt;If the front-end plugin adds additional dependencies, you need to modify the &lt;code&gt;vite.config.ts&lt;/code&gt; configuration in the plugin package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;cssInjectedByJsPlugin&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vite-plugin-css-injected-by-js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;...,&lt;/span&gt;
    &lt;span class="nf"&gt;cssInjectedByJsPlugin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;    &lt;span class="c1"&gt;// Required when importing style files, otherwise styles will be disordered&lt;/span&gt;
    &lt;span class="p"&gt;...,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...,&lt;/span&gt;
    &lt;span class="na"&gt;rollupOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;...,&lt;/span&gt;    &lt;span class="c1"&gt;// Declare your additional dependencies here&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;globals&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="p"&gt;...,&lt;/span&gt;    &lt;span class="c1"&gt;// Declare your additional dependencies here&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Thank you to OpenBuild for providing this opportunity. Although I was reluctant to take it on at first because I thought there were more important and urgent matters to attend to, time can always be squeezed out if you really want to!&lt;/p&gt;

&lt;p&gt;Thank you to the back-end developer for the great cooperation, which helped us resolve this "constipation" issue that had been lingering for months!&lt;/p&gt;

&lt;p&gt;Thank you to the Answer official reviewers for accompanying me through the PR process and helping me practice my English, which has set a good foundation for my future international development!&lt;/p&gt;

&lt;p&gt;Although I have contributed PRs to several other open-source projects before, they were mostly minor fixes and didn't involve much communication before being merged. This contribution to Answer truly gave me the feeling of being part of an open-source community!&lt;/p&gt;

&lt;p&gt;Salute to all OPEN SOURCERORs!!!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Front-end Shovel 💩 Diary #3: Refactoring the "Personal Profile"</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Fri, 31 Jan 2025 04:41:51 +0000</pubDate>
      <link>https://dev.to/ourai/front-end-shovel-diary-3-refactoring-the-personal-profile-j53</link>
      <guid>https://dev.to/ourai/front-end-shovel-diary-3-refactoring-the-personal-profile-j53</guid>
      <description>&lt;p&gt;Hey, Folks! From this note onwards, we’re diving into the actual code refactoring exercises!&lt;/p&gt;

&lt;p&gt;The first piece of code that needs refactoring is in the user’s personal profile page, which I encountered when I took over the official website project.&lt;/p&gt;

&lt;p&gt;In this system, users are divided into two types: individuals and project sponsors. Although their personal profiles look similar, there are differences in visual details and data structures. The layout structure of the profile page is roughly as shown in the figure below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F462r9630sykiyauaaquq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F462r9630sykiyauaaquq.jpg" alt="Profile Page Layout" width="800" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The original code for the personal profile page was somewhat modular in other parts, but the most important sections, such as courses and activities, were all crammed into a single React component. It looked like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxw9h2my0pe8zu0a3iwur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxw9h2my0pe8zu0a3iwur.png" alt="Code with Hidden " width="800" height="1000"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code was messy and disorganized, making it difficult to discern the purpose of each section. Therefore, the refactoring approach was clear—split and encapsulate.&lt;/p&gt;

&lt;p&gt;Based on the display of the personal profile page and the overall functionality of the website, I first divided the &lt;code&gt;domain&lt;/code&gt; into four modules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bounty&lt;/code&gt; for bounty tasks;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;challenge&lt;/code&gt; for online and offline activities;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;course&lt;/code&gt; for online courses;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;quiz&lt;/code&gt; for quizzes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I then encapsulated the code for each list rendering in the personal profile page into list view components and placed them in the corresponding modules. The data requests were also encapsulated into asynchronous functions and placed in the &lt;code&gt;repository.js&lt;/code&gt; of each module:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F439u482ymyan1y74acqp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F439u482ymyan1y74acqp.png" alt="Refactored Directory Structure" width="756" height="1574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the interaction logic for each list was consistent—clicking “More” to load the next page—I further encapsulated a generic &lt;code&gt;LoadableList&lt;/code&gt; component and placed it in the &lt;code&gt;shared/components&lt;/code&gt; folder. This made the list view code much cleaner and more concise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LoadableList&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/loadable-list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchEnrolledCourseList&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../repository&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;EnrolledCourseItem&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./EnrolledCourseItem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;EnrolledCourseList&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;series&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;EnrolledCourseItem&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`course-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;series&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;EnrolledCourseListView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LoadableList&lt;/span&gt;
      &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fetchEnrolledCourseList&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;resolveResponse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;})}&lt;/span&gt;
      &lt;span class="nx"&gt;renderList&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;EnrolledCourseList&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;    &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;EnrolledCourseListView&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I encapsulated the logic for switching between list views into &lt;code&gt;ActivityTabList&lt;/code&gt; and declaratively passed the array of list views to it. The refactored personal profile page code looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;EnrolledCourseListView&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../course/views/enrolled-course-list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;EnrolledChallengeListView&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../challenge/views/enrolled-challenge-list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AppliedBountyListView&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../bounty/views/applied-bounty-list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AnsweredQuizListView&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../../quiz/views/answered-quiz-list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ActivityTabList&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../widgets/activity-tab-list&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// List view declarations&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Course&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;view&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EnrolledCourseListView&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Challenge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;view&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EnrolledChallengeListView&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bounty&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;view&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AppliedBountyListView&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Quiz&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;view&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AnsweredQuizListView&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;IndividualProfileView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pl-[410px] pb-14 pr-14&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ActivityTabList&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;IndividualProfileView&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The relative paths are used because a new &lt;code&gt;profile&lt;/code&gt; module was added under &lt;code&gt;domain&lt;/code&gt; to handle personal profile-related functions, and files within the same &lt;code&gt;domain&lt;/code&gt; are constrained to use relative paths.&lt;/p&gt;

&lt;p&gt;Finally, the original code in the &lt;code&gt;app&lt;/code&gt; directory was changed to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#/domain/profile/views/individual-profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, the core code related to the personal profile was successfully moved from &lt;code&gt;app&lt;/code&gt; to &lt;code&gt;domain&lt;/code&gt;, completing the first code refactoring exercise!&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>refactorit</category>
    </item>
    <item>
      <title>Front-end Shovel 💩 Diary #2: The Easily Overlooked "domain"</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Thu, 30 Jan 2025 20:31:04 +0000</pubDate>
      <link>https://dev.to/ourai/front-end-shovel-diary-2-the-easily-overlooked-domain-1epk</link>
      <guid>https://dev.to/ourai/front-end-shovel-diary-2-the-easily-overlooked-domain-1epk</guid>
      <description>&lt;p&gt;If you've read &lt;a href="https://dev.to/ourai/front-end-shovel-diary-1-project-directory-structure-adjustment-136g"&gt;the previous note&lt;/a&gt;, the keen-eyed among you might have noticed that the &lt;code&gt;domain&lt;/code&gt; folder mentioned in the directory restructuring plan did not appear in the final refactoring results.&lt;/p&gt;

&lt;p&gt;This is because domain modeling is a relatively challenging task that requires long-term effort and careful consideration. So, we don't rush it. Starting from this note, we will delve into related content.&lt;/p&gt;

&lt;p&gt;Before diving into the actual refactoring exercise, this note will first explain the importance of the &lt;code&gt;domain&lt;/code&gt; folder. Please grab your seats and pay attention as I explain.&lt;/p&gt;

&lt;p&gt;In the modular directory structure I designed, there are three core top-level folders: &lt;code&gt;shared&lt;/code&gt;, &lt;code&gt;domain&lt;/code&gt;, and &lt;code&gt;entry&lt;/code&gt;, each serving the following purposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;shared&lt;/code&gt;: Contains universally used assets, styles, and functions that have no business logic and are applicable throughout the entire application.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;domain&lt;/code&gt;: Houses assets, styles, and functions related to specific business logic, without being restricted by the development framework or page routing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;entry&lt;/code&gt;: Serves as the application's initialization and page rendering "entry point", which is constrained by the development framework and page routing mechanisms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;domain&lt;/code&gt; folder is the cornerstone of this structure—most of the application's logic resides here, making it crucial. In contrast, the other two folders are relatively lightweight, especially the &lt;code&gt;entry&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Since the official website project I inherited uses Next.js, its prescribed &lt;code&gt;app&lt;/code&gt; folder serves as the &lt;code&gt;entry&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Many front-end developers have a superficial understanding of "modularization", thinking that simply moving a piece of code into another file and referencing it elsewhere (e.g., encapsulating utility functions or UI components) constitutes modularization. While this approach has some benefits, it doesn't significantly enhance application development. Modularizing business logic is where the real power lies—this is where domain modeling comes in, a skill that many front-end developers lack.&lt;/p&gt;

&lt;p&gt;The subfolders within the &lt;code&gt;domain&lt;/code&gt; folder represent abstracted business modules, each strictly adhering to the principles of "high cohesion and low coupling". Each module contains only code related to its own business logic, with clear semantic declarations of dependencies on other business modules.&lt;/p&gt;

&lt;p&gt;The directory structure of a business module typically looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6ct19u9784g6fip1h3h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6ct19u9784g6fip1h3h.jpg" alt="Directory structure of the  raw `domain` endraw  folder" width="800" height="532"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If, like in most projects, files are indiscriminately thrown into global folders such as &lt;code&gt;services&lt;/code&gt; or &lt;code&gt;components&lt;/code&gt; without any abstraction, the most immediate problem encountered is the need to sift through numerous subfolders to identify the files that need modification. This process must be repeated every time you switch between different categories of folders, making it difficult to focus and severely impacting efficiency.&lt;/p&gt;

&lt;p&gt;This is because organizing files by category forcibly disassembles files that are closely related from a business perspective—it's like breaking up a pair of lovebirds!&lt;/p&gt;

&lt;p&gt;Without abstracting and reusing modules based on business logic, the dependencies between UI components and pages can easily become extremely convoluted, eventually turning into an intractable mess that further affects development efficiency and application quality.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;domain&lt;/code&gt; folder in my modularization model is the perfect remedy for this issue, acting like different-colored cable ties that neatly organize and constrain the "wires", bringing order to the entire application.&lt;/p&gt;

&lt;p&gt;Moreover, ideally, each business module within the &lt;code&gt;domain&lt;/code&gt; folder can be reused in different applications—just like general-purpose modules installed via npm!&lt;/p&gt;

&lt;p&gt;What do you think? Have you grasped the benefits of the modularization model and the importance of the &lt;code&gt;domain&lt;/code&gt; folder?&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Front-end Shovel 💩 Diary #1: Project Directory Structure Adjustment</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Thu, 30 Jan 2025 13:07:03 +0000</pubDate>
      <link>https://dev.to/ourai/front-end-shovel-diary-1-project-directory-structure-adjustment-136g</link>
      <guid>https://dev.to/ourai/front-end-shovel-diary-1-project-directory-structure-adjustment-136g</guid>
      <description>&lt;p&gt;Recently, I took over a front-end project for an official website. Although it's called a website, it's actually a web application rather than a marketing site, so it does have a certain level of complexity.&lt;/p&gt;

&lt;p&gt;These past few days have been a whirlwind of debugging and getting familiar with the code logic. I didn't expect it to be such a hot potato. The previous developer left me a mess—frankly, I don't think they were much more than intermediate level. 😖&lt;/p&gt;

&lt;p&gt;You might think I'd be overwhelmed and frustrated by this pile of mess, with my mind racing like a herd of horses across the Hulunbuir Grasslands. But no! You're mistaken! In fact, I'm quite excited!&lt;/p&gt;

&lt;p&gt;Don't get me wrong—I'm not some kind of masochist. It's just that projects like this are like touchstone tests, proving my worth as a true gem, a hidden treasure, and the ultimate myth—after all, I'm a seasoned "front-end poop shoveler"! 😄&lt;/p&gt;

&lt;p&gt;Alright, enough with the backstory. Let's get down to business.&lt;/p&gt;

&lt;p&gt;This official website project is built with Next.js, and its directory structure is pretty standard, offering little constraint for development and maintenance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felffup6fpwdn467qc53d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felffup6fpwdn467qc53d.png" alt="Before Directory Structure" width="800" height="849"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The core issue with the project is the lack of abstraction. The code is like a jumbled mess of cables in an unorganized server room, with poor reusability and maintainability.&lt;/p&gt;

&lt;p&gt;What about robustness? What's that?&lt;/p&gt;

&lt;p&gt;I once wrote an article titled "&lt;a href="https://dev.to/ourai/patterns-of-directory-structure-in-front-end-projects-3gob"&gt;Patterns of Directory Structure in Front-end Projects&lt;/a&gt;". The directory structure of this project, like most front-end projects, falls into the "wild" category mentioned in the article—it's part of the problem!&lt;/p&gt;

&lt;p&gt;As I mentioned at the beginning, this project is a web application, which means it can largely benefit from domain modeling. This also implies that if I want to clean up this mess, the first step is to reorganize the directory structure using a "modular" approach, similar to the annual organizational restructuring at a company.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvy30j278qpwndg3jmxdc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvy30j278qpwndg3jmxdc.jpg" alt="Proposed Directory Structure Change" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Due to the limitations of Next.js, the &lt;code&gt;app&lt;/code&gt; folder must replace the &lt;code&gt;entry&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Ideally, apart from the &lt;code&gt;app&lt;/code&gt; folder, the &lt;code&gt;shared&lt;/code&gt; and &lt;code&gt;domain&lt;/code&gt; folders should be free from Next.js constraints and will carry the bulk of the application's logic—always ready to break free from Next.js's grasp! 😜😜😜&lt;/p&gt;

&lt;p&gt;The ideal is full, but the reality is quite 💀.&lt;/p&gt;

&lt;p&gt;Since this project is plagued with issues, it can't be fixed all at once. After today's refactoring, I had to leave some remnants for now, but I'll eliminate them one by one in the coming days!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feh6kj57sfti3nhkvitr3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feh6kj57sfti3nhkvitr3.jpg" alt="Directory Structure After Refactoring" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it looks much cleaner and more organized. I'm feeling great! 😄😁😆&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Abandon Web2 and Join Web3</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Thu, 30 Jan 2025 05:37:34 +0000</pubDate>
      <link>https://dev.to/ourai/abandon-web2-and-join-web3-46k3</link>
      <guid>https://dev.to/ourai/abandon-web2-and-join-web3-46k3</guid>
      <description>&lt;p&gt;The titles of my previous articles, "&lt;a href="https://dev.to/ourai/web3-is-the-future-for-front-end-engineers-part-1-3o3k"&gt;Web3 is the Future for Front-end Engineers Part 1&lt;/a&gt;" and "&lt;a href="https://dev.to/ourai/web3-is-the-future-for-front-end-engineers-part-2-4n35"&gt;Web3 is the Future for Front-end Engineers Part 2&lt;/a&gt;", might seem sensationalist, and some have accused me of clickbait. However, these articles are about my personal journey of transitioning to becoming a Web3 full-stack engineer. The phrase "Web2 is the End, Web3 is the Future" reflects my personal experience and choice, not a summary of the industry or advice for others—this article is the opposite.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web2 is the End
&lt;/h2&gt;

&lt;p&gt;After reading those two articles, some people commented, "You never explained why Web2 is the end". Indeed, those articles were mainly about my personal experience and not career advice for the industry.&lt;/p&gt;

&lt;p&gt;Additionally, I had previously expressed my views on "Web2 being outdated" more comprehensively. There was a small part in "&lt;a href="https://dev.to/ourai/the-last-advice-to-front-end-engineers-42kk"&gt;The Last Advice to Front-end Engineers&lt;/a&gt;", and more details were in a paid column article titled "What Kind of Job Should I Look For?".&lt;/p&gt;

&lt;p&gt;To ensure the coherence and completeness of this series of articles, I am now sharing the main content from the paid article, further refined below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supply and Demand Mismatch
&lt;/h3&gt;

&lt;p&gt;Last Mid-Autumn Festival, while I was idly chatting with my friend, I opened BOSS Zhipin to check out job opportunities. I set a higher expected monthly salary range and specified my areas of expertise. To my surprise, the usual abundance of basic coding positions had mostly disappeared. Instead, I saw job titles like Web IDE Development, Senior Electron Development, Front-end Technology Director, and Front-end Team Leader—more advanced positions.&lt;/p&gt;

&lt;p&gt;Their combined monthly salary range was approximately 35k to 70k, which sounded great! However, upon seeing the job requirements, I realized I didn't meet them.&lt;/p&gt;

&lt;p&gt;Some people complain about the difficulty of finding jobs, citing saturated demand, while others lament the difficulty of hiring, saying that suitable candidates are rare. At that moment, I truly understood the contradictions and gaps between these two perspectives.&lt;/p&gt;

&lt;p&gt;In the conventional job market, I found myself in an awkward position—neither suitable for basic coding roles (which would be an underutilization of my skills and thus not cost-effective for employers) nor qualified to lead a large-scale team.&lt;/p&gt;

&lt;p&gt;This was one aspect of the problem I faced when job hunting. The other aspect was the issue of career prospects, which affects the stability of job positions, companies, and industries (i.e., their lifecycle).&lt;/p&gt;

&lt;h3&gt;
  
  
  Is Front-end Dead?
&lt;/h3&gt;

&lt;p&gt;When I was organizing a topic on front-end engineering, I emphasized in the introduction—&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A 'front-end engineer' is a 'software engineer' who primarily uses Web front-end technologies such as HTML, CSS, and JavaScript to solve problems related to web pages or web-based applications. If someone uses Canvas, WebGL, and other technologies for drawing or game development, they have already stepped beyond the conventional scope of 'Web front-end.' Their knowledge system focuses more on computer graphics, which is not within the scope of this topic".&lt;/p&gt;

&lt;p&gt;—Ourai, Front-end Engineer's Self-cultivation&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a Zhihu Q&amp;amp;A about Yu Bo's resignation, Tang Zhu mentioned—&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A new era is coming, driven by AI, with significant upgrades in technological productivity, major reconstructions in product expression, and reshaping of business models. As one of the functions of technical implementation, front-end engineering will also enter a new era. The value of the user experience technology carried by front-end will be more widely recognized and become a basic consensus among people.&lt;/p&gt;

&lt;p&gt;Yu Bo was ahead of his time in cognition, founded, and successfully built Ant Group's Experience Technology Department. The achievements in concepts, products, teams, influence, and business value are substantial.&lt;/p&gt;

&lt;p&gt;Yu Bo became famous in front-end and achieved a lot in terms of technical products and the Experience Technology Department. In the next industry cycle, I believe Yu Bo still has the ability, space, and sufficient talent to make something better and promote change, succeeding in business and commerce.&lt;/p&gt;

&lt;p&gt;However, the so-called 'problems' of front-end are mostly due to limited cognition. In the new era driven by AI productivity, the new challenges of interaction and user experience delivery may just be the beginning of the 'front-end's' brilliance. This definitely does not mean that it will continue to be fully contained within the familiar 2D web pages in browsers".&lt;/p&gt;

&lt;p&gt;—Tang Zhu, &lt;a href="https://www.zhihu.com/question/596336458/answer/3001729216" rel="noopener noreferrer"&gt;How to View Yu Bo's Resignation from Ant Experience Technology Department?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Combining these two perspectives, I was reminded of the heated debate about "front-end engineering being dead" last year.&lt;/p&gt;

&lt;p&gt;I had expressed my views on this topic in 2020 in a Zhihu question, "&lt;a href="https://www.zhihu.com/question/392501126/answer/1208792987" rel="noopener noreferrer"&gt;Does Front-end Have a Future?&lt;/a&gt;", and later wrote a more detailed article titled "&lt;a href="https://dev.to/ourai/does-front-end-development-have-a-future-5317"&gt;Does Front-end Development Have A Future?&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;A year later, I added some more thoughts—&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"In 5 to 10 years, there will be a significant number of tool-like job positions in Web development that become obsolete. The entry barrier will be higher, and salaries and growth rates will be lower. People who have been in the industry for more than six years should be able to sense this.&lt;/p&gt;

&lt;p&gt;This profession is already on a downward trend. It's time to consider what you will do in 5 to 10 years and try to change direction and switch tracks as soon as possible.&lt;/p&gt;

&lt;p&gt;I want to say that—Web development-related professions, such as front-end engineers and Java engineers, are nearing their end. It doesn't mean there will be no jobs, but they will become increasingly difficult to find and will pay less, moving further away from the term 'high-paying.'&lt;/p&gt;

&lt;p&gt;Twenty years ago, China entered the PC Internet era; ten years ago, China and the world entered the mobile Internet era. During these two decades, with the rapid growth of various Internet companies, China's economy quickly rose and soared, catching up with and surpassing other countries.&lt;/p&gt;

&lt;p&gt;However, at this stage, many things are in a plateau phase. In ten years, no matter how the form of the Internet changes, Web development will not cause much of a stir and will have little to do with it.&lt;/p&gt;

&lt;p&gt;Currently, the future lies in data intelligence, mixed reality, graphical technology, computing combined with biology/life sciences, and some infrastructure areas. Relatively speaking, Web development is just some 'bricklayer' work.&lt;/p&gt;

&lt;p&gt;Any tool-like thing (such as technology, service, etc.) has a shelf life, so maximizing the benefits and value they generate is crucial.&lt;/p&gt;

&lt;p&gt;I've shared the basic points I've thought of, and whether you can use them is up to you—&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Access to first-hand information and a keen sense of smell—being one or even N steps ahead of most people in understanding the development of the world and the challenges you may face, as well as potential money-making opportunities;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rapid learning ability—reducing the time cost of mastering new tools and saving more time to gain value;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A discerning eye for finding applicable and landing scenarios for tools—quickly and vigorously promoting them to get promoted, get a raise, and make money;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Try to expand as much as possible—increasing and extending profits;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start the next cycle."&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;—Ourai's Thoughts&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The section "A Bit of Reflection" in the article "The Second Year of My Three-Year Journey" further refined the above views and echoed this year's "&lt;a href="https://dev.to/ourai/the-last-advice-to-front-end-engineers-42kk"&gt;The Last Advice to Front-end Engineers&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;Later, I reviewed the articles and ideas mentioned above, as well as Zenany's article "&lt;a href="https://www.yuque.com/zenany/up/the_future_frontend" rel="noopener noreferrer"&gt;The Future of Front-end&lt;/a&gt;" written in 2019, trying to find entry points for job hunting.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Cycle of Technology
&lt;/h4&gt;

&lt;p&gt;Whether it is Zenany's "&lt;a href="https://www.yuque.com/zenany/up/the_future_frontend" rel="noopener noreferrer"&gt;The Future of Front-end&lt;/a&gt;", my "&lt;a href="https://dev.to/ourai/does-front-end-development-have-a-future-5317"&gt;Does Front-end Development Have A Future?&lt;/a&gt;", or Tang Zhu's answer on Zhihu, they all indicate that "front-end has a future", but this "front-end" is not the same as the traditional "front-end"—&lt;/p&gt;

&lt;p&gt;If you cling to the "traditional Web front-end" represented by HTML, CSS, and JS, it will not have a future in the long run. However, the "front-end" that aims to "solve human-computer interaction problems" and "provide a good user experience" does have a future.&lt;/p&gt;

&lt;p&gt;The difference between these two "front-ends" lies in the fact that the former is bound to HTML, CSS, and JS, which are frequently used in development; while the&lt;br&gt;
 latter's connotation is dynamic and can be the old trio, WebGL, or even something completely unrelated to Web.&lt;/p&gt;

&lt;p&gt;For example, the "front-end" involved in digital twins, immersive technologies, and smart spaces has almost nothing to do with the "traditional Web front-end".&lt;/p&gt;

&lt;p&gt;If we follow the 15-year cycle of front-end development mentioned in Tang Zhu's answer (2008–2023), it is clear that the "traditional Web front-end" is currently in a period of decline and doesn't have many years left to "live".&lt;/p&gt;

&lt;p&gt;What will the "next generation" of "front-end" be specifically in terms of technology? How long will its lifecycle be? Will it be as enduring as the "traditional Web front-end"?&lt;/p&gt;

&lt;p&gt;Additionally, generational transitions do not occur separately but simultaneously, with few people noticing; by the time most people become aware and take action, it may already be too late to get in on the ground floor.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Cycle of Domains
&lt;/h4&gt;

&lt;p&gt;These articles also suggest that "front-end" can develop in both the production and commercial fields—improving efficiency and reducing costs in the former, and expanding territory and generating revenue in the latter.&lt;/p&gt;

&lt;p&gt;As software engineering theories become more refined, the problems encountered when using new technologies and tools can easily be solved by drawing on existing knowledge and experience (across boundaries).&lt;/p&gt;

&lt;p&gt;Thus, the "spiral" in the "spiral upward" will spin faster and faster, to the point where it doesn't matter whether it's a spiral or not—similar problems keep recurring, and as long as the models and patterns for solving problems remain unchanged, improvements in technology and tools will be meaningless.&lt;/p&gt;

&lt;p&gt;In other words, the ceiling for efficiency and optimization is becoming easier to reach.&lt;/p&gt;

&lt;p&gt;The commercial field is similar—commerce is based on human nature, which has not changed much in thousands of years. It's just that with the emergence of new technologies, everything existing has been redone once again—another "spiral upward".&lt;/p&gt;

&lt;p&gt;Of course, there are a few "exceptions", such as the advent of electrical appliances and computers, which are "singularity" events.&lt;/p&gt;

&lt;p&gt;From past experience, it's hard to say which cycle is longer between production and commerce, but the decline of the production field may accompany the decline of a specific technology—"if the 'traditional Web front-end' is no longer used, why bother with its infrastructure?"&lt;/p&gt;

&lt;h4&gt;
  
  
  The Limitations of Articles
&lt;/h4&gt;

&lt;p&gt;These articles are written from a macro perspective and offer advice for a broad audience. For a specific individual, the reference value may be limited—just as with the societal issue of "old jobs disappearing and new ones emerging".&lt;/p&gt;

&lt;p&gt;Take me, for example. I am older and at a generational transition point. The technologies I am proficient in are from the "old era", while the specific technologies of the "new era" are still unclear, with high learning barriers and long cycles to reach a workable level.&lt;/p&gt;

&lt;p&gt;From the perspective of employers, they tend to hire people with practical work experience and proven results. As someone who has just "switched careers", should I be an intern? If they are hiring interns, why not choose someone who is both young and obedient?&lt;/p&gt;

&lt;h2&gt;
  
  
  Web3 is the Destination
&lt;/h2&gt;

&lt;p&gt;To summarize the above briefly—&lt;/p&gt;

&lt;p&gt;The mainstream human-computer interaction technology in the future is likely no longer HTML, CSS, and JS. Even if it is still them, it will no longer be important or will be unrecognizable compared to now, equivalent to learning new technologies and mastering more hardcore foundational knowledge such as computer graphics.&lt;/p&gt;

&lt;p&gt;The knowledge related to new technologies has a high learning threshold, and it takes a long cycle to reach a workable level; it is unclear how long the generational transition will take, but it should only be a few years. The sooner you step into the "new era", the better.&lt;/p&gt;

&lt;p&gt;In recent years, the growth of the traditional Internet industry has been lackluster, as everyone can see. Most front-end engineers are proficient in the "old era" technology of "traditional Web front-end" and work in business-oriented companies.&lt;/p&gt;

&lt;p&gt;If you still limit your vision to Web2, from the perspective of the technology cycle and the cycles of production and commerce, the future is easily foreseeable and only has a few years left to "live". Although working for a technology-oriented company is not a bad choice and can prolong the status quo for a while, this option is only available to a minority of technical elites and has little to do with the vast majority of business front-end developers whose technical skills are not advanced.&lt;/p&gt;

&lt;p&gt;For these front-end engineers, especially those who have been in the industry for more than five years, the "traditional Web front-end" technology, which is from the "old era", has become a historical burden that is hard to shake off. Continuing to stay in Web2 will soon lead to the end of their career paths.&lt;/p&gt;

&lt;p&gt;In "&lt;a href="https://dev.to/ourai/questioning-web3-understanding-web3-c5p"&gt;Questioning Web3, Understanding Web3&lt;/a&gt;", I provided a detailed description of my understanding of "Web3". Anyone who is not foolish can see that even with only the "traditional Web front-end" skills, it is quite smooth to transition from Web2.&lt;/p&gt;

&lt;p&gt;Moreover, given the current stage of Web3 industry development, it can extend the career lifeline of front-end engineers who rely on "traditional Web front-end" by at least another ten years. Calling Web3 the "destination" for these engineers is not an exaggeration, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Since I started writing articles about Web3, some people have commented that decentralization, blockchain, and Web3 are illegal. When asked to cite specific laws and regulations, they fall silent.&lt;/p&gt;

&lt;p&gt;I would like to ask: "In China, blockchain technology is applied by government agencies and major Internet companies. Are they openly breaking the law? Or are they simply unaware of the law?"&lt;/p&gt;

&lt;p&gt;The wise adapt to the times, and the clever adapt to the situation.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>web3</category>
    </item>
    <item>
      <title>Questioning Web3, Understanding Web3</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Wed, 29 Jan 2025 05:58:09 +0000</pubDate>
      <link>https://dev.to/ourai/questioning-web3-understanding-web3-c5p</link>
      <guid>https://dev.to/ourai/questioning-web3-understanding-web3-c5p</guid>
      <description>&lt;p&gt;When you hear the term "Web3", what comes to mind?&lt;/p&gt;

&lt;p&gt;Judging from the comments on my first two articles, most people leave messages like "jail" and "rug-pulling", indicating that they don't understand Web3 and that it has been severely demonized.&lt;/p&gt;

&lt;p&gt;It is reasonable and necessary to question Web3, as any concept should be scrutinized to get closer to its essence. However, the comments I see are not questions but rather prejudiced discrimination.&lt;/p&gt;

&lt;p&gt;This article aims to explain my understanding of Web3 and to set the record straight.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Decentralization?
&lt;/h2&gt;

&lt;p&gt;Being a content creator is one of my many roles. Although I have a personal website that I've been running for over a decade, in today's world, if I want my content to reach a larger audience, I have no choice but to rely on the potential traffic from content platforms.&lt;/p&gt;

&lt;p&gt;For content creators, the most frustrating thing is not having anyone view the content they've put their heart into. If it's due to a lack of skill, that's acceptable. But what if it's because the content platform has throttled it or made it visible only to the author?&lt;/p&gt;

&lt;p&gt;The system notifications received after such actions are often vague, like "Your content does not comply with the rules", without any clear indication of which specific rule was violated.&lt;/p&gt;

&lt;p&gt;What's even more unreasonable is the lack of an effective appeal process—either there is no appeal entry point at all, or appeals are ignored, or they are handled in a perfunctory manner. In front of content platforms, do creators have any dignity?&lt;/p&gt;

&lt;p&gt;This is just one example of the many issues I and others have encountered, and their commonality is that centralized platforms struggle to achieve maximum fairness, mainly because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Power is concentrated in the hands of the operators, with no external participation in decision-making;&lt;/li&gt;
&lt;li&gt;Platform rules are not detailed enough, with many vague terms creating a large gray area for arbitrary interpretation and manipulation;&lt;/li&gt;
&lt;li&gt;The process of handling user-generated content is not transparent, and there is a lack of a user supervision system;&lt;/li&gt;
&lt;li&gt;The feedback mechanism for reporting and appealing is very flawed, making it extremely complex to defend one's rights, and sometimes even impossible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The relationship between users and centralized platforms is not entirely adversarial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Platforms can have their own rules and punish users when they violate them, which is reasonable;&lt;/li&gt;
&lt;li&gt;Platforms can have imperfect rules but should be open to improvement when users raise valid objections, rather than being arbitrarily domineering;&lt;/li&gt;
&lt;li&gt;Users generate data for the platform, and the platform provides traffic or other value to the users—it should be a win-win situation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, as mentioned above, centralized platforms often fail to achieve these seemingly simple goals, leaving users' rights poorly protected. This leaves users with only three options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Leave directly;&lt;/li&gt;
&lt;li&gt;Try to appeal in a last-ditch effort;&lt;/li&gt;
&lt;li&gt;Continue to endure endless humiliation until it becomes unbearable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No matter which option is chosen, the likely outcome is "leaving".&lt;/p&gt;

&lt;p&gt;But then what? Do you stop doing what you were doing? Or do you switch to another similar centralized platform? Is that platform likely to better protect user rights?&lt;/p&gt;

&lt;p&gt;A truly people-oriented digital service should look something like what I described in A Brief Introduction to Individual-Centered Services.&lt;/p&gt;

&lt;p&gt;Ultimately, those who value their rights and have ideas will turn their attention to "decentralized" platforms, seeing them as a lifeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Decentralize
&lt;/h2&gt;

&lt;p&gt;When we talk about "decentralization", it is essential to clarify what exactly is being decentralized, such as data ownership, data control, computing methods, communication methods, etc. Otherwise, the conversation will be like comparing apples and oranges.&lt;/p&gt;

&lt;p&gt;Some people advocate absolute decentralization, but this is as unrealistic as wanting absolute freedom or egalitarianism—it's wishful thinking.&lt;/p&gt;

&lt;p&gt;Decentralization relies on a distributed network structure, where nodes in the network can communicate directly with each other without going through a central node that has control. That central node is the "center".&lt;/p&gt;

&lt;p&gt;Some may wonder—without a "center" to command and coordinate, wouldn't the nodes in the network be in chaos? How can they communicate and collaborate?&lt;/p&gt;

&lt;p&gt;Setting aside computer networks for a moment, let's look at how humans do it.&lt;/p&gt;

&lt;p&gt;Human communication relies on symbols, language, and other means of conveying information. The same unit of information can have different meanings in different systems. Only when two people are in the same system can they communicate, such as both speaking Chinese.&lt;/p&gt;

&lt;p&gt;So, how do human individuals work together in the same direction without a commander? There are probably several ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The culture, traditions, and customs of civilizations and ethnic groups;&lt;/li&gt;
&lt;li&gt;National laws and regulations;&lt;/li&gt;
&lt;li&gt;Organizational rules and regulations;&lt;/li&gt;
&lt;li&gt;Tacit understanding developed through interaction.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the consensuses or rules that participants agree to follow, using consistent rules to restrain and coordinate the actions of each individual to complete a specific task.&lt;/p&gt;

&lt;p&gt;In summary, "the same medium system" and "consistent rules of action" are the keys to achieving "decentralization"!&lt;/p&gt;

&lt;p&gt;Shifting back to the field of computers, "the same medium system" refers to data types and encoding, while "consistent rules of action" refer to protocols and standards.&lt;/p&gt;

&lt;p&gt;Also, as mentioned earlier, absolute "decentralization" does not exist—within an overall distributed network, one of the nodes may also be a smaller network with a "center".&lt;/p&gt;

&lt;h2&gt;
  
  
  The Evolution of the Web
&lt;/h2&gt;

&lt;p&gt;People's digital lives today are inseparable from the Web, whether browsing web pages or using native client applications.&lt;/p&gt;

&lt;p&gt;Since its inception in 1989, Web-related technologies have developed rapidly to meet various needs, and its current direction of development has somewhat deviated from the expectations of its inventors.&lt;/p&gt;

&lt;p&gt;In these 35 years, due to changes in the way people use it in production and life and the shifts in ideological trends, there have been some concentrated characteristics every few years, which are used to divide periods and are named with an incrementing number after "Web".&lt;/p&gt;

&lt;p&gt;Many materials introducing Web3 describe it as "Web 3.0" or compare it with "Web 1.0" and "Web 2.0" at the same level—as someone who is sensitive to wording, I find it hard to agree.&lt;/p&gt;

&lt;p&gt;Replacing the number representing "generation" with "X", there are two forms of wording: "Web X.0" and "WebX", and they have very different meanings.&lt;/p&gt;

&lt;p&gt;Generations do not replace each other but coexist. Whichever one is more dominant becomes the "mainstream", and the less dominant ones do not disappear completely but are "neglected".&lt;/p&gt;

&lt;h3&gt;
  
  
  Web X.0
&lt;/h3&gt;

&lt;p&gt;The Web was invented by Tim Berners-Lee at CERN, initially for the purpose of sharing documents and data primarily in text and image formats on the Internet, with a natural "decentralized" gene, where one's computer could serve as a server.&lt;/p&gt;

&lt;p&gt;At that time, CSS and JS had not yet appeared, let alone PHP and Java. Web pages were not only completely static and non-interactive but also very plain—just like people's thoughts at the time—simply for knowledge sharing.&lt;/p&gt;

&lt;p&gt;With the emergence of supporting technologies that made web pages more visually appealing and dynamic in various senses, web pages began to develop towards personalization and commercialization, giving rise to a variety of personal and commercial websites and bringing vitality to the Web.&lt;/p&gt;

&lt;p&gt;Around 2004, the mainstream application form of the Web shifted towards socialization and platformization, with a flood of SNS and XaaS products that occupied every aspect of people's daily production and life. The platform side gained control over a large number of users and data, with its commercial value rising accordingly.&lt;/p&gt;

&lt;p&gt;Taking around 2004 as a dividing line, the application form of the Web before that was mainly information publishing content websites, where the content was "read-only" for users, known as "Web 1.0".&lt;/p&gt;

&lt;p&gt;After that, the application form of the Web became more about user participation in content creation and sharing interactions through platform services, that is, "read-write", known as "Web 2.0". At this time, there was a clear centralization feature, which contradicted the original intention of the Web.&lt;/p&gt;

&lt;p&gt;The above is a periodization based on the application form of the Web. As the inventor of the Web, Tim Berners-Lee does not agree with this. In &lt;a href="https://www.w3.org/DesignIssues/" rel="noopener noreferrer"&gt;his notes&lt;/a&gt;, he divides it from the perspective of technological development and problem-solving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web 1.0—Creating a global web of documents and data;&lt;/li&gt;
&lt;li&gt;Web 2.0—Enhancing the security of information access;&lt;/li&gt;
&lt;li&gt;Web 3.0—Building a semantic web to improve data interoperability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among them, "Web 3.0" is to use a series of protocols, standards, and technologies to transform web content into structured data that is easily readable and understandable by machines, turning the entire Web into a vast knowledge graph and intelligent network.&lt;/p&gt;

&lt;p&gt;The "Web 3.0" conceived by Tim Berners-Lee can be applied in a decentralized manner to fields such as knowledge engineering, artificial intelligence, the Internet of Things, and social networks.&lt;/p&gt;

&lt;h3&gt;
  
  
  WebX
&lt;/h3&gt;

&lt;p&gt;In the Web as conceived by Tim Berners-Lee, "decentralization" is natural and does not need to be emphasized. However, in actual application, it has deviated from expectations and has taken on a centralized platform as the mainstream model.&lt;/p&gt;

&lt;p&gt;At this time, blockchain-related technologies, which are different from Web-related technologies and are also decentralized, were born. Because they emerged in an era dominated by centralized platforms and come with their own monetary system, their "decentralization" has a&lt;br&gt;
 rebellious connotation.&lt;/p&gt;

&lt;p&gt;The immutability of cryptocurrency transactions and records is a basic characteristic of blockchain, so it is only natural that various financial activities centered around cryptocurrencies have developed.&lt;/p&gt;

&lt;p&gt;The relatively mature application field of blockchain-related technologies at present is decentralized finance, that is, "DeFi". Because it has the characteristics of stock and foreign exchange trading and is unregulated, it can easily cause economic losses and needs to be approached with great caution.&lt;/p&gt;

&lt;p&gt;Blockchain-related technologies more or less have financial attributes in their application fields and have also formed corresponding cultures and industries, which is "Web3".&lt;/p&gt;

&lt;p&gt;The reason it is called "Web3" is closely related to the centralized characteristics of "Web 2.0" in the application form of the Web mentioned above, and it has a significant difference from the "Web 3.0" conceived by Tim Berners-Lee.&lt;/p&gt;

&lt;p&gt;In order to distinguish Web-related products and industries that do not use blockchain-related technologies, they are called "Web2".&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This article, based on my personal experience and understanding, has explained the reasons for and the underlying logic of decentralization and has tried to clarify the meanings of the two forms of Web periodization, "Web X.0" and "WebX".&lt;/p&gt;

&lt;p&gt;I am committed to exploring and researching solutions for personal and family decentralization and digital intelligence. From this perspective, whether it is Tim Berners-Lee's "Web 3.0" or "Web3" does not matter. However, considering my career development, it is only "Web3".&lt;/p&gt;

&lt;p&gt;Web3 is a dark forest, with people lurking everywhere, coveting your assets. You need to be vigilant and cautious at all times to protect yourself—this is the downside of lack of regulation and the price of freedom.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Web3 is the Future for Front-end Engineers Part 2</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Tue, 28 Jan 2025 11:50:37 +0000</pubDate>
      <link>https://dev.to/ourai/web3-is-the-future-for-front-end-engineers-part-2-4n35</link>
      <guid>https://dev.to/ourai/web3-is-the-future-for-front-end-engineers-part-2-4n35</guid>
      <description>&lt;p&gt;In my previous article, &lt;em&gt;&lt;a href="https://dev.to/ourai/web3-is-the-future-for-front-end-engineers-part-1-3o3k"&gt;Web3 is the Future for Front-end Engineers Part 1&lt;/a&gt;&lt;/em&gt;, I provided an overview of my journey transitioning from a traditional web front-end engineer to a Web3 full-stack engineer through the &lt;em&gt;&lt;a href="https://openbuild.xyz/learn/challenges/2036589711" rel="noopener noreferrer"&gt;Web3 Front-end Bootcamp&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;During the early days of the bootcamp, a common question was: "Can we find Web3 jobs after completing the course?" Some even approached it with a traditional mindset, seeking stable Web3 employment.&lt;/p&gt;

&lt;p&gt;From what I currently understand, the Web3 industry is highly unpredictable and volatile. The notion of "stability" simply does not exist. It's not uncommon for projects to vanish overnight. If anything, exchanges might be considered relatively stable.&lt;/p&gt;

&lt;p&gt;Thus, if you want to enter the Web3 space, you must embrace the instability and uncertainty. You need to be adaptable, flexible, and capable of rapidly and efficiently acquiring new knowledge to keep up with the constant changes.&lt;/p&gt;

&lt;p&gt;As a self-proclaimed &lt;strong&gt;independent developer&lt;/strong&gt;, I certainly don't limit my income to the option of "finding a job". Instead, I aim to diversify my sources of income.&lt;/p&gt;

&lt;p&gt;In addition to the usual approaches mentioned in &lt;em&gt;&lt;a href="https://dev.to/ourai/indie-developer-is-your-final-destination-30ek"&gt;Indie Developer is Your Final Destination&lt;/a&gt;&lt;/em&gt;, the Web3 community offers unique opportunities such as &lt;strong&gt;bounty tasks&lt;/strong&gt; and &lt;strong&gt;hackathons&lt;/strong&gt;. Being a "bounty hunter" can be quite rewarding!&lt;/p&gt;

&lt;h2&gt;
  
  
  Hackathon Experience
&lt;/h2&gt;

&lt;p&gt;OpenBuild, which has significant influence in the domestic Web3 developer community, not only runs the "Web3 Front-end Bootcamp" but also organizes numerous events, including the recently concluded &lt;em&gt;&lt;a href="https://www.ethshenzhen.org/" rel="noopener noreferrer"&gt;ETH Shenzhen&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This edition of "ETH Shenzhen" consisted of two parts: a sharing session and a roundtable discussion; and a hackathon competition. For teams participating in the hackathon who did not win, those from outside Guangdong Province were provided with travel subsidies.&lt;/p&gt;

&lt;p&gt;Half a month before the event, there was an &lt;strong&gt;online hackathon exclusive to bootcamp participants&lt;/strong&gt;, which can essentially be seen as a linked component of the "ETH Shenzhen Hackathon". The same project could be used for both, so I decided to participate in both.&lt;/p&gt;

&lt;p&gt;Before joining the bootcamp, I had the idea of developing a community-centered DAO-like organization around myself. During the bootcamp, while working on an NFT marketplace, I realized that this idea was feasible.&lt;/p&gt;

&lt;p&gt;Why not use the opportunity of participating in the hackathon to further concretize this idea as a competition project, and eventually make it another work in my "Internet Freedom Manifesto" portfolio?&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction to the Competition Project
&lt;/h3&gt;

&lt;p&gt;After a day of contemplation, I established the name and positioning of the project—&lt;/p&gt;

&lt;p&gt;The Chinese name is "吾界", and the English name is "Selfverse". Both convey the same meaning: "Self" is the "world" or "universe".&lt;/p&gt;

&lt;p&gt;The world we see is a reflection of our inner world. To live a fulfilling life, one must first enrich their spirit to form a robust, systematic, and self-sustaining "ecosystem".&lt;/p&gt;

&lt;p&gt;The true and complete "self" is often deeply hidden, and what we interact with others is a "persona" filtered and somewhat embellished.&lt;/p&gt;

&lt;p&gt;This is not only true in real life, but even on the internet, where anonymity is a feature, most people still have to follow the "unwritten rules" of social interaction to some extent.&lt;/p&gt;

&lt;p&gt;In today's increasingly internet-dependent daily life, many people need to maintain a relatively stable "persona" online, especially those who rely on digital means to make a living or even get rich through it, such as freelancers, independent hackers, and digital nomads.&lt;/p&gt;

&lt;p&gt;Some more popular and easier-to-understand terms can replace "persona"—personal brand, influence, individual identity, super-individual, etc.&lt;/p&gt;

&lt;p&gt;The positioning is to provide a suite of tools as infrastructure to help those in need more easily create a "persona" and enhance the closeness of connections between people.&lt;/p&gt;

&lt;p&gt;Using decentralized technology that is not limited to blockchain, we solve problems in a decentralized manner and give users the choice of deployment, hosting, management, etc.&lt;/p&gt;

&lt;p&gt;This project is an important part of my envisioned "decentralized and digital solutions for individuals and families", and it will be deeply integrated with &lt;a href="https://linxoid.com/" rel="noopener noreferrer"&gt;LinXoid&lt;/a&gt; and &lt;a href="https://knosysio.github.io/" rel="noopener noreferrer"&gt;KnoSys&lt;/a&gt; in the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Online Hackathon
&lt;/h3&gt;

&lt;p&gt;Although the competition time for the bootcamp's online hackathon was stated to be from August 1st to 10th, the actual development time was likely less than 8 days, as the 1st was almost over by the time it was announced, and submissions were due by 2 PM on the 10th.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foal56c931fcosbbjg375.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foal56c931fcosbbjg375.jpg" alt="Web3 Front-end Bootcamp Hackathon" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my case, I started developing at noon on the 3rd. I first wrote a smart contract supporting RBAC (Role-Based Access Control) and passed the unit tests by the 5th. From the 6th, I began working on the front-end interface, initially thinking it would take only two days. However, I underestimated the complexity of handling role-based access control, and it was not until the afternoon of the 9th that I completed the integration testing.&lt;/p&gt;

&lt;p&gt;Then, I prepared the project introduction materials and submitted them to the bootcamp's GitHub repository via a &lt;a href="https://github.com/openbuildxyz/Web3-Frontend-Bootcamp/pull/1369" rel="noopener noreferrer"&gt;PR&lt;/a&gt;, with time being extremely tight!&lt;/p&gt;

&lt;p&gt;Given the ambitious scope of my project idea, it was impossible to implement all the planned features within such a short period, so I had to settle for a small part of the functionality:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Mcyzc2OHrSU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;To save development time, I chose Ant Design and Ant Design Web3 for the front-end UI components, and deployed it as a pure front-end single-page application using Vite.&lt;/p&gt;

&lt;h3&gt;
  
  
  Offline Hackathon
&lt;/h3&gt;

&lt;p&gt;Although the "ETH Shenzhen Hackathon" could be participated in online, it was better to attend in person to have a unique experience.&lt;/p&gt;

&lt;p&gt;The hackathon took place in Shenzhen from the afternoon of August 16th to the evening of the 18th. I flew there and bought a ticket for the 15th to increase flexibility in case of any issues.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flyalz5l4u4ki4rtdbv1g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flyalz5l4u4ki4rtdbv1g.jpg" alt="ETH Shenzhen Hackathon Poster" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the 16th, the first activity was check-in for hackathon participants, who received a paper wristband to distinguish their identity. Completing interactions on X also earned a "swag bag" containing a T-shirt, cap, bag, etc., which was completely different from what we received during the bootcamp, with a brand-new design!&lt;/p&gt;

&lt;p&gt;Then there were several workshops by sponsors—one of the opening ones seemed under-prepared, showing off some on-the-spot debugging skills and failing to finish the presentation. I left during the second or third workshop to work on my project code.&lt;/p&gt;

&lt;p&gt;If you watched the video above, you would see that the paid content was just an empty shell without any actual content, like buying a book with only a cover and no pages. The main task during the hackathon was to address this issue.&lt;/p&gt;

&lt;p&gt;To do so, I needed to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add an article module, allowing site administrators to add, edit, and publish articles, and visitors to browse and tip;&lt;/li&gt;
&lt;li&gt;Modify the paid content module, enabling site administrators to associate articles as chapters, and visitors to see the table of contents and access the actual content;&lt;/li&gt;
&lt;li&gt;Add a fund module to centrally control the flow of payment and tipping funds within the same smart contract;&lt;/li&gt;
&lt;li&gt;Add a unique visitor center for users to view their payment and tipping records.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I started with the relatively simple visitor center, thinking that using only wallet addresses for user identification would be too plain and monotonous, so I added Jazzicons generated based on addresses, similar to MetaMask, and changed all avatars to this style.&lt;/p&gt;

&lt;p&gt;Next, I completed the smart contract code for the token fund, system settings, user registration, etc., which I had already thought about some logic for, and then it was time for the ice-breaking party.&lt;/p&gt;

&lt;p&gt;The organizers ordered takeout food such as kebabs, pizza, fried chicken, beer, and soda to the venue. Seeing the food and drinks, everyone rushed to grab them, quickly finishing and not having much time to chat—it seemed everyone was very hungry...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyt9vdbeisy0fioeoqjq9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyt9vdbeisy0fioeoqjq9.png" alt="Hackers' Party" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That day, I socialized a bit, meeting some people I had already interacted with in Hangzhou, as well as those I had connected with online before but were meeting in person for the first time.&lt;/p&gt;

&lt;p&gt;I got back to the hotel quite late, and there was still some development work to be done for this version of my project, with time being&lt;br&gt;
 tight. Since I didn't want to prepare a PowerPoint presentation for the pitch, I had to finish coding in the next two days—I decided to code all night!&lt;/p&gt;

&lt;p&gt;Listening to music by Xu Wei, BIGBANG, and others, I finished writing the article smart contract and adjusted the parts related to fund flow in the smart contracts without any issues, and then went to sleep, just before 4 a.m.&lt;/p&gt;

&lt;p&gt;The next two days followed a similar routine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Arriving at the venue before 9 a.m., signing in, and then heading to the coding area to work on my project;&lt;/li&gt;
&lt;li&gt;Having lunch with the boxed meals provided by the organizers, all with soup and beef;&lt;/li&gt;
&lt;li&gt;Spending the afternoon working on project-related tasks, either coding or explaining;&lt;/li&gt;
&lt;li&gt;Attending the dinner organized by the organizers in the evening and switching to social mode.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I hardly attended any of the guest presentations, instead focusing on preparing for the final pitch on the last day. I stayed up all night on the 17th and finally managed to complete most of the remaining features, feeling relieved!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbz6m84nmiwrlxgw5bkgz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbz6m84nmiwrlxgw5bkgz.jpg" alt="Coding for Selfverse" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the 18th, after wrapping up the project, I was eager to share it with others. I approached a fellow bootcamp participant and teaching assistant who was volunteering at the event. I sat next to him, demonstrated the project on my laptop, explained its features, and shared some long-term visions, such as attracting investments by using myself as a value carrier, issuing tokens to investors to prove their rights, and potentially rewarding them when certain conditions are met in the future.&lt;/p&gt;

&lt;p&gt;This was the first time I had introduced my project in such detail, and I felt a sense of excitement while talking. He listened attentively, not only understanding what I was saying but also offering some suggestions.&lt;/p&gt;

&lt;p&gt;Finally, it was time for the pitch session. There were about 30 projects, each given 10 minutes. Including breaks and other interruptions, the entire process took around 5 to 6 hours—I was the 10th presenter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcqdoxqofp7yb20debwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcqdoxqofp7yb20debwe.png" alt="Pitch Schedule" width="800" height="825"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since demonstrating the complete functionality of my project would take more than 10 minutes, I prepared the initial configuration and added demo data beforehand to save time on stage.&lt;/p&gt;

&lt;p&gt;When I started my pitch, I hardly made any data changes and instead introduced the project based on the pre-loaded data on the webpage. Just doing this almost filled the time, leaving only enough for the judges to ask two questions...&lt;/p&gt;

&lt;p&gt;Did I feel nervous when presenting? On a conscious level, I would say "no". I didn't feel anxious or anything like that, probably because of my experience making vlogs as a content creator. However, my body seemed to disagree, as my voice started trembling after just a few sentences, and I had to constantly adjust and control it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6hvsdrauaqky5ck8jag.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6hvsdrauaqky5ck8jag.jpg" alt="My Pitch" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main track my project participated in was "Open Source Tools and Infrastructure", with a usage model similar to WordPress. The project's underlying philosophy and vision are quite novel, and I believe they require long-term education and cultivation of potential users. Therefore, I have no plans for commercialization at the moment.&lt;/p&gt;

&lt;p&gt;Nevertheless, even though I had stated this beforehand, the judges still asked about commercialization, which left me a bit embarrassed and unsure of how to respond.&lt;/p&gt;

&lt;p&gt;The hackathon ended, and in the evening, I had a relaxing dinner with the OpenBuild team and bootcamp participants. The next day, I flew back to Hangzhou.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reflections on the Hackathon
&lt;/h2&gt;

&lt;p&gt;I believe my pitch was a failure. I felt that the chances of winning were extremely slim. Any score other than zero would be the greatest recognition for me!&lt;/p&gt;

&lt;p&gt;Although it was impossible to explain my project clearly within 10 minutes, this cannot be an excuse. There is still much room for improvement, such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Even with relatively complete functionality, a demo alone is not enough. A PowerPoint presentation is essential.&lt;/li&gt;
&lt;li&gt;My speaking pace was a bit slow, and the presentation lacked rhythm. I enjoyed the presentations of the two projects that followed mine, and I should learn from them.&lt;/li&gt;
&lt;li&gt;I should have interacted more with the judges before the pitch, introducing my project more. This would be like extending my pitch time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now I understand that participating in a hackathon is like playing a game of chess—how you allocate time between development, pitch material preparation, and networking affects the actual workload and the people you connect with, thereby influencing your chances of winning.&lt;/p&gt;

&lt;p&gt;Hackathons have two meanings for me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When working on my own project, it feels like entrepreneurship. The judges are like investment firms, and winning the prize is like securing investment.&lt;/li&gt;
&lt;li&gt;When working on someone else's project, it is like a bounty task. I use my professional skills to help them win and share the prize as compensation. However, for bounty tasks, the compensation is more uncertain.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In addition to coding, I also invested more effort in networking during these days than usual. I used to be quiet in offline settings, mainly listening to others. This time, I not only engaged in passive interactions but also actively approached people, including complete strangers.&lt;/p&gt;

&lt;p&gt;However, there was still a shortcoming: most of the people I networked with were those I had already connected with before, and very few were "new" acquaintances.&lt;/p&gt;

&lt;p&gt;Many technical people at such events have a common misconception—that they attend to learn technology. Those with this mindset will likely leave disappointed.&lt;/p&gt;

&lt;p&gt;I used to be one of them, attending various technical events before 2017 but rarely feeling like I had learned anything, mostly thinking "nothing special". Thus, I stopped attending until this year.&lt;/p&gt;

&lt;p&gt;My perspective has changed now. The most important aspects of attending events are to understand industry trends, interact with others, build deep connections, and explore collaboration opportunities—these are key to increasing the success rate of my career as a self-proclaimed &lt;strong&gt;independent developer&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This concludes my summary of the initial three-month journey of transitioning from a traditional web front-end engineer to a Web3 full-stack engineer.&lt;/p&gt;

&lt;p&gt;For me, with a rich knowledge base and experience forming an abstract model network, the technical aspect of the transition was not very difficult. The slightly more challenging part was distilling a more stable model from the complex blockchain ecosystem and the ever-changing Web3 industry, and accumulating valuable project experience.&lt;/p&gt;

&lt;p&gt;To enter the Web3 space, one must firmly discard the notion of "stability" in mindset. "Flexibility" and "efficiency" are your greatest and strongest weapons!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>web3</category>
      <category>openbuild</category>
    </item>
    <item>
      <title>Web3 is the Future for Front-end Engineers Part 1</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Tue, 28 Jan 2025 04:02:00 +0000</pubDate>
      <link>https://dev.to/ourai/web3-is-the-future-for-front-end-engineers-part-1-3o3k</link>
      <guid>https://dev.to/ourai/web3-is-the-future-for-front-end-engineers-part-1-3o3k</guid>
      <description>&lt;p&gt;In April of this year, likely due to the "Golden March and Silver April" phenomenon, I often saw front-end peers discussing job hunting. They were troubled about which company to join and were uncertain about job stability and prospects.&lt;/p&gt;

&lt;p&gt;For me, who thought I had "seen through everything", I believed that as long as they didn't break out of their original mindset, no matter what choices they made, they would end up with the same results. However, no matter how I explained the limitations, they remained indifferent, which really made me anxious!&lt;/p&gt;

&lt;p&gt;Thus, feeling exhausted, I wrote "&lt;a href="https://dev.to/ourai/the-last-advice-to-front-end-engineers-42kk"&gt;The Last Advice to Front-end Engineers&lt;/a&gt;" and decided never to "meddle" again in trying to pull those who were about to jump into the fire pit—one last attempt to help, then let go and respect their destinies.&lt;/p&gt;

&lt;p&gt;Although I firmly believed that the original path of front-end development was not viable, I didn't know how to relatively smoothly switch to another seemingly feasible path at that time.&lt;/p&gt;

&lt;p&gt;Until mid-May, while I was tinkering with my home data center and probably thinking about decentralized issues, the term "Web3" suddenly popped into my mind, pointing me to that smoother transition path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exposure to Web3
&lt;/h2&gt;

&lt;p&gt;Regarding "Web3", before May 14th, I had only heard of it and basically knew it existed without really understanding it.&lt;/p&gt;

&lt;p&gt;But on that day, after installing MetaMask and experiencing a few dApps and getting a preliminary understanding of the ecosystem, I felt that the Web3 direction had a lot of growth potential and a promising future—&lt;/p&gt;

&lt;p&gt;There are so few dApps for individual users, the user experience is so poor, and the infrastructure system is not yet mature. Of course, there is a lot of room for growth! 😂😂😂&lt;/p&gt;

&lt;p&gt;When mentioning "Web3", another closely related term comes to mind—"DAO", which stands for "Decentralized Autonomous Organization"—a type of organizational form that seems to match my ideal.&lt;/p&gt;

&lt;p&gt;Naturally, I immediately applied and joined a DAO initiated by Chinese people that matched my ideals.&lt;/p&gt;

&lt;p&gt;Towards the end of the month, the DAO's manager forwarded in the group a "Web3 Front-end Bootcamp" organized by OpenBuild, which not only teaches the knowledge and skills needed to transition to Web3 full-stack development but is also free, with various rewards. I really couldn't find a reason not to sign up!&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning in the Bootcamp
&lt;/h3&gt;

&lt;p&gt;The bootcamp started on June 4th, entirely online, and except for the Q&amp;amp;A sessions, it was asynchronous, giving both teachers and learners a lot of freedom to arrange their time independently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8a2i9rg3c6h2b8naifz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8a2i9rg3c6h2b8naifz.png" alt="Promotional image of Web3 Front-end Bootcamp" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The overall positioning and design are more inclined to "help experienced Web2 front-end developers transition to Web3 front-end", including 6 basic courses and 3 advanced courses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic courses—covering the basic elements needed to develop a dApp based on EVM, and using the more common project types NFT market and DEX as practical exercises;&lt;/li&gt;
&lt;li&gt;Advanced courses—promoting products of stakeholders, and also helping developers who want to enter the industry to adapt to the current industry's variability as soon as possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each class has corresponding homework, which needs to be submitted as a PR in the &lt;a href="https://github.com/openbuildxyz/Web3-Frontend-Bootcamp" rel="noopener noreferrer"&gt;accompanying GitHub repository&lt;/a&gt; for the review personnel to check; those submitted before July 16th can receive rewards, with a maximum of 43 USDT.&lt;/p&gt;

&lt;p&gt;If you encounter problems during learning and doing homework, there is a bootcamp-specific group for everyone to discuss and exchange in real time, which plays a role in mutual supervision while learning from each other.&lt;/p&gt;

&lt;p&gt;Not only doing homework has rewards, but writing good learning notes and making other contributions to the bootcamp will also have rewards, but again, only before July 16th—As an active enthusiast, I naturally got them all～😎😎😎&lt;/p&gt;

&lt;p&gt;Even though there are no rewards now, if you want to transition to Web3, the courses of this bootcamp are still worth looking at; it's best to follow and do the homework, and as one of the reviewers, I will try my best to correct it.&lt;/p&gt;

&lt;p&gt;For more of my experiences during the bootcamp, see the learning notes "&lt;a href="https://dev.to/ourai/how-to-build-a-dapp-as-a-smart-contract-newbie-1eid"&gt;How to Build a dApp as a Smart Contract Newbie&lt;/a&gt;" and "&lt;a href="https://s.ourai.ws/notes/openbuild-web3-frontend-bootcamp-review/" rel="noopener noreferrer"&gt;OpenBuild Web3 Front-end Bootcamp Review&lt;/a&gt;".&lt;/p&gt;

&lt;h3&gt;
  
  
  Gains from the Bootcamp
&lt;/h3&gt;

&lt;p&gt;This more than a month's bootcamp experience had a significant impact on me and was a milestone in my life because the gains from multiple perspectives looked quite good—&lt;/p&gt;

&lt;p&gt;The most basic and important thing is to achieve the initial goal of signing up for the bootcamp—to transition to Web3 full-stack development—although I have just crossed the threshold, I can now independently develop a complete dApp, laying the foundation for participating in hackathons next.&lt;/p&gt;

&lt;p&gt;Since I actively communicated with others in the group during the learning process and occasionally gave suggestions to the organizers, I was absorbed into the "teaching assistant" team to help review homework.&lt;/p&gt;

&lt;p&gt;Later, I "fiercely" reviewed and merged hundreds of PRs, indirectly teaching some people the skills of using Git and the precautions for open-source collaboration.&lt;/p&gt;

&lt;p&gt;Given my outstanding performance, including the rewards for doing homework and writing learning notes, I finally received more than 500 USDT at the end of the camp, which should be the most.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3bj6bvyuggk01gl99d58.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3bj6bvyuggk01gl99d58.jpg" alt="Excellent Teaching Assistants of " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My activity during the bootcamp had some influence, and I established connections and gradually became familiar with others, including the founder of the organizer OpenBuild.&lt;/p&gt;

&lt;p&gt;Taking this bootcamp as a lead, I gave some more systematic suggestions to OpenBuild and slightly envisioned its future development direction; perhaps seeing that I was willing to work together, I was pulled into the PMC.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26kgrcbq4030q5d6ftns.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26kgrcbq4030q5d6ftns.jpg" alt="Members of " width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After multiple communications and exchanges, at least I think a deep cooperative relationship can be established between me and OpenBuild—formally independent but actually closely connected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;As a Web front-end engineer who has been struggling for more than ten years, I firmly do not see a good future for traditional Internet Web front-end development; by chance, I found the Web3 industry that can maximize smooth migration.&lt;/p&gt;

&lt;p&gt;Since then, I decisively decided to transition to Web3 full-stack development, that is, in addition to the original Web front-end knowledge and skills, I also need to learn and master smart contract development, and accumulate relevant project experience on this basis.&lt;/p&gt;

&lt;p&gt;By deeply participating in the "Web3 Front-end Bootcamp" organized by OpenBuild, I not only achieved the basic goal of "transitioning" but also gained many additional benefits, with very sufficient positive feedback!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>web3</category>
      <category>openbuild</category>
    </item>
    <item>
      <title>How to Build a dApp as a Smart Contract Newbie</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Mon, 27 Jan 2025 16:09:18 +0000</pubDate>
      <link>https://dev.to/ourai/how-to-build-a-dapp-as-a-smart-contract-newbie-1eid</link>
      <guid>https://dev.to/ourai/how-to-build-a-dapp-as-a-smart-contract-newbie-1eid</guid>
      <description>&lt;p&gt;As a senior front-end engineer who has long been pessimistic about the traditional Internet industry's Web front-end development, I have been searching for a way to maximize the use of my existing knowledge and skills. I chose to transition to full-stack development in the Web3 field.&lt;/p&gt;

&lt;p&gt;When I made this decision, I knew little about Web3, whether from the perspective of a practitioner or an ordinary user. I urgently needed a way to get started quickly!&lt;/p&gt;

&lt;p&gt;By chance, I learned about &lt;a href="https://openbuild.xyz/" rel="noopener noreferrer"&gt;OpenBuild&lt;/a&gt;'s &lt;a href="https://openbuild.xyz/learn/challenges/2036589711" rel="noopener noreferrer"&gt;Web3 Front-end Bootcamp&lt;/a&gt;. Judging from the content introduction, it should meet my needs, so I signed up without hesitation—it's free, and there are even "Manis" to earn. Why hesitate?&lt;/p&gt;

&lt;p&gt;The content of this article is the practical notes of the boot camp course, focusing on "How a pure novice in smart contracts with front-end development foundation can develop their first NFT market dApp". That is to say, it will cover &lt;a href="https://github.com/openbuildxyz/Web3-Frontend-Bootcamp/blob/main/task/03_NFTMarket_Contract.md" rel="noopener noreferrer"&gt;task 3&lt;/a&gt;, &lt;a href="https://github.com/openbuildxyz/Web3-Frontend-Bootcamp/blob/main/task/04_NFTMarket_Component.md" rel="noopener noreferrer"&gt;task 4&lt;/a&gt;, and &lt;a href="https://github.com/openbuildxyz/Web3-Frontend-Bootcamp/blob/main/task/05_NFTMarket_Dapp.md" rel="noopener noreferrer"&gt;task 5&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since I am a beginner transitioning to Web3, I don't understand many things. The following content represents my personal understanding. If there are any errors, omissions, or mistakes, please point them out.&lt;/p&gt;

&lt;p&gt;I think the name "smart contract" comes from its business role, and for developers, it is just a software program that needs to be written in a certain programming language.&lt;/p&gt;

&lt;p&gt;Therefore, to write Ethereum smart contracts, you need to learn and understand Solidity syntax, ERC, and on-chain interaction processes. Once you understand these, you can write the code correctly. The rest is deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning Solidity
&lt;/h3&gt;

&lt;p&gt;Experienced programmers can tell at a glance that Solidity is an object-oriented static type language. Although there are some unfamiliar keywords, it does not prevent me from seeing it as a "class" wrapped in a "contract".&lt;/p&gt;

&lt;p&gt;Therefore, if you are familiar with typed, class-based programming languages such as TS and Java, you can quickly get a preliminary understanding of Solidity by establishing a mapping relationship.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;contract&lt;/code&gt; keyword can be considered a domain-specific deformation of the &lt;code&gt;class&lt;/code&gt; keyword, more semantically expressing the concept of "contract". Thus, writing a contract is equivalent to writing a class.&lt;/p&gt;

&lt;p&gt;State variables are used to store data within the contract, equivalent to class member variables, that is, class properties.&lt;/p&gt;

&lt;p&gt;Functions can be defined both inside and outside the contract—the former is equivalent to class member functions, that is, class methods; the latter is ordinary functions, usually some utility functions.&lt;/p&gt;

&lt;p&gt;Unlike TS and Java, in Solidity, the visibility identifiers for variables and functions are not at the front, and their positions are inconsistent, which is somewhat counterintuitive.&lt;/p&gt;

&lt;p&gt;The semantics of &lt;code&gt;private&lt;/code&gt; and &lt;code&gt;public&lt;/code&gt; are the same as in other languages, but there is no &lt;code&gt;protected&lt;/code&gt;. Instead, there is &lt;code&gt;internal&lt;/code&gt;, and there is also an additional &lt;code&gt;external&lt;/code&gt; for functions that are only callable externally.&lt;/p&gt;

&lt;p&gt;Function modifiers are equivalent to TS decorators or Java annotations and can be used for aspect-oriented programming (AOP). Both functions and function modifiers can be overridden by derived contracts.&lt;/p&gt;

&lt;p&gt;The following types can all be regarded as objects in ES, but they are used in different scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structures (&lt;code&gt;struct&lt;/code&gt;) are used to define entities;&lt;/li&gt;
&lt;li&gt;Enumerations (&lt;code&gt;enum&lt;/code&gt;) are collections of limited options;&lt;/li&gt;
&lt;li&gt;Mappings (&lt;code&gt;mapping&lt;/code&gt;) are infinite options.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Solidity supports multiple inheritance and function polymorphism, which can better combine and reuse; since contract development tends to be driven by ERC, the side effects of multiple inheritance should not be as severe as in other languages.&lt;/p&gt;

&lt;p&gt;Given that Solidity is born for blockchain and the characteristics of blockchain itself and application scenarios, communicating with the outside world through events and rolling back previous operations when encountering errors are "must-haves", so the syntax supports event and error-related processing.&lt;/p&gt;

&lt;p&gt;The usage of the &lt;code&gt;require()&lt;/code&gt; function is also a bit special to me. &lt;code&gt;require(initialValue &amp;gt; 999, "Initial supply must be greater than 999.");&lt;/code&gt; is equivalent to the following ES code in a concise and semantic way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialValue&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Initial supply must be greater than 999.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understanding ERC
&lt;/h3&gt;

&lt;p&gt;In Ethereum, "ERC" stands for "Ethereum Request for Comments", which is a type of EIP (Ethereum Improvement Proposal) that defines standards and conventions for smart contract applications.&lt;/p&gt;

&lt;p&gt;Since Web3 promotes decentralization and openness, ensuring the interoperability of smart contract applications is a basic requirement, so ERC, as the standard in this regard, is very important.&lt;/p&gt;

&lt;p&gt;The most basic ERCs in Ethereum smart contract application development are as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ERC-20—Fungible tokens, as the infrastructure of a financial system, such as virtual currencies, contribution points;&lt;/li&gt;
&lt;li&gt;ERC-721—Non-fungible tokens (NFTs), as the infrastructure of an identity system, such as medals, certificates, tickets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In fact, ERC can be regarded as authoritative API documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing Smart Contracts
&lt;/h3&gt;

&lt;p&gt;When developing smart contract applications, you need to choose a framework to assist. It seems that Hardhat and Foundry are used more often—I chose the former because it is friendly to the JS technology stack, that is, it is friendly to people transitioning from front-end development.&lt;/p&gt;

&lt;p&gt;In terms of IDE selection, many people will use Remix provided by the Ethereum official, while I continue to use VS Code, mainly to reduce learning costs as much as possible when just getting started.&lt;/p&gt;

&lt;p&gt;If you are not familiar with Hardhat, you can follow the &lt;a href="https://hardhat.org/tutorial" rel="noopener noreferrer"&gt;official tutorial&lt;/a&gt; step by step to selectively set up the running environment. In the generated directory structure, in addition to the &lt;code&gt;hardhat.config.ts&lt;/code&gt; configuration file, you basically only need to pay attention to 4 folders and their files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;contracts&lt;/code&gt;—Smart contract source code;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;artifacts&lt;/code&gt;—Compiled files generated by &lt;code&gt;hardhat compile&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ignition&lt;/code&gt;—For deploying smart contracts based on Hardhat Ignition;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;test&lt;/code&gt;—Smart contract function test code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;code&gt;ignition&lt;/code&gt;, compiled files will also be generated, but they are different from &lt;code&gt;artifacts&lt;/code&gt; and are bound to the target chain to be deployed, that is, they are generated in the folder of the chain ID to be deployed.&lt;/p&gt;

&lt;p&gt;As the 3 tasks of the boot camp assignment involve ERC-20 tokens, ERC-721 tokens, and NFT markets, the first two token contracts can be based on the verified &lt;a href="https://www.openzeppelin.com/contracts" rel="noopener noreferrer"&gt;OpenZeppelin Contracts&lt;/a&gt; for extension.&lt;/p&gt;

&lt;p&gt;My implementation code for the ERC-20 token RaiCoin is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract RaiCoin is ERC20("RaiCoin", "RAIC") {
  constructor(uint256 initialValue) {
    require(initialValue &amp;gt; 999, "Initial supply must be greater than 999.");
    _mint(msg.sender, initialValue * 10 ** 2);
  }

  function decimals() public view virtual override returns (uint8) {
    return 2;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;It is best to mint a certain amount of tokens (usually a large number) at initialization and set the owner to your own account address. Otherwise, you will be prompted that there is no balance when conducting transactions later, which is more troublesome to handle.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;msg.sender&lt;/code&gt; in the &lt;code&gt;constructor()&lt;/code&gt; is actually the account address that deploys the contract. If you deploy it with your own account address, the initial tokens will all go into your account.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since my own ERC-20 token is just for fun and will not appreciate, you can consider overriding the &lt;code&gt;decimals()&lt;/code&gt; in OpenZeppelin to set the value smaller.&lt;/p&gt;

&lt;p&gt;Below is the implementation code for the ERC-721 token RaiE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract RaiE is ERC721 {
  uint256 private _totalCount;

  constructor() ERC721("RaiE", "RAIE") {
    _totalCount++;
  }

  function mint() external returns (uint256) {
    uint256 tokenId = _totalCount;

    _safeMint(msg.sender, tokenId);

    _totalCount++;

    return tokenId;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why did I only additionally implement a &lt;code&gt;mint()&lt;/code&gt; without any parameters, just simply issuing coins? Aren't NFTs supposed to have corresponding pictures? The specific reasons will be explained later.&lt;/p&gt;

&lt;p&gt;These two token contracts are a piece of cake. You don't need to write much code yourself. The real thinking is mainly focused on the NFT market contract, such as—&lt;/p&gt;

&lt;p&gt;Should the NFT list in the market be paginated?&lt;/p&gt;

&lt;p&gt;If paginated, the delay when flipping pages will be more noticeable, and the user experience on the front end will not be good. But if not paginated, there will also be this problem when there are many NFTs.&lt;/p&gt;

&lt;p&gt;Where should the NFT picture URL be stored? In the NFT contract or the market contract?&lt;/p&gt;

&lt;p&gt;In theory, it should be stored in the NFT contract, but if so, when obtaining the NFT list, it will frequently access the NFT contract through external calls, affecting performance and user experience.&lt;/p&gt;

&lt;p&gt;Should a list of "who owns which tokens" that can be externally obtained be maintained in the NFT contract?&lt;/p&gt;

&lt;p&gt;If there is, the data is redundant compared to the market contract, making the NFT contract very bloated. If not, it is not possible to explicitly know which tokens there are and who they belong to.&lt;/p&gt;

&lt;p&gt;It can be seen that &lt;strong&gt;relying solely on blockchain-related technologies to make a product-level application currently has great limitations, and the user experience will be very poor!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is to say, &lt;strong&gt;the performance and experience of the product still need to be supported by the traditional application architecture, and the blockchain is only used as identity verification and a "backup" for some data.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Therefore, I temporarily gave up the way of thinking oriented towards making products and stopped worrying about whether it is reasonable or not, and turned to first meeting the requirements of the assignment—just having the relevant functions is fine.&lt;/p&gt;

&lt;p&gt;In this way, the decision is very easy to make—just do it in a way that can complete the assignment more quickly! As a result, the above three doubts were quickly eliminated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The NFT list in the market is not paginated—there will only be a few NFTs;&lt;/li&gt;
&lt;li&gt;The NFT picture URL is stored in the market contract—the NFT contract is only used by its own market contract;&lt;/li&gt;
&lt;li&gt;The NFT contract does not maintain a list of token ownership—temporary operations can remember which account minted which token.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When implementing the NFT market RaiGallery, I found that only arrays can be traversed, and &lt;code&gt;mapping&lt;/code&gt; cannot, and arrays with a specified length when initialized cannot use &lt;code&gt;.push()&lt;/code&gt; to add elements, only indexes can be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract RaiGallery {
  struct NftItem { address seller; address nftContract; uint tokenId; string tokenUrl; uint256 price; uint256 listedAt; bool listing; }

  struct NftIndex { address nftContract; uint tokenId; }

  NftIndex[] private _allNfts;

  function getAll() external view returns (NftItem[] memory) {
    // The length of the array is specified when initialized
    NftItem[] memory allItem = new NftItem[](_allNfts.length);
    NftIndex memory nftIdx;

    for (uint256 i = 0; i &amp;lt; _allNfts.length; i++) {
      nftIdx = _allNfts[i];
      // Here, using `allItem.push(_listedNfts[nftIdx.nftContract][nftIdx.tokenId])` will report an error
      allItem[i] = _listedNfts[nftIdx.nftContract][nftIdx.tokenId];
    }

    return allItem;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Debugging Smart Contracts
&lt;/h3&gt;

&lt;p&gt;After writing the smart contract source code, you need to write test code to go through it first, expose some basic problems, and solve them.&lt;/p&gt;

&lt;p&gt;As mentioned above, in the Hardhat project, the test code is placed in the &lt;code&gt;test&lt;/code&gt; folder, and it is basically one file for each contract, of course, the reusable logic between different files can also be extracted into additional files, such as &lt;code&gt;helper.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The test code is written based on the API of Mocha and Chai. Before really starting to test the contract functions, you need to deploy the contract to the local environment first, which can be the built-in &lt;code&gt;hardhat&lt;/code&gt;, or you can start a local node &lt;code&gt;localhost&lt;/code&gt;, I temporarily choose the former.&lt;/p&gt;

&lt;p&gt;At this time, the deployment method can reuse the Hardhat Ignition module, but I haven't figured out how to use it yet, so I use the easier-to-understand &lt;code&gt;loadFixture()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Testing is quite troublesome, and it feels like almost a day's time is spent on it, but in this process, I have a deeper understanding of how ERC-20 tokens, ERC-721 tokens, NFT markets, and users should interact, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you directly use the contract instance to call the method, the caller is the contract itself. You need to use &lt;code&gt;contract instance.connect(some account)&lt;/code&gt; and then call it to simulate the operation with the user;&lt;/li&gt;
&lt;li&gt;The owner of the NFT needs to authorize all their NFTs to the NFT market through &lt;code&gt;.setApprovalForAll(market contract address, true)&lt;/code&gt; before they can be listed for sale in the market.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think the single-party testing of the smart contract is almost done, and it is time to deploy it to the local node for joint debugging with the front end, which will use the Hardhat Ignition module this time.&lt;/p&gt;

&lt;p&gt;When I went to read the documentation to learn, I felt a bit abstruse and difficult to understand, and I wanted to sleep when I read it; but now when I look back, each module is actually describing how to initialize when deploying the corresponding contract of the module.&lt;/p&gt;

&lt;p&gt;Hardhat Ignition supports sub-modules, which can be used through &lt;code&gt;.useModule()&lt;/code&gt;, and can be processed together with sub-modules when compiling and deploying modules, that is to say—&lt;/p&gt;

&lt;p&gt;Assuming I have &lt;code&gt;RaiCoin.ts&lt;/code&gt;, &lt;code&gt;RaiE.ts&lt;/code&gt;, and &lt;code&gt;RaiGallery.ts&lt;/code&gt; three modules, among which &lt;code&gt;RaiGallery.ts&lt;/code&gt; needs the address returned by the deployment of &lt;code&gt;RaiCoin.ts&lt;/code&gt; when deploying, then &lt;code&gt;RaiCoin.ts&lt;/code&gt; can be used as a sub-module of &lt;code&gt;RaiGallery.txt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;buildModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nomicfoundation/hardhat-ignition/modules&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;RaiCoin&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./RaiCoin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;buildModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RaiGallery&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;coin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;RaiCoin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gallery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RaiGallery&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;coin&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;gallery&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, &lt;code&gt;RaiE.ts&lt;/code&gt; is deployed separately, and when deploying &lt;code&gt;RaiGallery.txt&lt;/code&gt;, &lt;code&gt;RaiCoin.txt&lt;/code&gt; will be cascaded deployed, so only two deployment commands need to be executed.&lt;/p&gt;

&lt;p&gt;Then, change the &lt;code&gt;defaultNetwork&lt;/code&gt; configuration item in &lt;code&gt;hardhat.config.txt&lt;/code&gt; to &lt;code&gt;'localhost'&lt;/code&gt;, execute &lt;code&gt;npx hardhat node&lt;/code&gt; in the root directory of the Hardhat project to start the local node, and then open another terminal window to deploy the smart contract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute &lt;code&gt;npx hardhat ignition deploy ./ignition/modules/RaiE.txt&lt;/code&gt; to deploy the ERC-721 token contract;&lt;/li&gt;
&lt;li&gt;Execute &lt;code&gt;npx hardhat ignition deploy ./ignition/modules/RaiGallery.txt&lt;/code&gt; to deploy the ERC-20 token contract and NFT market contract.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After all deployments are successful, the compiled contract-related files will be generated in the &lt;code&gt;ignition/deployments/chain-31337&lt;/code&gt; folder (&lt;code&gt;31337&lt;/code&gt; is the chain ID of the local node):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;deployed_addresses.json&lt;/code&gt; lists the contract addresses;&lt;/li&gt;
&lt;li&gt;The JSON files in the &lt;code&gt;artifacts&lt;/code&gt; folder contain the contract's ABI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The above two key pieces of information need to be copied and pasted into the global shared variables of the front-end project for use in joint debugging.&lt;/p&gt;

&lt;p&gt;Before starting joint debugging, you need to do two things in the MetaMask wallet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the Hardhat local node to the network, you can refer to the YouTube video &lt;a href="https://www.youtube.com/watch?v=KhxXnHADWyw" rel="noopener noreferrer"&gt;How to Add a Local Test Network to Metamask&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://support.metamask.io/managing-my-tokens/custom-tokens/how-to-display-tokens-in-metamask/#how-to-add-a-custom-token" rel="noopener noreferrer"&gt;As shown on the official website&lt;/a&gt;, add the &lt;strong&gt;ERC-20 token contract address you are testing&lt;/strong&gt; to facilitate viewing of account balances.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The third-party libraries and frameworks I depend on in the front-end part mainly include Vite, React, Ant Design Web3, and Wagmi. Since the front end is what I am familiar with, there is no experience to share, so I won't elaborate.&lt;/p&gt;

&lt;p&gt;However, when developing the front-end part, there was one point that puzzled me for a while—&lt;/p&gt;

&lt;p&gt;Although programmatically, a new NFT needs to be minted before it can be listed on the market for trading, the interface should be one-step, that is, after filling in the NFT-related information and clicking "OK", it is directly listed.&lt;/p&gt;

&lt;p&gt;The assignment requires a two-step operation of minting first and then listing, which I think is a bit unreasonable, or the user experience is not good.&lt;/p&gt;

&lt;p&gt;In the end, due to my unfamiliarity with Wagmi and really not thinking of an implementation plan, and eager to submit the assignment, I didn't continue to worry about it...😂😂😂&lt;/p&gt;

&lt;p&gt;When debugging, if you encounter problems that block you, you can troubleshoot in the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When listing NFTs for sale, you need to first call the &lt;code&gt;setApprovalForAll&lt;/code&gt; of the NFT token contract to authorize the market contract and use the escrow market to transfer NFTs on your behalf;&lt;/li&gt;
&lt;li&gt;Before sending the listing request, use viem or ethers' &lt;code&gt;parseUnits&lt;/code&gt; to convert it into a number that conforms to the &lt;code&gt;decimals()&lt;/code&gt;
defined in your ERC-20 token contract (the default is &lt;code&gt;18&lt;/code&gt;);&lt;/li&gt;
&lt;li&gt;Before purchasing NFTs, check the balance of your custom ERC-20 token in your wallet to avoid mistaking Ether (ETH) for the balance of your ERC-20 token;&lt;/li&gt;
&lt;li&gt;When purchasing NFTs, you need to first call the &lt;code&gt;approve&lt;/code&gt; of your ERC-20 token contract to authorize the market contract and use the escrow market to transfer funds on your behalf.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The joint debugging is also over, finally, it is time for the last link—deploying to the Sepolia test network!&lt;/p&gt;

&lt;p&gt;This requires Sepolia Ether, and the general way to obtain it is to drip it from those "faucets", and you can only get a little bit every day. Fortunately, &lt;a href="https://github.com/Mika-Lahtinen" rel="noopener noreferrer"&gt;@Mika-Lahtinen&lt;/a&gt; provided a PoW method, see &lt;a href="https://github.com/zer0fire" rel="noopener noreferrer"&gt;@zer0fire&lt;/a&gt;'s note &lt;a href="https://github.com/openbuildxyz/Web3-Frontend-Bootcamp/discussions/897" rel="noopener noreferrer"&gt;🚀 Ultra-simple faucet tutorial - No transaction records or account balance required&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At this time, turn your attention back to the Hardhat project, open the &lt;code&gt;hardhat.config.txt&lt;/code&gt; file, temporarily change the &lt;code&gt;defaultNetwork&lt;/code&gt; to &lt;code&gt;'sepolia'&lt;/code&gt;, and add a &lt;code&gt;sepolia&lt;/code&gt; in &lt;code&gt;networks&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HardhatUserConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;defaultNetwork&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sepolia&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Temporarily change the default network to this&lt;/span&gt;
  &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;sepolia&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your Sepolia endpoint URL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;accounts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your wallet account private key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Sepolia endpoint can be obtained by registering an account on &lt;a href="https://www.infura.io/" rel="noopener noreferrer"&gt;Infura&lt;/a&gt; or &lt;a href="https://www.alchemy.com/" rel="noopener noreferrer"&gt;Alchemy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Then, follow the process of deploying to the local node mentioned above again, and after verifying the functions of the test network environment in the front end, you can submit the assignment!&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I have open-sourced all the code related to the NFT market dApp in &lt;a href="https://github.com/ourai/my-first-nft-market" rel="noopener noreferrer"&gt;&lt;code&gt;ourai/my-first-nft-market&lt;/code&gt;&lt;/a&gt;, and plan to solve the points discussed above in the future, and make it a benchmark for this kind of demo.&lt;/p&gt;

&lt;p&gt;Since the Sepolia contract address has been configured inside, you can directly run it locally and operate it. Welcome to refer to, discuss, and point out.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>web3</category>
      <category>solidity</category>
      <category>openbuild</category>
    </item>
    <item>
      <title>The Last Advice to Front-end Engineers</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Mon, 27 Jan 2025 03:02:12 +0000</pubDate>
      <link>https://dev.to/ourai/the-last-advice-to-front-end-engineers-42kk</link>
      <guid>https://dev.to/ourai/the-last-advice-to-front-end-engineers-42kk</guid>
      <description>&lt;p&gt;I don't know why, but I have this annoying habit of being overly eager to meddle in other people's affairs, which is why I changed my group nickname to "Enthusiastic Netizen" in some WeChat groups.&lt;/p&gt;

&lt;p&gt;Recently, some of my peers have been job hunting, cramming for interviews, and asking how to answer certain interview questions, and so on.&lt;/p&gt;

&lt;p&gt;Seeing them like this, I get extremely anxious – they seem to be willingly jumping into a pit of fire, one after another!!!&lt;/p&gt;

&lt;p&gt;At this point in time, the vast majority of my peers are "Web Front-end" developers centered around HTML, CSS, and JavaScript, and most of them are business front-end developers, who mostly work on middle and back-office applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Momentum" of Middle and Back-office Applications
&lt;/h2&gt;

&lt;p&gt;Middle and back-office applications have two important characteristics –&lt;/p&gt;

&lt;p&gt;First, business processes and data security are far more important than product experience. Compared to so-called "product power" and flashy visual design, ensuring that business processes proceed smoothly and that data remains intact is much more important, with the rest being just icing on the cake.&lt;/p&gt;

&lt;p&gt;Especially when facing manufacturing and other physical industries, even without digital products, the business can still run, albeit less efficiently; digital products exist only to improve efficiency and have no right to change existing business rules, nor should they be the other way around.&lt;/p&gt;

&lt;p&gt;Therefore, companies or departments that develop middle and back-office applications do not need the "product manager" of to C, but need a "requirements manager" who can understand the needs of the business side (mainly industry or domain experts) and convey them accurately.&lt;/p&gt;

&lt;p&gt;Second, the front-end part of middle and back-office applications is highly patterned, and since business and data are prioritized, it is possible to better model at the system level and abstract a construction pipeline that automatically deduces the final application from the model as the source.&lt;/p&gt;

&lt;p&gt;That is to say, as long as the model is extracted from the business, and various relationships are described based on a certain mechanism, the final effect of the operable application can be seen directly.&lt;/p&gt;

&lt;p&gt;The ways to describe relationships can be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;DSLs with programming-like experiences such as XML, JSON, JS pure objects;&lt;/li&gt;
&lt;li&gt;Visual operations by dragging and dropping on the page;&lt;/li&gt;
&lt;li&gt;Let AI understand the requirements document and then translate it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The last one is the ability that I advocate and pursue for the "&lt;a href="https://dev.to/ourai/the-effect-of-knowledge-on-efficiency-part-3-3api"&gt;knowledge-driven, intelligent R &amp;amp; D integration platform&lt;/a&gt;" I mentioned.&lt;/p&gt;

&lt;p&gt;As for what that "mechanism" is, there are two that I currently favor:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;a href="https://nop-platform.github.io/" rel="noopener noreferrer"&gt;Nop platform&lt;/a&gt; implemented by Canonical based on its own reversible computing theory;&lt;/li&gt;
&lt;li&gt;The BFF framework that my senior is currently developing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But they both lack support for the pure front-end part, and my "&lt;a href="https://ntks.ourai.ws/" rel="noopener noreferrer"&gt;Anti-chaos Front-end Engineering&lt;/a&gt;" will fill this gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Fate" of Engineers
&lt;/h2&gt;

&lt;p&gt;Before ChatGPT came into the public eye, we believed that in the R &amp;amp; D process of middle and back-office applications, designers and front-end engineers would be eliminated, and "requirements managers" and back-end engineers could collaborate to do the job.&lt;/p&gt;

&lt;p&gt;The emergence of ChatGPT and similar products has also made it possible to eliminate most back-end CRUD engineers, and "requirements managers" only need to write detailed requirements documents.&lt;/p&gt;

&lt;p&gt;Since it is a "trend" that business R &amp;amp; D engineers will be replaced by knowledge-driven, intelligent R &amp;amp; D integration platforms, why not accelerate this process?!&lt;/p&gt;

&lt;p&gt;In our view, positions engaged in such R &amp;amp; D have no future, but some people do not think so – either thinking with the current perspective, or believing that humans are stronger than AI.&lt;/p&gt;

&lt;p&gt;However, the fact is that the iteration and growth speed of technology is never linear, and one of the impacts of its development is to require people to renew their knowledge and skills; the most foolish thing about humans is to be self-righteous.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Although the main topic of this article is that business R &amp;amp; D engineers of middle and back-office applications will "suffer heavy casualties", it does not mean that to C is "unscathed", only the proportion will not be so large.&lt;/p&gt;

&lt;p&gt;Compared with my idea, my senior's statement is a bit more exaggerated – maybe one day AI will create miracles and directly generate applications composed of source code, instead of those that have been abstracted layer by layer.&lt;/p&gt;

&lt;p&gt;Such applications are black boxes, and from the perspective of software engineering, they are not maintainable, and any best practices and optimization methods will become invalid – neither meaningful nor necessary – just like after the advent of cars, knowledge and skills about horse riding became useless.&lt;/p&gt;

&lt;p&gt;Many times I feel like that kind of person – telling others that a disaster will come in a few days and they should escape quickly, but they think I am talking nonsense and make fun of me.&lt;/p&gt;

&lt;p&gt;So, this is my last warning, I hope those who see and understand it can take action and stop jumping into the pit of fire.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Things Behind the KnoSys Web App</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Sun, 26 Jan 2025 13:27:58 +0000</pubDate>
      <link>https://dev.to/ourai/things-behind-the-knosys-web-app-5b28</link>
      <guid>https://dev.to/ourai/things-behind-the-knosys-web-app-5b28</guid>
      <description>&lt;p&gt;In my previous article "&lt;a href="https://dev.to/ourai/im-developing-the-knosys-web-app-1a7i"&gt;I'm Developing the KnoSys Web App&lt;/a&gt;", I highlighted the reasons for developing the KnoSys GUI application and its core features. However, some people still don't understand why I'm reinventing the wheel.&lt;/p&gt;

&lt;p&gt;To put it simply, KnoSys is a piece of my grand vision, and one must grasp the overall picture to truly comprehend why I insist on creating this tool.&lt;/p&gt;

&lt;p&gt;I hope that by revealing the ideas and significance behind the KnoSys GUI application in this article, everyone can gain a slight understanding of my grand vision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design and Composition
&lt;/h2&gt;

&lt;p&gt;As someone who pursues freedom and doesn't want to be held hostage by platforms or tools, I won't create a tool that holds others hostage—do unto others as you would have them do unto you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Philosophy
&lt;/h3&gt;

&lt;p&gt;In the core design, I adhere to the principles of "openness, standardization, and transferability" as much as possible, especially for the crucial data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data is stored in file formats that can be viewed using the built-in applications of the operating system without the need to download or install additional applications;&lt;/li&gt;
&lt;li&gt;Text data prioritizes formats such as Markdown and YAML, which are friendly to human reading and writing and have become (de facto) standards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore, even if you don't use the KnoSys GUI application and switch to Obsidian, Source Notes, IDE, etc., you can still open and edit the relevant files without any barriers—even using the built-in applications of the operating system!&lt;/p&gt;

&lt;p&gt;The only limitation of using the KnoSys GUI application is the directory structure specification for convenient program processing—the &lt;a href="https://qiidb.github.io/meta/zh/guides/spec/" rel="noopener noreferrer"&gt;QiiDB Data Specification&lt;/a&gt;, which is also in line with (de facto) standards or common practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  User Autonomy
&lt;/h3&gt;

&lt;p&gt;When using other cloud services or applications, they always "presumptuously" build in some function modules that are never used and cannot be deleted or disabled, occupying limited "space" in various senses.&lt;/p&gt;

&lt;p&gt;As a knowledge management tool, the most indispensable function features of the KnoSys GUI application are "knowledge base" and "extension market", and the rest are basically enhanced functions, which can theoretically be obtained on demand through the "extension market".&lt;/p&gt;

&lt;p&gt;I don't intend to deprive users of their choice, so I won't build in any non-essential function modules, and will maximize user autonomy in choosing and combining.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical Architecture
&lt;/h3&gt;

&lt;p&gt;From a technical point of view, to put it bluntly, the KnoSys GUI application is the operation client of &lt;a href="https://qiidb.github.io/" rel="noopener noreferrer"&gt;QiiDB&lt;/a&gt;, because it itself does not have any operation capabilities—&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;QiiDB is a data specification and an open data collection based on this standard, and KnoSys is a tool for data processing based on this data specification.&lt;/p&gt;
  Ourai's thoughts
&lt;/blockquote&gt;

&lt;p&gt;So far, the KnoSys system consists of three main parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SDK—provides the ability to operate folders and files that comply with the QiiDB data specification in the form of functions;&lt;/li&gt;
&lt;li&gt;Website—combined with &lt;a href="https://jamstack.org/generators/" rel="noopener noreferrer"&gt;SSG&lt;/a&gt; to convert data sources that comply with the QiiDB data specification and generate static websites;&lt;/li&gt;
&lt;li&gt;Application—visual operation of data sources that comply with the QiiDB data specification, that is, the KnoSys GUI application.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Among them, the application part strongly depends on the SDK, and the website part will serve as an extended function of the application to provide the "knowledge base" sharing and publishing capabilities.&lt;/p&gt;

&lt;p&gt;The "knowledge base" dynamically renders the interface-related display forms based on "metadata" for data verification and other capabilities, which are built based on my own low-code development &lt;a href="https://dev.to/ourai/fxxk-design-from-anti-chaos-514n"&gt;Fxxk Design&lt;/a&gt; and &lt;a href="https://dev.to/ourai/futurejs-from-anti-chaos-47c3"&gt;Future.js&lt;/a&gt; system.&lt;/p&gt;

&lt;p&gt;In addition, the ability to subscribe to information from the "person" dimension will depend on &lt;a href="https://linxoid.com" rel="noopener noreferrer"&gt;LinXoid&lt;/a&gt;, a project aimed at helping people establish connections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vision and Significance
&lt;/h2&gt;

&lt;p&gt;Since KnoSys is a piece of my grand vision, what do the other pieces look like? Next, I will reveal them to you in both pragmatic and visionary aspects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Digital Life
&lt;/h3&gt;

&lt;p&gt;Like relying on electrical appliances, the vast majority of people in the twenty-first century can no longer live without digital products, and post-00s are the "natives" of the digital world.&lt;/p&gt;

&lt;p&gt;However, so far, digital products have mainly been aimed at businesses, enterprises, and governments, and those aimed at individuals are mainly for consumption and entertainment; there are not many products that make life better for individuals and families, and I think they are not good enough.&lt;/p&gt;

&lt;p&gt;As a person who loves life and has software development skills, I am determined to fill and improve this gap!&lt;/p&gt;

&lt;p&gt;Combining my personal situation, to support the sustainable digital nomadic life I want to live, I need a family digital workbench:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a server in the physical family that can be accessed from the outside network, and it is best to have multi-center data backup in multiple places;&lt;/li&gt;
&lt;li&gt;AI-assisted knowledge management, which will use KnoSys and local large language models;&lt;/li&gt;
&lt;li&gt;Knowledge-driven personal and family life management, including family collaboration, finance, health, smart devices, etc.;&lt;/li&gt;
&lt;li&gt;Personal or family communication for resource sharing and communication, which will use LinXoid and peer-to-peer networks (P2P).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At that time, the server in the physical family will be the SSOT data center, and computers, mobile phones and other devices will be client operation interfaces that basically do not store persistent data and connect and access the data center.&lt;/p&gt;

&lt;p&gt;See the article "If I Become a Digital Nomad" and the "Digital Life" plan for more information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cyberspace
&lt;/h3&gt;

&lt;p&gt;With the development of technology, the "erosion" of the digital world on the real world will gradually deepen, until the two are deeply integrated, and people no longer "deliberately" distinguish between the virtual and the real—both are illusions, and both are real.&lt;/p&gt;

&lt;p&gt;In the real world, the most important thing is the "knowledge" formed by the exploration of truth, and everything centered around "people"—in the digital world, which is a reflection of the real world, is equally important and is its foundation.&lt;/p&gt;

&lt;p&gt;To become a resident of cyberspace, it is extremely important to have a clear understanding of "knowledge" and "people", to clearly realize their importance and to fight for the relevant rights!&lt;/p&gt;

&lt;p&gt;In the real world, in the past, "knowledge" was held by a very small number of specific groups such as wizards, priests, and popes, while the general public was ignorant and could be manipulated at will; in the digital world, "knowledge" is mostly held by platforms, and users are manipulated.&lt;/p&gt;

&lt;p&gt;In the real world, in the past, most people generally had no human rights and were exploited and oppressed as de facto slaves by a very small number of specific groups; in the digital world, people are just resources in a certain platform, and are exploited cheap/free labor.&lt;/p&gt;

&lt;p&gt;The civilization degree of the digital world is far lower than that of the real world—most people have not yet realized their "knowledge" and "people" related rights in cyberspace, let alone strive for them!&lt;/p&gt;

&lt;p&gt;I hope my actions can awaken others, even if it's only a few.&lt;/p&gt;

&lt;p&gt;For extended reading, you can see my "Talking About Individual-Centered Services" series of articles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Speaking of the KnoSys GUI application, because it adheres to the principles of openness, standardization, and user autonomy, and there are no technical limitations, I chose Web technology with the same philosophy to implement it.&lt;/p&gt;

&lt;p&gt;Initially considering supporting the following two usage methods:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Automatically open in a new tab through a browser extension;&lt;/li&gt;
&lt;li&gt;Automatically start the application service when the computer is turned on, and manually enter the address in the browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The knowledge management part only provides the desktop version, and if you want to operate on mobile devices, please look forward to the mobile applications related to "digital life" that I will develop in the future!&lt;/p&gt;

</description>
      <category>knosys</category>
      <category>personalknowledgebase</category>
    </item>
    <item>
      <title>I'm Developing the KnoSys Web App</title>
      <dc:creator>Ourai L.</dc:creator>
      <pubDate>Sun, 26 Jan 2025 04:05:30 +0000</pubDate>
      <link>https://dev.to/ourai/im-developing-the-knosys-web-app-1a7i</link>
      <guid>https://dev.to/ourai/im-developing-the-knosys-web-app-1a7i</guid>
      <description>&lt;p&gt;After the New Year, I once again embarked on the construction of the KnoSys system, which had been on hold for nearly nine months. Last year in Q1, I worked on a static website generator, but this time, I am developing a Web-based all-in-one knowledge management GUI application.&lt;/p&gt;

&lt;p&gt;In this span of less than a month, I have been writing code intermittently in my spare time. Although the application is not yet usable, I am eager to introduce it specifically!&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems and Needs
&lt;/h2&gt;

&lt;p&gt;The motive behind doing something is crucial. A clear and well-defined motive can provide strong willpower and the ability to implement ideas effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Public Clouds Are Not Trustworthy
&lt;/h3&gt;

&lt;p&gt;I believe that if people optimistically flock to various cloud services, it is because they do not consider the data they generate as valuable assets, or they have not been sufficiently harmed by the service providers.&lt;/p&gt;

&lt;p&gt;As an old Internet user with nearly 20 years of experience, I have been hurt enough by cloud service providers—&lt;/p&gt;

&lt;p&gt;In the early stages of launching cloud services, to quickly accumulate users and obtain their information and the data they generate, service providers often offer free services for a period, sometimes with various promotional activities.&lt;/p&gt;

&lt;p&gt;Once most users have generated a significant amount of data and become dependent on the platform, it is time for the service providers to start reaping the benefits—charging for functions that were originally free, or restricting/reducing the amount of resources that were previously available for free.&lt;/p&gt;

&lt;p&gt;Some platforms do not notify users before banning or deleting the data they generate, leaving no time for backups; worse still, some do not even notify users before shutting down the service and simply disappear!&lt;/p&gt;

&lt;p&gt;The shutdown of cloud services or the bankruptcy of the companies behind them is inevitable. When there is a tendency to deeply use a certain cloud service, there is a risk of being held hostage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fragmented "People"
&lt;/h3&gt;

&lt;p&gt;Current content platforms and social media all have their own account systems, and they tend to create closed information silos—neither integrating with other platforms and services nor providing relatively open data access APIs.&lt;/p&gt;

&lt;p&gt;This behavior is driven by their own commercial interests, ignoring the needs and experience of users, forcing users to only obtain updates from people they are interested in through the "follow" function within the application.&lt;/p&gt;

&lt;p&gt;I particularly dislike having to "follow" someone just to view their content!&lt;/p&gt;

&lt;p&gt;There are some platforms that do a slightly better job, such as Twitter's "&lt;a href="https://help.twitter.com/en/using-twitter/twitter-lists" rel="noopener noreferrer"&gt;Lists&lt;/a&gt;" feature, which solves my need to receive updates without having to "follow" someone.&lt;/p&gt;

&lt;p&gt;However, even so, it is still impossible to subscribe to people across applications and platforms on my own.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clumsy File Management
&lt;/h3&gt;

&lt;p&gt;The final products of blogs, API documentation, etc., are static pages, and their data sources are local files that conform to certain standards and formats—these files can be considered a mixture of "regular data" and "metadata".&lt;/p&gt;

&lt;p&gt;When the number of files increases and the site becomes more complex, there are several significant pain points with the simple local file format:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is not easy to know what documents you have;&lt;/li&gt;
&lt;li&gt;Searching and editing are inconvenient;&lt;/li&gt;
&lt;li&gt;The relationships between documents are unclear and unmanageable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a need for a way to manage local files like a mid-to-back-end business system and to convert the data of local files in some way.&lt;/p&gt;

&lt;h3&gt;
  
  
  My Eccentric Needs
&lt;/h3&gt;

&lt;p&gt;My biggest hobby is to "collect" and "organize" things that interest me, which gives me a strong sense of fulfillment, control, and security.&lt;/p&gt;

&lt;p&gt;From a young age to now, I have collected many physical items in various categories, such as cassettes, CDs, comics, games, stamps, and currencies. In addition to these, I am fascinated by the collection of virtual data and information that can expand infinitely!&lt;/p&gt;

&lt;p&gt;In my limited understanding, since the birth of the universe, nothing exists in isolation; there are more or less relationships between things—finding and utilizing these relationships is extremely valuable!&lt;/p&gt;

&lt;p&gt;Modeling the collected data and information, effectively associating them with each other to form a network, and thereby achieving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standardizing and automating mechanical tasks;&lt;/li&gt;
&lt;li&gt;Quickly finding the optimal path between the current state and the target based on needs;&lt;/li&gt;
&lt;li&gt;Providing suitable and appropriate suggestions based on the current state of life, living, and work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These needs of mine are difficult to meet when using cloud services or other applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features and Characteristics
&lt;/h2&gt;

&lt;p&gt;To facilitate understanding, I liken the GUI application I am developing to a local version of "Yuque", but unlike Yuque, it does not support collaboration with others and only supports local operations for individuals.&lt;/p&gt;

&lt;p&gt;Below is a brief introduction to the core features and characteristics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Knowledge Base
&lt;/h3&gt;

&lt;p&gt;In the KnoSys system, the term "knowledge base" has both broad and narrow meanings—broadly speaking, anything that follows the QiiDB data specification is included; narrowly speaking, it is almost equivalent to a dataset, which is the case in this GUI application.&lt;/p&gt;

&lt;p&gt;Using a local folder set by the user as the data source, it traverses subfolders and reads file content according to the QiiDB data specification, presenting it in the interface through a list page.&lt;/p&gt;

&lt;p&gt;Each record in the list corresponds to a real file, such as YAML, Markdown, images, etc., which means that the CRUD operations in the interface are actually read and write operations on files.&lt;/p&gt;

&lt;p&gt;In addition to the above operations on "regular data", it is also possible to visually modify "metadata": defining field names, data types, validation rules, etc.; configuring the display forms of list pages, form pages, detail pages, and other interface-related elements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-application
&lt;/h3&gt;

&lt;p&gt;The "application" in this GUI application is similar to the "space" in Yuque and is the broad "knowledge base" mentioned earlier. In theory, each "application" has a corresponding local Git repository, which provides a certain degree of data isolation.&lt;/p&gt;

&lt;p&gt;A folder corresponding to an "application" can contain one or more datasets and may also include files that do not conform to the QiiDB data specification in addition to the datasets—these files will be ignored and not processed.&lt;/p&gt;

&lt;p&gt;Modifications and deletions of data, which are variable operations in the interface, are restricted within a specific "application" and cannot change data in other "applications". However, data from one "application" can be read as an external data source for other "applications".&lt;/p&gt;

&lt;p&gt;For example—&lt;/p&gt;

&lt;p&gt;I have two "applications": one contains basic information about books, movies, and music, similar to Douban, and the other is for my creations and some personal records—let's call it "Exobrain".&lt;/p&gt;

&lt;p&gt;Suppose I am watching "Breaking Bad" and want to record my progress. I would need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the book, movie, and music "application" as an external data source in "Exobrain" and associate it with a certain "knowledge base" in "Exobrain";&lt;/li&gt;
&lt;li&gt;Add a new piece of data containing information about "Breaking Bad" in the book, movie, and music "application";&lt;/li&gt;
&lt;li&gt;Go to "Exobrain" to read the book, movie, and music data, find "Breaking Bad", and mark it as "watching", which will generate corresponding data in the associated "knowledge base";&lt;/li&gt;
&lt;li&gt;Later, find "Breaking Bad" in the associated "knowledge base" and mark which episode I have watched.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It can be said that an "application" is equivalent to a database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Information Subscription
&lt;/h3&gt;

&lt;p&gt;In platforms like Yuque, following an account will result in receiving information pushes, which is a way of subscribing to information. The information subscription in this GUI application will break the "norm" and receive information based on the dimension of "people".&lt;/p&gt;

&lt;p&gt;The "people" here refers to identifiable entities behind virtual identities that have the same identity—&lt;/p&gt;

&lt;p&gt;My account on Yuque and Zhihu is "Ourai", while my account on Juejin and Weibo is "Ouraidono", but they all point to the virtual persona "Ourai"—both "Ourai" and myself are considered that "person".&lt;/p&gt;

&lt;p&gt;A "person" can be an individual or an organization, and the main manifestation in this GUI application is a unified information source that aggregates multiple platform accounts or website feeds.&lt;/p&gt;

&lt;p&gt;That is to say, by subscribing to the information of "Ourai" in this GUI application, you can receive updates from "Ourairyu" website and other platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Extension Market
&lt;/h3&gt;

&lt;p&gt;One aspect of measuring whether application software is user-friendly is its extensibility. As an open-source and free Web-based all-in-one knowledge management GUI application, it must have relatively strong extensibility!&lt;/p&gt;

&lt;p&gt;The main customization points of this GUI application are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The interface style theme, including fonts, colors, spacing, overall layout, etc.;&lt;/li&gt;
&lt;li&gt;The display forms of the list page, form page, detail page, and other interface-related elements of the "knowledge base";&lt;/li&gt;
&lt;li&gt;CRUD hooks and custom operations for "knowledge base" data and interface operations;&lt;/li&gt;
&lt;li&gt;"Widgets" displayed on the "home page" (referencing operating systems like iOS, macOS, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among them, extensions related to the "knowledge base" can be packaged into "templates" for installation together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Every time I tell others that I am developing a knowledge management tool, I am asked: "Aren't there already Obsidian, Siyuan Notes, and so on? What's the difference between yours and theirs?"&lt;/p&gt;

&lt;p&gt;The eagerness to write this article to introduce it is also an important reason to answer such questions.&lt;/p&gt;

&lt;p&gt;This article highlights the reasons for developing this GUI application and its core features—some of which have been implemented, some are in the process of being implemented&lt;br&gt;
, and some are still in the planning stage.&lt;/p&gt;

&lt;p&gt;The next article will further elaborate on the underlying philosophy, more ambitious visions, and significance.&lt;/p&gt;

</description>
      <category>knosys</category>
      <category>personalknowledgebase</category>
    </item>
  </channel>
</rss>
