Tuesday, November 22, 2022

What's new in NextJS 13?

 NextJS had released the latest version of its framework NextJS 13. There are so many changes can be obviously noticed. I summaries the changes in short notes.

Folder-based Routing in NextJS 13.

1. the pages folder had been removed and replaced with app folder for routing purpose.

2. use folder for file system routing.

3. use square bracket for dynamic routing [id].tsx http://www.mywebsite.com/{id}

4. use  parenthesis to exclude the directories from routing. (excluding directory)

NextJS provide to turbo mode for fast app launching in the development machine with the following command

npx next dev --turbo 

NextJS had reserved serveral file names in NextJS 13.

  • page.tsx
  • layout.tsx
  • loading.tsx
  • error.tsx
  • template.tsx
  • head.tsx 

Update nextjs.config.js configure file to use new feature app folder instead of pages folder for file sytem routing

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  experimental: { appDir: true },
};

module.exports = nextConfig;


 Update packages.json file to enable turbo mode in development

"scripts": {
    "dev": "next dev --turbo",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },



 

 

 

 

 



 


Monday, August 1, 2022

A cool tool to test your web app performance in command line

you can use the following command to install this utility in your development manchine.

if you this package run globally

npm i autocannon -g

for the specific app only

npm i autocannon --save

To test the performance of the app that running in port 3000

autocannon http://localhost:3000

the execution outcome will be shown as below






for more specific information, you can visit the link below 

https://github.com/mcollina/autocannon

Tuesday, July 5, 2022

How to enable CORS options in Apollo-Server-Micro?

 According the Apollo Server documentation, the CORS option is not available in server configuration.  

"Note that apollo-server-micro does not have a built-in way of setting CORS headers."

when  we create a apollo server, we can't set the cors options in the configuration object.

import {ApolloServer} from 'apollo-server-micro';
import 'reflect-metadata';
import { buildSchema } from 'type-graphql';
import { PetsResolver } from '../../src/schema/pet.resolver';

const schema = await buildSchema({
  resolvers: [PetsResolver],
});


const server = new ApolloServer({
    schema,
    csrfPrevention: true,  // see below for more about this
    cache: "bounded",
});

As a result, we should encounter the following CORS policy issue 

Access to fetch at 'http://localhost:3000/api/graphql' from origin 'https://studio.apollographql.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Since we can't add the cors option with the configruation object, we have to manually add those cors options in the handler function

export default async function handler(req:any, res:any){
    res.setHeader("Access-Control-Allow-Credentials", "true");
    res.setHeader(
        "Access-Control-Allow-Origin",
        "https://studio.apollographql.com"
    );
    res.setHeader(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept,
        Access-Control-Allow-Methods, Access-Control-Allow-Origin,
        Access-Control-Allow-Credentials, Access-Control-Allow-Headers"
    );
    res.setHeader(
        "Access-Control-Allow-Methods",
        "POST, GET, PUT, PATCH, DELETE, OPTIONS, HEAD"
    );
    if (req.method === "OPTIONS") {
        res.end();
        return false;
    }

    await startServer;
    await server.createHandler({path:"/api/graphql"})(req, res);
}


Now the cross site access violation should be resolved and we can manipulate the query and mutation in the apollo-studio.


Monday, July 4, 2022

How to fix " ReferenceError: document is not defined" in Jest?

When I setup a test again the AppShell in Micro-Frontend Application Development, then I added the test command to the scripts section in the package.json 

   "test": "jest"

now the scripts section should be shown as below.

 "scripts": {
    "dev": "tsc --watch --outDir dist",
    "build": "tsc --outDir dist",
    "lint": "eslint *.ts*",
    "storybook": "start-storybook",
    "test": "jest"
  },


However when i run the test with pnpm test, I encoutered the error in the following image.







"AppShell › renders

    The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string.

    Consider using the "jsdom" test environment."


based on the suggestion, i added the environment tag jsdom to the test command, then the test run is succeed.

"scripts": {
    "dev": "tsc --watch --outDir dist",
    "build": "tsc --outDir dist",
    "lint": "eslint *.ts*",
    "storybook": "start-storybook",
    "test": "jest --env=jsdom"
  },

The successful test run is shown below.





How to access environment variable from Fastify server?

 We can easy access the environment variable from the express server with help from dotenv library. we can just need to add this following line the Server.ts or Index.ts file, then we can access the environment variable.

require('dotenv').config();
 app.use(
    cors({
      origin: __prod__
        ? process.env.CORS_ORIGIN_PROD
        : process.env.CORS_ORIGIN_DEV,
      credentials: true
    })
  )

In the server, we can't not simply assign the JWT_SECRET that stored in the environment setting as we usually did in the express server. In the fastify server, we should create a Constant.ts file to store the code above, the we import the Constant.ts into Server.ts file.

require('dotenv').config();

export const DB_CONNECTION_STRING =
  process.env.DB_CONNECTION_STRING ||
  "mongodb://localhost:27017/password-manager";

export const CORS_ORIGIN = process.env.CORS_ORIGIN || "http://localhost:3000";

export const COOKIE_DOMAIN = process.env.COOKIE_DOMAIN || "localhost";

export const JWT_SECRET= process.env.JWT_SECRET || "jwt-secret-key";

Server.ts 

import { JWT_SECRET } from "../constant";
 app.register(fastifyJwt, {
    secret: JWT_SECRET,
    cookie: {
        cookieName: "token",
        signed: false,
    },
    });



Monday, June 27, 2022

A cool tool (Windows Powertoys) to provide you quick access to application in windows environment

 Usually we need to click on the Windows Start button to launch the menu, then we can search the application that we want the access.

Now Microsoft provide us cool toy call Windows Powertoys. we can use Powertoys Run to quickly find the application and launch it.

shortcut key: ALT + SPACE to activate the Powertoys Run 





then we can type in the input box to find the application that we want to launch








you can download this toy from GitHub with the link below

https://github.com/microsoft/PowerToys/releases/tag/v0.59.1

ASP.Net MVC Web API vs .Net 6 Minimal API quick compare in a diagram

 Microsoft introduced the Minimal API in .Net 6, which is a lightweight API development for web api

We can show two with difference in a diagram









we can easily spot the big difference is that there is no Controller component in the Minimal API.

As a result there will much more difference between Mininal API and MVC Web API


you can find out more information with this link  Tutorial: Create a minimal web API with ASP.NET Core


Thursday, June 23, 2022

How to quickly set up a shared library for Micro-Frontend application?

When we start the Micro-Frontend application development. we can use Turborepo to setup the project by 

executing the following command in the CMD window or Terminal in the VS Code.   

npx create-turbo@latest

By default, the project will create a ui inside the packages folder for crosss project sharing.









if you want to create other sharing library or context project, then we just have to copy the entire ui folder and rename it to store (which is the state-management for the entire application). we can run the following command from the parent level of ui, which should packages folder.

cp -rf ui store

now open the package.json file inside the store folder to modify the following information.

name: "store"

remove all libraries in the dependenices section  and unrelated libraries in the devdependencies section.

then add zutand for state management.

{
  "name": "ui",
  "version": "0.0.0",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "license": "MIT",
  "scripts": {
    "dev": "tsc --watch --outDir dist",
    "build": "tsc --outDir dist",
    "lint": "eslint *.ts*"
  },
  "devDependencies": {
    "@types/react": "^18.0.9",
    "@types/react-dom": "^18.0.5",
    "eslint": "^7.32.0",
    "eslint-config-custom": "workspace:*",
    "react": "^18.1.0",
    "tsconfig": "workspace:*",
    "store": "workspace:*",
    "typescript": "^4.5.2"
  },
  "dependencies": {
    "@mantine/core": "^4.2.6",
    "@mantine/hooks": "^4.2.6",
    "react-router-dom": "^6.3.0"
  }
}

now the modified package.json should looks like the one below


{
  "name": "store",
  "version": "0.0.0",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "license": "MIT",
  "scripts": {
    "dev": "tsc --watch --outDir dist",
    "build": "tsc --outDir dist",
    "lint": "eslint *.ts*"
  },
  "devDependencies": {
    "@types/react": "^18.0.9",
    "@types/react-dom": "^18.0.5",
    "eslint": "^7.32.0",
    "eslint-config-custom": "workspace:*",
    "react": "^18.1.0",
    "tsconfig": "workspace:*",
    "typescript": "^4.5.2"
  },
  "dependencies": {
    "zustand": "4.0.0-rc.1"
  }
}

 

 You should run pnpm i to link all packages together.  Now we should have a share Store acrosss all projects in our MFE application.








How to access Postgres Database host in the Docker?

 it is very convenient to spin up a Postgres Database in the docker by composing a docker compose yaml file.

the following code will help us setup a Postgres Database in the Docker

version: '3.8'
services:
  twitter_postgres_db:
    image: debezium/postgres:13-alpine
    environment:
      - POSTGRES_DATABASE=twitter_db
      - POSTGRES_USER=twitter_dev
      - POSTGRES_PASSWORD=twitter_dev
    ports:
      - 6543:5432
    volumes:
      - twitter_db_data:/data/db
volumes:
  twitter_db_data:

I should be able to setup another container for the PgAdmin in the docker. Since I already install a Postgres PgAdmin instance in my desktop. I just want to access the Postgres Database from my local host.


Here is the step that we should follow to access the Postgres from local PgAdmin

1.  Register the localhost Server







2.  Fill the following information in the Register Server Window

  • Name: LocalHost
  •  Host Name /Address: localhost
  • Port: 6543  (copied from the docker compose file)
  • Maintenance Database: twitter_db (copied from the docker compose file)
  • Username: twitter_dev  (copied from the docker compose file)
  • Password: twitter_dev  (copied from the docker compose file)































3.  After I click on the save button, then you should be able to access the Twttier_db