Categories
Web Development

How to use Google Typescript Style Guide in a ReactJS project

gts is Google’s TypeScript style guide, and the configuration for formatter, linter, and automatic code fixer. No lint rules to edit, no configuration to update, no more bike shedding over syntax. there are a few configurations to use it in a ReactJS project and I logged here:

1. Create a new React project with the TypeScript template

%npx create-react-app client-demo --template typescript
%cd client-demo
%yarn

2. Add and initiate gts into the project

Before adding gts, please backup your tsconfig.json file because gts will generate a new one overwriting it.

Execute the below command, it will prompt if you want to overwrite the existing “tsconfig.json”, just select “y” here.

%npx gts init

We have installed ReactJS and gts in our project, however, if you try starting the project with “yarn start” now, you will encounter the below error due to the eslint setting conflicts between reactjs and gts, we need to do some extra work to solve it.

3. Restore tsconfig.json changed by gts

The tsconfig.json file overwritten by gts is like this:

{
  "extends": "./node_modules/gts/tsconfig-google.json",
  "compilerOptions": {
    "rootDir": ".",
    "outDir": "build"
  },
  "include": [
    "src/**/*.ts",
    "test/**/*.ts"
  ]
}

Replace the above with our backup file, just keep the first “extends” line,

{
  "extends": "./node_modules/gts/tsconfig-google.json",
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

4. Eslint settings

Install required eslint plugins:

%yarn add -D eslint-plugin-react eslint-plugin-node eslint-plugin-prettier

Update eslintrc.json:

/* This is original created by gts */
{
  "extends": "./node_modules/gts/"
}

To:

{
  "extends": [
    "./node_modules/gts/",
    "plugin:react/recommended"
  ],
  "env": {
    "browser": true,
    "jest": true
  }
}

Now, you have completed all the above four-step settings and can run ReactJS successfully.


There is one more optional setting I would recommend is adding husky pre-commit check so the system will execute gts check automatically when committing your code every time.

1. Install husky

npx husky-init && yarn

2. Edit “./husky/pre-commit” file

Replace "npm test" as "./node_modules/.bin/gts check"

All done, now the system will do “gts check” before committing your code.

Thanks for reading, please comment and let me know if you have any questions.

Categories
Web Development

Build Magento 2.4.2 Community test environment using nginx1.19+php7.3+mysql8 on MacOS

The article logs my process of using Nginx1.19 + php7.3 + MySQL8 to build the test environment of Magento on my MacBook(macOS Big Sur 11.2.1), I hope it is helpful for you.

Before starting the installation, you need homebrew installed on the computer.

Nginx Part:

Firstly, install Nginx and start the service

% brew install nginx
% brew services start nginx

MySQL Part:

Secondly, install MySQL8, start the service and create the database

% brew install mysql
% brew services start mysql

Edit my.cnf to run MySQL8 with native password authentication

% vi /usr/local/etc/my.cnf 

#add the below line in the section [mysqld]
default-authentication-plugin=mysql_native_password

# If my.cnf file doesn't exist in the directory '/usr/local/etc'
# use the following commands to find out where it is
# ---------------------------------------------
# % sudo /usr/libexec/locate.updatedb
# #wait a few minutes for it to finish
# locate my.cnf
# --------------------------------------------- 

Save then restart MySQL service

% brew services restart mysql

Change MySQL password

% mysql -uroot
% mysql> use mysql;
% mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
% mysql> flush privileges;
% mysql> exit;

Create new Magento database:

% mysql -uroot -p123456
% mysql> create database magento;
% mysql> exit;

Mysql has been installed successfully and configured properly. Now let us install PHP.

PHP Part:

The default PHP version is PHP8 by brew however Magento2 doesn’t support it so we need to install a downgraded PHP7.3 version and start the service for php-fpm mode which will be occupying port 9000.

% brew install php@7.3
% brew link --force php@7.3
% brew services start php@7.3

After installed, open a new terminal to confirm the latest php7.3 has been installed:

There are some configures you need to set in php.ini

% vi /usr/local/etc/php/7.3/php.ini

then update following settings:

memory_limit=2G
date.timezone=Pacific/Auckland
zlib.output_compression = On

#For test purpose only
max_execution_time = 86400
upload_max_filesize = 2G 
post_max_size = 2G
max_input_vars = 86400 
max_input_time = 86400

remember to restart PHP services after updated php.ini

% brew services restart php@7.3

Install composer as the PHP package management tool

% brew install composer

Magento Part:

Install elasticsearch and start the service which relied on Magento.

% brew install elasticsearch
% brew services start elasticsearch

Download Magneto source code to a new folder, I name it as “magento-community” and you can use any name.

composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition magento-community

You will be asked to provide the name and password for downloading from repo.magento.com, access https://marketplace.magento.com/ , register a new user or login, then, click “My Profile” on your username at the right top of the page.


Click “Access Keys” to go to the Access Keys page, then create a new access key, and use Public Key as username and Private Key as password, then you should be able to download Magento Community Version, my downloaded version is Magento 2.4.2.

After downloading successfully, go to the Magento folder,

Install Magento:

% php bin/magento setup:install --base-url=http://127.0.0.1:8001/ --db-host=127.0.0.1 --db-name=magento --db-user=root --db-password=123456 --admin-firstname=admin --admin-lastname=admin --admin-email=ukalpa@gmail.com --admin-user=admin --admin-password=admin123456 --language=en_AU --currency=NZD --timezone=Pacific/Auckland --use-rewrites=1

Starting Magento installation:
File permissions check...
[Progress: 1 / 1314]
Required extensions check...
[Progress: 2 / 1314]
Enabling Maintenance Mode...
[Progress: 3 / 1314]
Installing deployment configuration...
......
[Progress: 1311 / 1314]
Disabling Maintenance Mode:
[Progress: 1312 / 1314]
Post installation file permissions check...
For security, remove write permissions from these directories: '/Users/ukalpa/Projects/php/magento/magento-community/app/etc'
[Progress: 1313 / 1314]
Write installation date...
[Progress: 1314 / 1314]
[SUCCESS]: Magento installation complete.
[SUCCESS]: Magento Admin URI: /admin_15owhz
Nothing to import.
ukalpa@Shuis-MacBook-Pro magento-community % 

Magento has been installed successfully, remember to turn off two-step authentication or you will get an email notification to confirm login.

php bin/magento module:disable Magento_TwoFactorAuth

now let us configure Nginx.

Configure Nginx to support PHP

% vi /usr/local/etc/nginx/servers/magento-community 
--------------------------------------------------
# add the following content in the file
# remeber to change the folder path to your path

upstream fastcgi_backend {
     server  127.0.0.1:9000;
 }

server {
        listen 8001;
        server_name 127.0.0.1;
        set $MAGE_ROOT /Users/ukalpa/Projects/php/magento/magento-community;
        set $MAGE_DEBUG_SHOW_ARGS 0;
        include /Users/ukalpa/Projects/php/magento/magento-community/nginx.conf.sample;

}

#save and exit
-------------------------------------------------
 
% brew services restart nginx

Now Magento has been installed successfully on Macbook, you can access it at http://127.0.0.1:8001

Categories
Web Development

A console.log issue in Google Chrome

Found an interesting issue in Google Chrome today and have reported it to bugs.chromium.org.

The issue relates to change and print object value in a loop, you can reproduce it by executing the following code in Chrome Console.

var book = {info:{}};
for(var i = 0; i < 3; i++){
    book.info.id = i;
    console.log(book);
}

The expected result “id” in the object book should be 0, 1, 2 however it prints 2, 2, 2 as below. The code executes as expected in Safari.

I assume the issue is encountered by the cache rule of speeding up console.log only checks whether the top level of the variable is changed in a loop so caused the issue.

UPDATE:

Got the reply from Chromium that they won’t fix it:

Working as intended. If you hover over the [ i ] icon for more information, it will tell you that the variable content was evaluated at the point when you expanded the log entry.

Categories
Web Development

The best solution to build your website for developers

Review the process of building this website and I hope this article could be helpful for you to save money in building your website.

I know there already have a lot of websites providing easy solutions for creating your own website but still some reasons you want to create by yourself because of saving money or easily customization solutions or even just because you are a programmer. I write down my solution I think the best for your reference.

My solution is using the free Linux operation system and opensource software WordPress to build a website and deploying in Google Cloud which I estimate will just cost no more than NZD$100 annual fee ideally fulfills all your various requirements in your website’s early stage. Google Cloud has a low/free host plan calling “f1-micro” in GCE(Google Compute Engine) available in its some zones and you can spend tiny coins in extra disk space and a static IP or snap services to improve the flexibility and reliability of your website. Let’s talk about the details of my plan:

DOMAIN

I applied my domain in Google Domains and it costs me NZD$22 a year, you are free to hide your registration info which is a charged service in GoDaddy. Another advantage is you can easily set SSL certificates in Google Cloud Platform with Google Domains.

CLOUD HOST

As I mentioned above, I chose the plan “f1-micro (1 vCPU, 0.6 GB memory)” is free and an extra 10G hard disk and a static IP which only costs you just a few bucks per month.

OS AND SOFTWARE

Choose Ubuntu 20.04 as the operating system because it’s free, stable, and easily maintaining, Nginx as the webserver, WordPress as the website tool.

SSL CERTIFICATE

Use Let’s Encrypt‘s free SSL solution to apply SLL certificate by installing certbot on your server. there are very detailed documents for various operating systems in the certbot’s website. the whole process is as easy as a piece of cake.

OTHERS

WordPress has a lot of free plugins for your use. Google as well, for example, you can use Google Analytics to analyze your website’s visits, use Google Firebase for your site’s authentication solutions.

In summary

The solution will probably just cost you between $20 to $40 a year, then, you have a whole virtual machine, domain with SSL certificate, and website, so I think it’s the best for all developers, please comment if you have any questions or a better solution.

Categories
Web Development

Customize Zurb Foundation CSS in ReactJS

Use Zurb Foundation Layout Framework in ReactJS project and customize CSS by your requirements.

Add Foundation into your ReactJS project

Add foundation-sites and jquery into your project, the reason for adding jQuery is there are some Foundation javascript animations require Foundation initiation using jQuery.

$npm i foundation-sites jquery

Copy the default setting sass file from foundation-sites to your project, and you can customize any elements styles in _settings.css later.

$cp node_modules/foundation-sites/scss/settings/_settings.scss _settings.scss

Edit _settings.scss

...

@import 'util/util';  

// Change the above line to follow:
@import '~foundation-sites/scss/util/util';

...

Include the default settings in your sass file, then you can use the foundation HTML class in your JSX file.

// App.scss
@import "settings";
@import "~foundation-sites/scss/foundation";
@include foundation-everything;

// Example of changing the top bar background colour
.top-bar {
  background: #ff0000;
  .menu {
    background: #ff0000;
  }
}

There are some Foundation components using javascript so you need to activate the foundation HTML code by initiating it as below

import React, {useCallback, useEffect} from 'react';
import $ from 'jquery';
import Foundation from 'foundation-sites';

export default function () {

    const foundationTopNav = useCallback(node => {
        if ( node !== null ) {
            $(node).foundation();  // Initiate Foundation code at here.
        }
    })

    return (
        <div ref={foundationTopNav}>
            <div className="title-bar" data-responsive-toggle="responsive-menu" data-hide-for="medium">
                <button className="menu-icon" type="button" data-toggle="responsive-menu"></button>
                <div className="title-bar-title">Menu</div>
            </div>
            <div className="top-bar" id="responsive-menu">
                <div className="top-bar-left">
                    <ul className="dropdown menu"  data-responsive-menu="drilldown medium-dropdown">
                        <li className="menu-text">Site T1itle</li>
                        <li>
                            <a href="#">One1</a>
                            <ul className="menu vertical">
                                <li><a href="#">One</a></li>
                                <li><a href="#">Two</a></li>
                                <li><a href="#">Three</a></li>
                            </ul>
                        </li>
                        <li><a href="#">Two</a></li>
                        <li><a href="#">Thre1e</a></li>
                    </ul>
                </div>
                <div className="top-bar-right">
                    <ul className="menu">
                        <li><input type="search" placeholder="Search" /></li>
                        <li>
                            <button type="button" className="button">Search</button>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    )
}