自學 TypeScript 第三天 使用webpack打包 TS 程式碼

2022-11-18 12:00:30

前言:

大家好啊,昨天介紹了 TS 編譯器的設定,但在我們實際開發當中直接使用 TS 編譯器去編譯程式碼的情況會有,但沒有很多,因為我們在開發大型專案的時候,一般我們都會用到打包工具,也不可能脫離打包工具去使用 TS 

所以我們的 TS 在大多數情況下都是結合著打包工具去使用的,比如webpack,vite...

而今天我們就學習如何用 webpack 打包我們的 TS 程式碼

安裝:

首先第一步,我們要初始化我們專案,在目錄下輸入

npm init

接下來,我們的安裝幾個工具

npm i -D webpack webpack-cli typescript ts-loader

-D 意思是 開發依賴,也就是我們現在所安裝的依賴都是開發依賴,完整應該是 -dev -server 我們直接用 -D 簡寫

webpack 就是我們打包工具的一個核心程式碼

webpack-cli 是 webpack 的命令列工具,裝了以後我們可以通過命令列去使用

typescript 是 TS 的核心包

ts-loader 是 TS 的載入器,通過 ts-loader 可以讓 webpack 和 TS 進行整合,讓他們成為一體的

 下載成功之後,恭喜你,一個基礎的架子這就搭好了

接下來,和六扇老師一起,讓我們簡單的做一個基礎設定吧

基礎設定:

下載完成之後,我們可以看到我們的專案裡多了一個 node_modules 的資料夾,那是一些依賴不用去管

接下來在我們專案的根目錄裡建立一個名為 webpack.config.js 的檔案,以及一個 tsconfig.json 的檔案

用來設定我們的 webpack 和 TS ,目錄結構如下

開啟 webpack.config.js 進行設定

第一步,我們先參照一個 path 包 用來拼接路徑

const paht = require('path')

第二步,寫一個 module.exports 的物件,webpack 中所有的設定資訊都應該寫到我們的 module.exports 裡

第三步,寫一個 entry : " " ,

module.exports = {
    entry:"./src/index.ts",
}

意思是入口檔案,就是指定打包檔案位置

第四步,output :{ },裡面有倆個屬性一個是 path 一個是 filename 以及 environment

module.exports = {
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:"bundle.js",
     environment:{
      arrowFunction:false,
     }
    },
}

path 的意思是打包完成之後檔案存放的位置

ffliename 打包之後的檔案叫什麼

environment: arrowFunction 告訴 webpack 別使用箭頭函數了

第五步,module 物件,指定打包時候要用的模組

module.exports = {
    module:{
        rules:[
            {
                test:/\.ts$/, 
                use:'ts-loader',
                exclude:/node-modules/,
            }
        ]
    }
}

裡面有一個 rules 陣列用來指定載入規則,裡面接物件

test :正則,指定規則生效的檔案,/\.ts$/ :所有以 ts 結尾的檔案

use:指定要用的 loader

exclude : 要排除哪些檔案

 webpack.config.js 全部程式碼:

// 引入一個包
const path = require('path'); // 使用者拼接路徑

// webpack 中所有的設定資訊都應該寫到我們的 module.exports 裡
module.exports = {
    // 指定入口檔案
    entry:"./src/index.ts",

    // 指定打包檔案所在的目錄
    output:{
        path:path.resolve(__dirname,'dist'),
        // 打包後檔案的檔案
        filename:"bundle.js",
     // 告訴 webpack 不使用箭頭函數
     environment:{
      arrowFunction:false,
     } },
// 指定webpack 打包時要使用的模組 module:{ // 指定載入的規則 rules:[ { // test 指定的是規則生效的檔案 test:/\.ts$/, // 所有以 ts 結尾的檔案 use:'ts-loader', // 要排除的檔案 exclude:/node-modules/, } ] } }

這樣一個基礎的 webpack.config.js 設定就完成了

下面進行一個 taconfig.json 的設定,非常簡單

{
    "compilerOptions":{
        "module": "ES2015",
        "target": "ES2015",
        "strict": true,
    }
}

規定,所有規則為 ES2015,也就 ES6 規範,然後 strict 為 true 開啟最嚴格模式

然後還有最後一件事在我們的 package.json 裡面 scripts 裡面 新增一個命令

 什麼意思呢,就是通過 bukud 命令來執行我們的 webpack

經過這一系列步驟,我們的  webpack 和 TS 一個最基本的組合這就成型了,然後我們就可以在命令列中輸入

npm run build

之後我們看見,專案下出現 dist 目錄,裡面有一個 bundle.js 就證明我們成功了

 如果之前學過 webpack 的可以不用看了,因為往下都是關於 webpack 的設定了

 進階webpack打包:

 我們打包完成之後,有了一個單獨的 JS 檔案,但問題來了,怎麼使用呢?

這時有同學說了,六扇老師我直接建立一個 index.html 檔案,然後 srcipt src 引入不行嗎?

可以是可以,但是,很麻煩,而且將來檔案發生變化,或新增別的 JS 檔案還要手動的去改

 那怎麼做呢,這時就需要 webpack 的一個外掛了

第一步,下載 html-webpack-plugin

npm i -D -S html-webpack-plugin

什麼意思呢,就是自動的幫助我們生成 html 檔案

 第二步,在 webpack.config.js 引入我們的 html 外掛

const HTMLWebpackPlugin = require('html-webpack-plugin');

第三步,在 module.exports 裡面寫一個 plugins 屬性用來設定 webpack 外掛

module.exports = {
    plugins:[
        new HTMLWebpackPlugin(),
    ]
}

然後我們再執行打包命令,在我們的 dist 檔案下就會自動生成一個 index.html 檔案

當然我們也可以給生成的 html 檔案一個 html 模板,用 template 方法

module.exports = {
    plugins:[
        new HTMLWebpackPlugin({
            template:'./src/index.html',
        })
    ]
}

意思就是打包之後生成 index 繼承 src 下的 html 所生成的模板

 第二個外掛,webpack 的開發伺服器,就相當於在我們的專案裡面安裝了一個內建的伺服器

可以讓我們的專案在這個伺服器裡直接執行,而這個伺服器是跟隨我們專案有關聯的,它會跟隨我們的專案進行改動,自動去重新整理

npm i -D -S webpack-dev-server

下載成功之後,我們在 package.json 檔案裡面,剛才設定 build 的下邊設定一個 start

"start": "webpack serve --open chrome.exe"

 然後在命令列輸入

npm start 

就會自動開啟瀏覽器了

 第三個外掛,每一個編譯前,清空我們的 dist 目錄,然後把新檔案放進去,避免舊檔案殘留

npm i -D -S clean-webpack-plugin

和html-webpack-plugin 一樣,直接參照 clean-webpack-plugin

const { CleanWebpackPlugin } = require('clean-webpack-plugin');

然後在 plugins 裡面設定,直接加在 new HTMLWebpackPlugin 下邊或上邊就行

module.exports = {
    plugins:[
        new CleanWebpackPlugin(),
        new HTMLWebpackPlugin({
            template:'./src/index.html',
        })
    ]
}

好了,這樣就 ok 了,看不出什麼效果,沒報錯就成功了

第四個設定,在我們編寫 TS 引入其他 TS 檔案的時候,webpack 不知道我們的 TS 檔案可以當作一個模組去參照的,所以會報錯

這時候我們必須做一個設定,告訴 webpack 哪些檔案可以當作一個模組引入

直接設定,在 webpack.config.js 裡寫一個 resolve 用來設定參照模組

module.exports = {
    resolve:{
        extensions:['.ts','.js'] 
    }
}
設定 extensions 告訴 webpack 以 .ts 和 .js 結尾的都可以當模組去參照

 到這裡,如果我們不考慮一些相容性的問題,所以都必要設定都已經參照好了,多敲幾遍,熟悉幾遍

相容性:

 我們在寫程式碼的時候都會考慮一個相容性的問題,ES5啊,ES6啊,比如我們的老瀏覽器 IE 就不支援新 ES6 語法,這時候我們就需要把程式碼轉成其他版本的

而我們的 webpack 也不例外,那如何讓我們打包之後的程式碼自動轉換相容呢,這時候就要參照一個工具了 --babel 

廢話不多說,我們首先一步我們直接在我們的專案裡下載 babel 

npm i -D -S @babel/core @babel/preset-env babel-loader core-js

 @babel/core :我們 babel 的一個核心工具

 @babel/preset-env :preset 預先設定的,env 環境,裡面預置不同的環境

babel-loader :loader 包 用來結合的

core-js : js 一個執行環境,可以讓我們的老瀏覽器用到新瀏覽的語法,技術

 下載完成之後,我們可以去 package.json 看一下,看看是否載入成功

第二步,確認無誤之後,我們再開啟我們的 webpack.config.js 檔案進行設定

找到我們之前設定的 module 裡面不是有我們之前設定的 use :ts-loader 使用 loader 包,這時再新增一個就行了

module.exports = {
    module:{
        rules:[
            {
                test:/\.ts$/, 
                use:[
                    'babel-loader',
                    'ts-loader',
                ],    
            },
          ],   
  } 
}

當然我們還可以進行詳細的設定,推薦:

    module:{
        // 指定載入的規則
        rules:[
            {
                // test 指定的是規則生效的檔案
                test:/\.ts$/, // 所有以 ts 結尾的檔案
                // use:'ts-loader',
                use:[
                    // 設定我們的 babel
                    {
                        //  指定我們的載入器
                        loader:"babel-loader",
                        // 設定我們的babel
                        options:{
                            // 設定預定的環境
                            presets:[
                                [
                                    // 指定我們的環境外掛
                                    "@babel/preset-env",
                                    // 設定資訊
                                    {
                                        // 要相容的目標瀏覽器
                                        targets:{
                                            "chrome":"88" // 指定瀏覽器的一個版本
                                        },
                                        // 指定 corejs 版本
                                        "corejs":"3", // 用那個版本的 js
                                        // 使用 corejs 的方式
                                        "useBuiltIns":"usage", // usage 按需載入
                                    }
                                ]
                            ]
                        },
                    },
                    'ts-loader',
                ],
                // 要排除的檔案
                exclude:/node-modules/,
            }
        ]
    },

use執行的時候,會優先執行下邊的,所以記得把 ts-loader 放在下邊,因為我們想先讓 ts 轉換然後再相容轉換

loader:指定我們的載入器

options:{ } 裡面的 presets 是預設我們的環境 語法 :

options:{

presets :[

[

"@babel/preset-env", 第一個值 ,來指定我們的 環境外掛是那個,
{
targets:{}  設定我們的要相容的瀏覽器是哪些, 」瀏覽器名字「 : "版本"
}
"corejs" : "3" 指定 corejs 版本
」useBuiltIns「 :"usage" 使用方式 按需載入

]

]

}

 好了,這樣我們所有的 webpack 都設定好了,打包看看能不能使用

到此為止,我們的 TS 加 webpack 以及 babel 就都設定好了,最後貼出設定完成所有 webpack.config.js 程式碼

// 引入一個包
const path = require('path'); // 使用者拼接路徑

// 引入 html 外掛
const HTMLWebpackPlugin = require('html-webpack-plugin');

// 引入 clean 外掛
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

// webpack 中所有的設定資訊都應該寫到我們的 module.exports 裡
module.exports = {

    // 指定入口檔案
    entry:"./src/index.ts",

    // 指定打包檔案所在的目錄
    output:{
        path:path.resolve(__dirname,'dist'),
        // 打包後檔案的檔案
        filename:"bundle.js"
    },

    // 指定webpack 打包時要使用的模組
    module:{
        // 指定載入的規則
        rules:[
            {
                // test 指定的是規則生效的檔案
                test:/\.ts$/, // 所有以 ts 結尾的檔案
                // use:'ts-loader',
                use:[
                    // 設定我們的 babel
                    {
                        //  指定我們的載入器
                        loader:"babel-loader",
                        // 設定我們的babel
                        options:{
                            // 設定預定的環境
                            presets:[
                                [
                                    // 指定我們的環境外掛
                                    "@babel/preset-env",
                                    // 設定資訊
                                    {
                                        // 要相容的目標瀏覽器
                                        targets:{
                                            "chrome":"58",
                                            "ie":"11" // 指定瀏覽器的一個版本
                                        },
                                        // 指定 corejs 版本
                                        "corejs":"3", // 用那個版本的 js
                                        // 使用 corejs 的方式
                                        "useBuiltIns":"usage", // usage 按需載入
                                    }
                                ]
                            ]
                        },
                    },
                    'ts-loader',
                ],
                // 要排除的檔案
                exclude:/node-modules/,
            }
        ]
    },

    // 設定 webpack 外掛
    plugins:[
        new CleanWebpackPlugin(),
        new HTMLWebpackPlugin({
            template:'./src/index.html',
        })
    ],
    
    // 用來設定參照模組
    resolve:{
        extensions:['.ts','.js'] // 以 .ts 和 .js 結尾的都可以當模組去參照
    }
}