2019年7月18日 星期四

Typescript + Webpack (使用 ts-loader ) 練習

在"Typescript + Webpack (or SystemJs) 練習"這篇文章中,使用了多次指令分別去:
1. 用 npm 去 install 要的工具
2. 用 tsc 去使用 typescript 編譯
3. 用 webpack 去使用 webpack 打包程式

這次要來紀錄只使用 npm 指令,
因為 npm 的 package.json 可以設定 script 來方便的執行 command line 的指令,
而 webpack 可以用各種 loader 來處理項任務,其中 ts-loader 可以處理 typescript 的任務,
所以我們可以讓npm 去呼叫 webpack ,webpack 去呼叫 typescript 去完成任務。

這次的檔案結構跟上次差不多,如下所示:

其中,js 資料夾裡的檔案是 webpack 搭配 ts-loader 編擇 src資料夾下檔案所產生出來的,
package-lock.json不用管它,因為是npm 自已產生的。

我們先看看 Greeter.ts 和 test.ts :
Greeter.ts :
export class Greeter{
    name : string;
    constructor(name :string){
        this.name = name;
    }
    greet(){
        console.log("Hello, HIHI, " + this.name);
        alert("Hello, HIHI, " + this.name);
    }
}

test.ts :
import {Greeter} from "./Greeter";
 
let name : string = "Hugo";
let greeter : Greeter = new Greeter(name);
greeter.greet();

可以注意的是,在 test.ts 中 import 的Greeter可以只有檔名而沒有副檔名,因為在webpack.config.js中,有設定resolve {extensions : ['.js', '.ts']} 的設定。
接著我們來看看 npm的package.json、tyscript的tsconfig.json和webpack的webpack.config.js
三個 config 檔的內容:


package.json :
{
  "name": "webpacktypescripttest",
  "scripts": {
    "devEnvBuild": "npm install --save-dev typescript ts-loader webpack webpack-cli",
    "deploy": "webpack"
  },
  "devDependencies": {
    "ts-loader": "^6.0.4",
    "typescript": "^3.5.3",
    "webpack": "^4.36.1",
    "webpack-cli": "^3.3.6"
  }
}

tsconfig.json :
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "sourceMap": true,
    // "outDir": "./dist", //不需要
    "strict": true,
    "esModuleInterop": true    
  }
}

webpack.config.js :
var path = require('path');
module.exports = {
    entry: "./src/test.ts",
    output: {
        path: __dirname + "/js",
        filename: "test.js"
    },
    watch: false,
    devtool : 'source-map',
    mode : "production",
    resolve : {
     extensions : ['.js', '.ts']
    },
    module: {
     rules: [
       { 
        test: /\.ts$/, 
        use: 'ts-loader',
        include: path.resolve(__dirname, 'src')
       }
     ]
 }
}

可以注意到,在 tsconfig.json 中,我們不需要寫 outDir 來指定 typescript 的輸出位置,
其實就算指定了,經過 webpack 用 ts-loader 來執行 typescript 時,
也不會在 outDir 指的地方出現輸出的檔案。

先假設整個環境除了 npm 以外都沒建置完成,即 webpack, typescript, ts-loader.... 等
先用 command line 視窗到 webpackTypescriptTest 資料夾的路徑,
執行指令:
npm run devEnvBuild
就可以執行已經寫在 package.json 中,script 裡,devEnvBuild的指令,等同於執行
npm install --save-dev typescript ts-loader webpack webpack-cli
接著再執行
npm run deploy
就可以發現在 js 資料夾中,檔案被產生出來了,其中已經包括了 typescript的編擇和 webpack 的打包
可以注意到的是,在 webpack.config.js 中 ,
我們用了 module 設定了 ts-loader 來為 ts 檔在打包前進行了 typescript 的編譯。

最後我們在 index.html 中就可以使用 src/test.js 了 :

index.html :

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

原始碼下載:
webpackTypescriptTest.7z

參考資料:
  1.  TypeScript | webpack
  2. TYPESCRIPT合成WEBPACK中