大家好啊,昨天介紹了 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 的設定了
我們打包完成之後,有了一個單獨的 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'] } }
到這裡,如果我們不考慮一些相容性的問題,所以都必要設定都已經參照好了,多敲幾遍,熟悉幾遍
我們在寫程式碼的時候都會考慮一個相容性的問題,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 :[
[
]
]
}
好了,這樣我們所有的 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 結尾的都可以當模組去參照 } }