webpack5熱更新打包TS
webpack5熱更新打包
熱更新,是指 Hot Module Replacement,縮寫為 HMR。
模塊熱替換(HMR - Hot Module Replacement)是 webpack 提供的最有用的功能之一。它允許在運行時替換,添加,刪除各種模塊,而無需進行完全刷新重新加載整個頁面
當然這次主要是為了打包我寫的typescript,為了修改ts后能夠時時更新出js文件。
配置準備
在之前的文章 《webpack打包typescript》里面,關于webpack如何打包ts文件已經講過一次,需要安裝的插件還是需要繼續依賴
插件:
typescript
webpack
webpack-cli
ts-loader
本次熱更新對應還需要多安裝一個包,叫做webpack-dev-server
安裝命令: yarn add webpack-dev-server
我的這四個包的版本(這里可以注意一下,我的webpack版本已經是5了):
"typescript": "^4.3.5", "webpack": "^5.48.0", "webpack-cli": "^4.7.2", "webpack-dev-server": "^3.11.2"
此時需要在根目錄下創建webpack.config.js文件,這個文件的配置在此系列上一篇文章中已經有寫過,不過現在需要多增加devServer和plugins配置。
之前的webpack.config.js文件
const path = require('path'); const webpack = require('webpack'); module.exports = { entry:'./TypeScript/tsc05.ts', // 打包對入口文件,期望打包對文件入口。 這里配置tsc05.ts的位置 output:{ filename:'tsc_out.js', // 輸出文件名稱 path:path.resolve(__dirname,'./TypeScript/') //獲取輸出路徑 }, mode: 'development', // 整個mode 可以不要,模式是生產壞境就是壓縮好對,這里配置開發壞境方便看生成對代碼 module:{ rules: [{ test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/ }] }, resolve: { extensions: ['.ts'] // 解析對文件格式 }, }
在module.exports內增加的配置代碼如下:
通過 webpack-dev-server 的這些配置,能夠以多種方式改變其行為
devServer: { liveReload: true, // liveReload替代hot進行熱更新 port: 9000, // 端口號 filename: 'tsc_out.js', // 輸出文件名稱 }, plugins: [ //熱更新插件 new webpack.HotModuleReplacementPlugin() // 在最開始需要引入 const webpack = require('webpack'); ]
這里很有可能在后面運行時出現報錯,原因是webpack未找到, 如果此前沒有在webpack.config.js引入webpack,此時需要引入一下
const webpack = require('webpack');
webpack.config.js配置好了之后,在根目錄的package.json文件中,添加script運行腳本 start
"scripts": { "dev": "webpack --mode development", "start": "webpack serve --config webpack.config.js --mode development" }
注意: 這里千萬要注意,start的運行命令要寫作webpack serve而不是webpack-dev-server
因為使用webpack-dev-server是webpack5以前的方式了,如果使用,就會在npm run start運行時發生報錯,錯誤信息為: Error: Cannot find module 'webpack-cli/bin/config-yargs'
參考文檔:https://webpack.docschina.org/configuration/dev-server/
運行命令配置錯誤:
運行命令配置后運行成功:
艱難的配置之路
接下來就開始了更加艱辛的配置過程了
當然此時配置成功,并且npm run start命令成功運行起來后,發現又出現了一堆報錯,主要都是Module not found: Error: Can't resolve錯誤。
然后我又開始瘋狂找原因,進入錯誤的文件夾webpack-dev-server\client下面,找到index.js文件。 發現錯誤都出現在require導入中。
原因:require導入是CommonJS標準,這是主要出現在node中的方式。 所以需要在webpack.config.js中配置target
具體配置可查官網:https://webpack.docschina.org/configuration/target/
構建目標(Targets)
webpack 能夠為多種環境或 target 構建編譯。target 告知 webpack 為目標(target)指定一個環境。默認值為 “browserslist”,如果沒有找到 browserslist 的配置,則默認為 “web”
所以將target設置成為’node’即可, webpack.config.js配置文件中添加target: 'node'
這下使用npm run start命令成功運行起來了,并且好像沒有報錯啦。
現在運行npm run start命令,出現了下面的運行結果:
既然說 Compiled successfully.已經成功,那么在相應的TypeScript文件夾下應該有對應的tsc_out.js生成了。
但是,我沒找到生成的js文件,不應該呀。 然后趕緊排查原因:
熱更新JS文件未生成
排查原因
是否生成到其他文件夾
否
是否運行腳本錯誤
查看是否devServer配置錯誤
是
發現使用熱更新命令運行雖然成功了,但是熱更新是編譯的文件是存放在內存當中的,所以肯定在相應配置的output輸出位置找不到對應的打包文件了
如果想要在對應位置熱更新后產生相應的輸出文件,需要在webpack.config.js中配置devServer時多添加一句:
writeToDisk: true
這句命令可以將產生的文件寫入硬盤。 寫入位置為 output.path 配置的目錄 (writeToDisk我其實找了好久,才在官方文檔中找到的,淚目)
devServer: { progress: false, // 命令行中會顯示打包的進度 liveReload: true, port: 9000, filename: 'tsc_out.js', writeToDisk: true, // 將產生的文件寫入硬盤。 寫入位置為 output.path 配置的目錄 },
此時,使用熱更新npm run start命令運行后,就會產生對應的tsc_out.js文件了
不過
,每次更新ts后,雖然相應的tsc_out.js文件會自動改變,但是每次更新保存后也會多出兩個main.xxx.js文件
所以這種情況依舊要需靠配置避免。
可以給 devServer.writeToDisk 傳入一個函數用來篩選哪些文件需要寫入硬盤。 使用正則表達式來對寫入硬盤的文件名次進行篩選
writeToDisk: (filename) => { return /tsc_out.js/.test(filename); }
成功效果:
至此,通過webpack進行熱更新后時時打包生成typescript的編譯js文件就完成了
總結
這次的熱更新打包過程真的是跌跌撞撞,一個蘿卜一個坑。
本篇文章的重點其實并不在于如何打包typescript,反而是在于如何配置webpack的熱更新devServer
關于如何在webpack5中配置typescript,我發現在官方網站上也有說明:https://webpack.docschina.org/guides/typescript
雖然遇到了許多麻煩和報錯,不過最終還是完成了配置
JavaScript Node.js webpack
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。