Advanced Node.js

By 增廣建文

Agenda

  • Useful Tools
    • Webpack
    • ESLint
    • Nodeman
  • More Syntax
    • Async/ Await

Yarn

許多人會使用FB開發的yarn取代預設的npm來當套件的管理工具

他具有以下的幾點優勢

  • 下載與安裝套件的速度更快
  • 能夠在同台server上共享cache
  • CLI介面相較npm也更美觀、簡潔

Windows用戶的安裝方式非常簡單,只要用npm install yarn --g

裝成全域套件可以方便我們在任何地方呼叫yarn

可以透過yarn --version確認是否成功安裝

Webpack

通常在寫JS code時檔案都會相當的零散,webpack可以幫我們把code打包成一個bundle

在使用上我們只要設定程式的起始點(entry)以及最後輸出的bundle名稱即可

他也可以搭配babel或是ts-node來把JS/ TS code給轉成標準格式

通常前端框架在創建專案時就會幫你設定好webpack + babel, ex: Create React App

要先來安裝套件 npm install webpack webpack-cli --save-dev

webpack 預設的起始路徑是./src/index.js,而輸出的位置則是在./dist/main.js

如果你的檔案路徑本來就是這樣安排,可以直接透過webpack來打包檔案成bundle

如果是其他的檔案命名或是資料夾擺法就要額外設定

Setup Webpack 1/2

首先要裝幾個套件,npm install -D webpack-node-externals babel-loader

// webpack.config.js
const nodeExternals = require('webpack-node-externals');
const path = require('path');
// nodeExternals()可以避免把沒有用的套件全部bundle起來
module.exports = {
  target: 'node',
  externals: [nodeExternals()],
  module: {   //設定你的檔案選項
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      },
    ],
  },
}

Setup Webpack 2/2

像是entry point以及output也可以去設定

// webpack.config.js
module.exports = {
// ...
 entry: {
    'index': './src/index.js',
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].bundle.js',
    libraryTarget: 'commonjs2',
  },
}

webpack -w可以在檔案有異動時就立刻重新bundle
webpack -p可以產出production的版本

Webpack Loader

loader要額外安裝,npm install file-loader --save-dev

// index.js
import WebpackLogo from "file-loader!./webpack-logo.png";

function logo(url) {
  const element = new Image();

  element.src = url;

  return element;
}

document.body.appendChild(logo(WebpackLogo));

file-loader!表示要經過file-loader的pipe才會把圖讀入

Webpack Plugin

舉個比較常用的例子就是CopyWebpackPlugin,能自動複製檔案到別的資料夾

一樣得額外安裝 npm install copy-webpack-plugin --save-dev

// webpack.config.js
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [{ from: path.resolve(__dirname, "public") }],
    }),
  ],
};

這樣設定完後就會自動將public內的檔案給複製一份到./dist資料夾去

ESLint

與babel搭配的舊版套件 babel-eslint 已經停止維護

透過Lint的管理機制可以確保團隊成員的codeing style都一致

使用npx eslint --init可以選擇此專案想要follow的style

搭配babel使用的安裝方式 npm install eslint @babel/eslint-parser --save-dev

然後要在設定檔內指名要使用babel當作parser

// .eslintrc
{
  "parser": "babel-eslint"
}

ESLint - Usage

以前如果要使用Airbnb定義的coding style
還要額外去安裝套件eslint-config-airbnb-base 以及 eslint-plugin-import

可以透過指定npx eslint index.js去查看指定檔案有沒有違反規定的部分

如果要自動修正違反規定的部分可以用npx eslint --fix index.js

寫進script的執行方式會比較特別npm run lint -- --fix

// package.json
"scripts": {
  "lint": "eslint src/**/*.ts"
}

VScode和Webstorm都有相關套件能在寫code時就自動幫忙檢查Lint規則

Two Dashes in NPM Command

前面在執行eslint的script中需要加上兩條dash是為了避免npm start把參數拿去用

這項設定也有寫在npm的官方文件中

npm run <command> [-- <args>]

Prettier

Dotenv

先透過npm來安裝此套件npm i dotenv

dotenv可以幫我將設定檔.env內的變數在每次執行程式時給load到系統的環境變數內

// .env
PORT=3000

再來只要load dotenv套件,他就會自動把.env檔案內的變數給存進PROCESS.ENV

require('dotenv').config()

console.log(process.env.PORT)

Nodemon

自動監看指定檔案,發現異動後執行特定指令 npm install --save-dev nodemon

假設今天還要自動編譯index.js nodemon src/index.js --exec babel-node

要監看指定資料夾下所有的檔案要改用nodemon --watch src src/server.js

如果把這行寫進script就可以避免每次要打一串指令的麻煩

{
    "script":{
        "auto-start": "nodemon --watch src src/index.js --exec babel-node"
    }
}

Ngrok 1/2

安裝軟體後就可以透過Ngrok將外部的request導向我們的API/ Web Server

用docker裝最省事,但是得先註冊帳號取得Auth Token

https://dashboard.ngrok.com/signup

docker run -it -e NGROK_AUTHTOKEN=<token> ngrok/ngrok http 9443

http後面是要將那些服務給expose到外網

Ngrok 2/2

可以在輸出的介面看到目前對應到外網的網址,免費版在每次服務重啟就會更動網址

Session Status                online
Account                       xxx@gmail.com (Plan: Free)
Update                        update available (version 3.0.4, Ctrl-U to update)
Version                       3.0.3
Region                        Japan (jp)
Latency                       41.6571ms
Web Interface                 http://0.0.0.0:4040
Forwarding                    https://0cfd-xxx-xxx-xx-xxx.jp.ngrok.io -> 
                              http://localhost:9443

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00 

Postman

雖然可以用curl等指令來測試我們的API,但有時候還是有GUI會比較方便

Forever

類似的功能也可以用docker搭配restart和health check來達成

使用forever可以讓我們的程式變成process在背景自動執行與重啟

使用npm i forever就能安裝,假設今天要一直跑的是index.js

我們只要將啟動指令改成npx forever start index.js即可

要停止時就使用npx forever stop index.js或是npx forever stopall關掉全部

如果要在程式碼有異動時就自動重啟需要加上-w, npx forever start -w index.js

使用npx forever list除了可以看到所有forever管理的process外,還會將log給寫入當前目錄下的.forever資料夾內

More Syntax

Syntax

還有一些常用到的部分要提

  • promise, then
  • async/ await
  • JSON

Advance Syntax

在處理array時還有一些常會用到的methods:

  • map
  • reduce
  • filter
  • find

JWT

Mocha

Bcrypt

Reference

如果要web interface可以加上--p 3000:4040