BrowserSync, Gulp and TypeScript

I was creating a simple web app with VueJS (without cli, no single file component) and I thought it would be good to have a local server which watches changes, auto-transpiles TypeScript and later maybe builds(minify, terser, copy files etc.) for the production. By using BrowserSync & Gulp, a typescript project can be easily watched, and the browser can be auto-reloaded in case of any changes. Let’s assume we have .ts files and index.html in “src” folder. The following gulpfile compiles the TS files into “dist” folder, watches for the changes and reloads the browser in case of changes. It still requires the build function for the production but it would be similar to development function, maybe terser plugin can be added.

const { series, watch, src, dest } = require('gulp');
var ts = require('gulp-typescript');
var sourcemaps = require('gulp-sourcemaps');
var tsProject = ts.createProject('tsconfig.json');
var server = require('browser-sync').create();

const paths = {
    scripts: {
        ts: 'src/*.ts',
        dest: 'dist/js/'
    }
};

function reload(done) {
    server.reload();
    done();
}

function serve(done) {
    server.init({
        server: {
            baseDir: './dist'
        }
    });
    done();
}


let development = function() {
    src('./index.html').pipe(dest('./dist/'));
    src('./css/**/*').pipe(dest('./dist/css'));
    src('./src/*.json').pipe(dest('./dist'));
    src('./assets/**/*').pipe(dest('./dist/assets/'));
    return tsProject.src()
        .pipe(sourcemaps.init())
        .pipe(tsProject())
        .pipe(sourcemaps.write())
        .pipe(dest('./dist/js/'));
};

const mywatcher = () => {
    console.log(paths.scripts.ts)
    const watcher = watch(paths.scripts.ts, series(development, reload))
    watcher.on('change', (path) => {
        console.log(`File ${path} was changed.`);
    });
};
const dev = series(development, serve, mywatcher );
exports.default = dev;

Another simple example. It uses terser and browsersync, dist folder is alway ready to deploy. It is for single js file but can be modified:

const { series, watch, src, dest } = require('gulp');
const terser = require('gulp-terser');
var server = require('browser-sync').create();

function copyAssets() {
    return src('src/assets/*')
        .pipe(dest('dist/assets'));
}

function copy() {
    return src('./src/app.js')
        .pipe(terser({
            mangle: { toplevel: true },
            compress: true
        }))
        .pipe(src('src/index.html'))
        .pipe(src('src/style.css'))
        .pipe(src('_redirects'))
        .pipe(dest('dist/'));
}

function reload(done) {
    server.reload();
    done();
}

function serve(done) {
    server.init({
        server: {
            baseDir: './dist'
        }
    });
    done();
}


const watcher = () => {
    const watcher = watch('src', series(copyAssets, copy, reload))
    watcher.on('change', (path) => {
        console.log(`File ${path} was changed.`);
    });
};
exports.default = series(copyAssets, copy, serve, watcher);

There is a gulp plugin for the same purpose: https://www.npmjs.com/package/gulp-webserver

Use browsersync to start a server from a folder and watch all the files for changes:

 browser-sync start --server './' --files './'

Links:
1. https://www.browsersync.io/docs/gulp
2. https://gulpjs.com/docs/en/api/watch
3. https://css-tricks.com/gulp-for-beginners/
#typescript #gulp #vuejs #javascript

Compiling vs Transpiling

A question that I heard recently: Compiling vs Transpiling 

It seems that Wikipedia has enough information as well: “A source-to-source compiler, transcompiler or transpiler is a type of compiler that takes the source code of a program written in one programming language as its input and produces the equivalent source code in another programming language. A source-to-source compiler translates between programming languages that operate at approximately the same level of abstraction, while a traditional compiler translates from a higher level programming language to a lower level programming language.”

Here is the part that NativeScript has in its tooling section: https://docs.nativescript.org/tooling/transpilers

Well, considering how Typescript plays an important role nowadays, transpiling will be a term that we hear a lot.

#typescript #angular #nativescript

TypeScript Notes – Type assertions

Type assertions are a way to tell the compiler “trust me, I know what I’m doing.” A type assertion is like a type cast in other languages, but performs no special checking or restructuring of data. It has no runtime impact, and is used purely by the compiler. TypeScript assumes that you, the programmer, have performed any special checks that you need.

1. Way


let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;

2. Way

let someValue: any = "this is a string";

let strLength: number = (someValue as string).length;

Resource: TypeScript Handbook

#type-assertions, #typescript

TypeScript Notes – Primitive Types

Types

Boolean

The most basic datatype is the simple true/false value, which JavaScript and TypeScript call a boolean value.


let isDone: boolean = false;

Number

As in JavaScript, all numbers in TypeScript are floating point values. These floating point numbers get the type number. In addition to hexadecimal and decimal literals, TypeScript also supports binary and octal literals introduced in ECMAScript 2015.


let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;

String


let color: string = "blue";
color = 'red';

let fullName: string = `John Doe`;
let age: number = 27;
let sentence: string = `Hello, my name is ${ fullName }.
I'll be ${ age + 1 } years old next month.`;

Array

let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

Tuple

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ["hello", 10]; // OK
// Initialize it incorrectly
x = [10, "hello"]; // Error

console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'<span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>

Enum

enum Color {Red, Green, Blue}
let c: Color = Color.Green;

enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;

enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;

enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];

alert(colorName);

Any

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

let list: any[] = [1, true, "free"];

list[1] = 100;

Void

void is a little like the opposite of any. void means the absence of having any type at all. void type is mainly used as the return type of functions that do not return a value:

function warnUser(): void {
    alert("This is my warning message");
}

Null and Undefined

void is a little like the opposite of any. void means the absence of having any type at all. void type is mainly used as the return type of functions that do not return a value:

// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;

#primitive-types, #typescript

Reverse an array

You know there is array.reverse() function, sharing the snippet below just in case wondering how to do it. We iterate half of the lentgh, guess why?

let array = [1, 2, 3, 'Siesta', 5, 6, 7, 7, 'Spain'];
for (let i = 0; i < array.length / 2; i++) {
    let val= array[i];
    array[i] = array[array.length - i - 1];
    array[array.length - i - 1] = val;
}
console.log(array);

#array #typescript #javascript