const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
path: __dirname,
filename: "app.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
plugins: [
[
"@babel/plugin-transform-runtime",
{
regenerator: true
}
]
]
}
}
}
]
},
target: "node",
node: {
__dirname: false,
__filename: false
},
externals: {
fs: "commonjs fs"
},
mode: "development"
};
Friday, March 27, 2020
webpack config
https://github.com/Microsoft/TypeScript-Babel-Starter
Sunday, March 22, 2020
Data Validation using Decorator in Typescript
In index.html we have
<form> <input type="text" placeholder="Course Title" id="title" /> <input type="text" placeholder="Price" id="price" /> <button type="submit">Submit</button> </form>and inside our ts (transpiled into js file and link it into our index.html), we write:
enum Validation {
required = "required",
positive = "positive"
}
interface ValidatorConfig {
[property: string]: {
[validatableProp: string]: Validation[]; //e.g., [Validation.required, Validation.positive]
};
}
const registeredValidators: ValidatorConfig = {};
function Required(target: any, propName: string) {
//we don't have propertyDescriptor for property, it exists only for methods
registeredValidators[target.constructor.name] = {
...registeredValidators[target.constructor.name],
[propName]: [Validation.required]
};
}
function Positive(target: any, propName: string) {
registeredValidators[target.constructor.name] = {
...registeredValidators[target.constructor.name],
[propName]: [Validation.positive]
};
}
function validate(obj: any) {
const objValidatorConfig = registeredValidators[obj.constructor.name];
if (!objValidatorConfig) {
return true;
} else {
let validated = true;
for (const prop in objValidatorConfig) {
for (const validator of objValidatorConfig[prop]) {
if (validator === (Validation.required as string)) {
console.log("run?");
validated = validated && obj[prop].trim().length > 0;
}
if (validator === (Validation.positive as string)) {
validated = validated && obj[prop] > 0;
}
}
}
return validated;
}
}
class Course {
@Required
public title: string;
@Positive
public price: number;
constructor(t: string, p: number) {
this.title = t;
this.price = p;
}
}
const courseForm = document.querySelector("form")!;
courseForm.addEventListener("submit", e => {
e.preventDefault();
const titleEl = document.getElementById("title") as HTMLInputElement;
const priceEl = document.getElementById("price") as HTMLInputElement;
const title = titleEl.value;
const price = +priceEl.value;
const newCourse = new Course(title, price);
if (!validate(newCourse)) {
alert("Invalid input, please try again!");
return;
}
console.log(newCourse);
});
Sunday, March 15, 2020
Wordpress Study Notes
Extension in VSCode
- I install beautify for cleaning up the indentations of both php and html code at the same time.
- I also install PHP Intelephense to give auto completion on html tag.
Prelude
Hierarchy of wordpress php files: Assume that we have a post type called "program", as registered by using
<?php
function university_post_types()
{
//Program Post Type
register_post_type("program", array(
'supports' => array('title', 'editor'),
'rewrite'=>array('slug'=>'programs'),
'has_archive' => true,
'public' => true,
'labels' => array(
'name' => 'Programs',
'add_new_item'=>'Add New Program',
'edit_item'=>'Edit Program',
'all_items'=> 'All Programs',
'singular_name' => 'Program'
),
'menu_icon' => 'dashicons-awards'
));
}
add_action("init", "university_post_types");
?>
inside \wp-content\mu-plugins\*.php (mu stands for "must-use") , then we get:in our dashboard. This is a kind of customized post type, therefore we will create a php file that is dedicated to customizing post of type "program".
Wednesday, March 4, 2020
php installation
- Follow the link to install php
https://www.youtube.com/watch?v=4_-12QSaaFg - Following this to install xampp:
https://www.youtube.com/watch?v=TjFRTkw6GDQ - visual studio plug-in that I have used:
1. phpfmt - PHP formatter
2. Format HTML in PHP
refer to my config file sent in gmail
Tuesday, March 3, 2020
Factory Design Pattern in Typescript
Javascript is not enough to implement ordinary factory design patternt that I want to mimic from C#, therefore I try to do it on Typescript, though nested class declaration is still not that straight forward in typescript:
class Point {
x: number;
y: number;
private constructor(x: number, y: number) {
this.x = x;
this.y = y;
}
static Factory = class {
static pointXY(x: number, y: number) {
return new Point(x, y);
}
static pointPolar(r: number, theta: number) {
return new Point(
r * Math.cos((theta * Math.PI) / 180),
r * Math.sin((theta * Math.PI) / 180)
);
}
};
}
now we can create our point by calling
const pt = Point.Factory.pointXY(10, 20);
Monday, February 17, 2020
Certbot
SSH into our ubuntu device and do the following. The commands are subject to changes, we should use all latest relevant commands from certbot's website.
$ sudo apt update $ clear $ sudo apt install apache2 $ cd /etc/apache2/sites-available/ $ clear $ ls $ sudo vi ridiculous-inc.com.conf $ cd /var/www $ sudo git clone https://github.com/ridiculous-ijquery-todo.git ridic $ sudo a2ensite ridiculous-inc.com.conf $ sudo service apache2 restart $ sudo apt-get update $ clear $ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:certbot/certbot $ clear $ sudo apt-get update $ sudo apt-get install python-certbot-apache $ clear $ sudo certbot --apache $ historyand
<VirtualHost *:80>
DocumentRoot /var/www/ridic
ServerName ridiculous-inc.com
<Directory "/var/www/ridic">
allow from all
AllowOverride All
Order allow,deny
Options +Indexes
</Directory>
</VirtualHost>
To redirect request to port 80 to other internal port we use the following setting of virtualhost:
<VirtualHost *:80>
ServerName api.screencapdictionary.com
<Location "/">
ProxyPreserveHost On
ProxyPass http://localhost:5000/
ProxyPassReverse http://localhost:5000/
</Location>
</VirtualHost>
Saturday, February 8, 2020
Git command that I should know
Configuration
git config --global --editThis will open the .gitconfig file by our default editor. Make changes, save, and close the editor, changes will take place. To view the changes:
git config --global --list
Branches
List out all branches:git branch -aCreate new branch:
git branch mynewbranchswitch to new branch:
git checkout mynewbranchRename a branch (-m for move, as in mv in bash command):
git branch -m mynewbranch newbranchDelete a branch:
git branch -d newbranch
Specific branch
git clone a specific branch instead of all the branches and checkout specific one. For example, in my private repo I want to clone the "forth-branch" only, then write:git clone --single-branch --branch forth-branch https://github.com/machingclee/2020-English-Learning-Website.gitwithout --single-branch the above will fetch all branches and checkout the forth-branch.
P4Merge Configuration
git config --global merge.tool p4merge git config --global mergetool.p4merge.path "C:/Program Files/Perforce/p4merge.exe" git config --global mergetool.prompt false git config --global diff.tool p4merge git config --global difftool.p4merge.path "C:/Program Files/Perforce/p4merge.exe" git config --global difftool.prompt falseand
git config --global --list to double check the configuration:
core.editor="C:\Users\Ching-Cheong Lee\AppData\Local\Programs\Microsoft VS Code\Code.exe" --wait user.name=James Lee user.email=machingclee@gmail.com color.ui=true merge.tool=p4merge mergetool.p4merge.path=C:/Program Files/Perforce/p4merge.exe mergetool.prompt=false diff.tool=p4merge difftool.p4merge.path=C:/Program Files/Perforce/p4merge.exe difftool.prompt=false
Subscribe to:
Posts (Atom)
