Webpackでsassとtypescriptの環境を作る

package.json

{
  "name": "front",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server --mode development --env development",
    "dev": "webpack-dev-server --mode development --env development",
    "build": "webpack --mode production"
  },
  "keywords": [],
  "author": "hpscript",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.12.13",
    "@babel/preset-env": "^7.12.13",
    "@babel/preset-react": "^7.12.13",
    "babel-loader": "^8.2.2",
    "css-loader": "^5.0.2",
    "mini-css-extract-plugin": "^1.3.6",
    "node-sass": "^5.0.0",
    "optimize-css-assets-webpack-plugin": "^5.0.4",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "sass-loader": "^11.0.1",
    "style-loader": "^2.0.0",
    "ts-loader": "^9.2.6",
    "typescript": "^4.4.3",
    "webpack": "^5.53.0",
    "webpack-cli": "^4.8.0",
    "webpack-dev-server": "^4.2.1"
  },
  "description": ""
}

webpack.config.js

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
	entry: {
		anyname: `./src/scss/style.scss`,
		bundle: './src/app.ts'
	},
	output: {
		path: path.join(__dirname,'dist'),
		filename: '[name].js'
	},
	resolve: {
		extensions:['.ts','.js']
	},
	devServer: {
		host: '192.168.34.10',
        port: '8000',
        static: "./dist",
        open: true
	},
	module: {
		rules: [
			{
				test:/\.ts$/,use:'ts-loader'
			},
			{
                test: /\.scss$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },
                    { loader: 'css-loader' },
                    { loader: 'sass-loader' },
                ],
            }
		]
	},
	plugins: [
        new MiniCssExtractPlugin({ filename: 'css/style.css'}),
    ],
    optimization: {
        minimizer: [new OptimizeCSSAssetsPlugin({})],
    },
}

tsconfig.json

環境構築まではOK^^

[ TypeScript ] 環境構築でWebsocketServer.js:10エラーになる時

### コンパイラ導入
$ node -v
v10.19.0
$ sudo npm install -g typescript
$ tsc -v
Version 4.4.3

hello.ts

const message:string = 'Hello! TypeScript!'
console.log(message);

$ tsc hello.ts
$ ls
hello.js hello.ts
$ node hello.js
Hello! TypeScript!

### npm環境
$ npm install typescript ts-loader webpack webpack-cli webpack-dev-server –save-dev

package.json

  // 省略
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode=development",
    "start": "webpack-dev-server --mode=development"
  },
    // 省略

webpack.config.js

const path = require('path');
module.exports = {
	entry: {
		bundle: './src/app.ts'
	},
	output: {
		path: path.join(__dirname,'dist'),
		filename: '[name].js'
	},
	resolve: {
		extensions:['.ts','.js']
	},
	devServer: {
		contentBase: path.join(__dirname,'dist')
	},
	module: {
		rules: [
			{
				test:/\.ts$/,loader:'ts-loader'
			}
		]
	}
}

$ tsc –init
-> tsconfig.json が生成される

dist, srcフォルダを作成する

src/app.ts

import {Item} from './item';
var elem = document.getElementById('output');
var aBook = new Item('はじめてのTypeScript', 2020);
aBook.say(elem);

src/item.ts

export class Item {
	constructor(private name:string, private price:number){}

	public say(elem: HTMLElement | null) : void {
		if(elem){
			elem.innerHTML = '書名:' + this.name + ' 価格: ' + this.price + '円';
		}
	}
}

dist/index.html

<body>
	<div id="output"></div>
	<script src="bundle.js"></script>
</body>
</html>

$ npm run start

> tutorial@1.0.0 start /home/vagrant/dev/typescript/tutorial
> webpack-dev-server –mode=development

[webpack-cli] /home/vagrant/dev/typescript/tutorial/node_modules/webpack-dev-server/lib/servers/WebsocketServer.js:10
static heartbeatInterval = 1000;

何でだろう? なんかエラーになるな。。

$ sudo apt-get purge nodejs

▼この記事を参考に最新版を入れる
https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-20-04-ja

$ cd ~
$ curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
$ sudo bash nodesource_setup.sh
$ sudo apt install nodejs
$ node -v
v14.17.6
$ npm run start

http://192.168.34.10:8000/

nodeがv10だとwebpack-dev-serverでエラーになるみたい 
https://github.com/VickScarlet/lifeRestart/issues/176
v14にupgradeするとエラー解消
マジかよ~~~~ もうやだー

typescript入門

$ npm –version
$ npm init
$ sudo npm install typescript
$ echo export PATH=\$PATH:`pwd`/node_modules/.bin >> ~/.bashrc
$ source ~/.bashrc
$ tsc –version
Version 4.2.4

function hello(name: string): void {
	console.log("Hello " + name + "!");
}
let your_name: string = "Yamada";
hello(your_name);

$ tsc sample.ts
$ node sample.js
Hello Yamada!

TypeScript 3

class User {
	constructor(private _name: string){
	}

	public sayHi(): void {
		console.log("hi i am" + this._name);
	}
	get name(){
		return this._name;
	}
	set name(newValue: string){
		this._name = newValue;
	}
}

var tom = new User("Tom");
console.log(tom.name);
tom.sayHi();
console.log(tom.name);
tom.sayHi();
class User {
	constructor(protected _name: string){
	}

	public sayHi(): void {
		console.log("hi i am" + this._name);
	}
}

class AdminUser extends User {
	private _age: number;
	construtor (_name: string, _age: number){
		super(_name);
		this._age = _age;
	}
	public sayHi(): void {
		console.log("my age: " + this._age);
		console.log("my name: " + this._name);
		super.sayHi();
	}
}

var bob = new AdminUser("Bob", 23);
bob.sayHi();
class User {
	name: string;
	constructor(name: string){
		this.name = name;
		User.count++;
	}
	sayHi(): void {
		console.log("hi! i am" + this.name);
	}
	static count: number = 0;
}

var tom = new User("Tom");
var bob = new User("Bob");
console.log(User.count);
// interface
interface Result{
	a: number;
	b: number
}

function getTotal(result: Result){
	return result.a + result.b;
}

var result = {
	a: 32,
	b: 55
};

console.log(getTotal(result));

// interface
interface SpringResult {
	a: number;
}
interface FallResult {
	b: number;
}
interface FinalResult extends SpringResult, FallResult{
	final: number;
}


function getTotal(result: FinalResult){
	return result.a + result.b + result.final;
}

var result = {
	a: 32,
	b: 55,
	final: 67
};

console.log(getTotal(result));
interface GameUser{
	socre: number;
	showScore(): void;
}

class User implements GameUser {
	name: string;
	score : number = 0;
	constructor(name: string){
		this.name = name;
	}
	sayHi(): void {
		console.log("hi, i am" + this.name);
	}
	showSchore(): void {
		console.log("score" + this.score);
	}
}
// generics

function getArray<T>(value: T): T[]{
	return [value, value, value];
}

console.log(getArray<number>(3))
class MyData<T>{
	constructor(public value: T){}
	getArray(): T[]{
		return [this.value, this.value, this.value];
	}
}
var v1 = new MyData<string>("hello");
console.log(v1.getArray());
var v2 = new MyData<number>(234);
console.log(v2.getArray());
// 内部モジュール

module UserModule {
	export var name = "sato";
	export moudle AddressModule {
		export var zip = "111-1111";
	}
}
console.log(UserModule.name);
console.log(UserModule.AddressModule.zip);
// 外部モジュール

import User = require("./user_commonjs")
console.log(User.name);

[vagrant@localhost typescript]$ tsc main.ts -m commonjs

TypeScript 2

web:https://www.typescriptlang.org/

typescriptはtsとjsを共存して書ける
main.ts

class User {
	
}
console.log("hello world");

main.js

var User = /** @class */ (function () {
    function User() {
    }
    return User;
}());
console.log("hello world");

変数の後にコロンを入れて型を宣言する

var x: number = 10;
x = "hello";

// number, string, boolean, any
var i: number;
var i = 10; // i:number 型推論

var x; // var x:any

var results: number[]; // 配列の宣言
results = [10, 5, 3];

列挙型

// 列挙型
enum Signal {
	Red = 0,
	Blue = 1,
	Yello = 2
}
var result: Signal;
console.log(Signal[2]);

// 列挙型
enum Signal {
	Red,
	Blue = 3,
	Yello
}
var result: Signal;
console.log(Signal[3]);

enum Signal {
	Green = 6
}

拡張もできる

関数
型制限を間違えるとコンパイル時にエラーになる

function add(a:number, b:number) : number{
	return a + b;
}
console.log(add(5, 3));

function add(a:number, b:number) : number{
	if(b){
		return a + b;
	} else {
		return a + a;
	}
}

関数式

var add = function(a: number, b: number){
	return a + b;
}

var add = (a: number, b: number): number =>{
	return a + b;
}

オーバーロード

function add(a: number, b: number): number; // シグネチャ
function add(a: string, b: string): string;

function add(a: any, b: any): any {
	if(typeof a === "string" && typeof b === "string"){
		return a + " " + b;
	}
	return a + b;
}

class

class User {
	public name: string;

	constructor(name: strin){
		this.name = name;
	}

	sayHi(): void {
		console.log("hi i am" + this.name);
	}
}

var tom = new User("Tom");

TypeScript 1

TypeScriptとは?
– Microsoftによって開発されたJavaScript拡張言語
– 静的型付クラスベースオブジェクト言語
– AngularJSもTypeScript推奨
– TypeScript作者はC#の制作者(マジかよ)

JSでの大規模開発向けか?
TypeScriptの求人を眺めているとロジック実装が多そうではある

$ sudo npm install -g typescript
$ tsc -v
Version 3.7.2

hello.ts

class test{
	constructor(public Text: string){}

	helloShow()
	{
		return this.Text;
	}
}

var msgStr = new test("Hello World!");
document.body.innerHTML = msgStr.helloShow();

[vagrant@localhost typescript]$ tsc hello.ts
[vagrant@localhost typescript]$ ls
hello.js hello.ts node_modules package-lock.json

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>

</head>
<body>
<script src="hello.js"></script>
</body>
</html>

TypeScript tutor

静的型付け

var x:number  = 10;
x = "hello";

コンパイルエラーとなります。

var x:number  = 10;
x = "hello";

様々な型

// number, string boolean, any
var i = 10;
var x; // var x: any

var results: number[]
results = [10, 5, 3]

列挙型

enum Signal {
  Red = 0,
  Blue = 1,
  Yellow = 2
}
var result: Signal;

// if (result === Signal.Yellow){}
// if (result === Signal['Yellow']){}
console.log(Signal[2])

関数宣言

function add(a: number, b?: number): number {
 if (b){
 return a + b;
 } else{
 return a + a;
 }
}

console.log(add(5, 3));

関数式

var add = (a: number, b: number): number =>{
 return a + b;
}
var add = (a: number, b: number): number => a + b
console.log(add(5, 3));

関数のオーバーロード

function add(a: number, b: number): number; //シグネチャ
function add(a: string, b: string): string;

function add(a: any, b: any): any {
 if(typeof a === "string" && typeof b === "string"){
 return a + " " + b;
 }
 return  a + b;
}
console.log(add(5, 3));
console.log(add("hello", "world"));

class

class User {
  name: string;
  constructor(name: string){
     this.name = name;
  }
  sayHi(); void {
  console.log("hi! i am " + this.name);
  }
}

var tom = new User("tom");
console.log(tom.name);
tom.sayHi();

getter, setter

class User {
  name: string;
  constructor(private _name: string){
     this.name = name;
  }
  sayHi(); void {
  console.log("hi! i am " + this.name);
  }
  get name(){
   return this._name;
  }
  set name(newValue: string){
    this._name = newValue;
  }
}

extends, override

class User {
  name: string;
  constructor(private _name: string){
     this.name = name;
  }
  sayHi(); void {
  console.log("hi! i am " + this.name);
  }
}

class AdminUser extends User{
 private _age: number;
 constructor(_name: string, _age: number){
  super(_name);
  this._age = _age;
 }
  public sayHi(): void {
    console.log("my age:" + this._age);
    super.sayHi();
  }
}

private:メソッドの中のみ可能
protected:クラスの中のみアクセス可能

静的メンバ:static

class User {
  name: string;
  constructor(private _name: string){
     this.name = name;
     User.count++;
  }
  sayHi(); void {
  console.log("hi! i am " + this.name);
  }
  static count: number = 0;
  
}

インターフェイス

interface Result {
  a: number;
  b: number;
}


function getTotal(result: {a: number; b: number}){
  return result.a + result.b;
}

var result = {
 a: 32,
 b: 58
};

console.log(getTotal(result));

interfaceの継承

interface SpringResult {
  a: number;
}

interface FallResult{
 b: number;
}

interface FinalResult extends SpringResult, FallResult {
 final?: number;
}

ジェネリクス

function getArray<T>(value: T): T[]{
 return[value, value, value];
}

console.log(getArray<number>(3));
console.log(getArray<string>("hello"));

ジェネリクスの制約

interface Result {
  a: number;
  b: number;
}


class MyData<T extends Result>{
  constructor(public value: T){}
  getArray(): T[]{
    return [this.value, this.value, this.value];
  }
}

内部モジュール

module UserModule{
  export var name = "yamada";
  export modlue AddressModlue {
     var zip = "123-4567"
  }
}

console.log(UserModule.name);
console.log(UserModlue.AddressModlue.zip);

Getting started Type Script

TypeScriptは大規模開発にも適したjavascriptの拡張ランゲージです。microsftが開発しています。npmでインストールします。

[vagrant@localhost typescript]$ sudo npm install -g typescript
/usr/bin/tsc -> /usr/lib/node_modules/typescript/bin/tsc
/usr/bin/tsserver -> /usr/lib/node_modules/typescript/bin/tsserver
typescript@2.0.10 /usr/lib/node_modules/typescript

拡張子はtsを使います。
main.ts

class User {

}

console.log("hello world")

変換後のjsファイルです。
main.js

var User = (function () {
    function User() {
    }
    return User;
}());
console.log("hello world");
[vagrant@localhost typescript]$ tsc main.ts
[vagrant@localhost typescript]$ ls
main.js  main.ts
[vagrant@localhost typescript]$ node main.js
hello world