自學 TypeScript 第三天 使用webpack打包 TS 程式碼
- 2022 年 11 月 18 日
- 筆記
前言:
大家好啊,昨天介紹了 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'] } }
到這裡,如果我們不考慮一些兼容性的問題,所以都必要配置都已經引用好了,多敲幾遍,熟悉幾遍
兼容性:
我們在寫程式碼的時候都會考慮一個兼容性的問題,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 結尾的都可以當模組去引用 } }