前言
webpack是當前前端項目中最常用的資源構建工具,從本文開始,來總結記錄一下關於webpack的學習。
正文
1、webpack簡介
webpack官網(https://webpack.docschina.org/)
我們代碼中使用less,ES6的impot以及一些高級的語法,瀏覽器無法識別,因此webpack解決了這個問題,它是一種前端的資源構建工具,同時也是一個靜態的模塊打包器。在webpack看來,前端的所有資源文件(js/img/css/less)都會作為模塊處理,他會根據模塊的依賴關系進行靜態分析,打包生成對應的靜態資源。我的理解就是,要完成這些首先要告訴weback的一個入口起點,然后根據這些依賴關系,形成一個代碼塊,這個代碼塊就叫chunk,然后根據這個chunk進行不同的處理,這一過程叫打包,打包之后,輸出出來的文件叫 bundles。
(1)Entry
入口,指示webpack以哪個文件為入口起點開始打包,但是打包之前需要分析清模塊之間的依賴關系圖。
(2)Output
輸出,指示webpack 打包后的資源 bundles 輸出到哪里,以及如何命名。
(3)Loader
Loader,指示webpack能夠處理那些非 js 文件,可以理解 webpack 本身只能處理一些 js 文件,一旦處理樣式文件,圖片文件這些就會報錯或處理不了。它就類似一個翻譯官的角色。
(4)Plugins
插件,用於執行一些范圍更廣的任務,比如打包優化和壓縮,一直到重新定義環境變量等。
(5)Mode
模式(process.env.NODE_ENV),development開發模式,能讓代碼在本地調試運行的環境。
production 生產模式,能讓代碼優化上線的運行環境。
3、webpack 安裝及初體驗
前提:node環境 npm安裝成功
全局安裝:npm install -g webpack npm i -g webpack-cli
本地安裝:npm install webpack -D npm i webpack-cli -D
注意:在安裝webpack的時候,如果報錯如下,是自己的項目名package.json中的name值設置成了webpack
初體驗,創建項目,通過 cmd 中輸入 npm init 指令初始化項目,這里要注意 package.json 的 name 值問題,然后在本地安裝依賴 npm i webpack-cli -D 和 npm install webpack -D ,創建src目錄,在下面創建(index.js,index.css,data.json),index.js文件為項目入口文件,並分別測試css文件,json資源文件,代碼如下:
index.js
// 普通js代碼 function add(x,y){ return x + y } console.log(add(1,2)); // json資源 import data from "./data.json" console.log(data); // 引入css資源 // import "./index.css"
index.css
body{ padding: 0; background-color: pink; }
data.json
{ "name":"name", "age":18 }
分別測試下面的指令:
開發環境指令:webpack ./src/index.js -o ./build --mode=development。以 ./src/index.js 為入口 ,./build 為輸出,整體打包環境是開發環境。
生產環境指令:webpack ./src/index.js -o ./build --mode=production。以 ./src/index.js 為入口 ,./build 為輸出,整體打包環境是生產環境。
經測試得出結論如下:
(1)webpack能處理 js 資源,json 資源,不能處理 css 、html、和 img 資源,打包過程會報錯:Module parse failed: Unexpected token (1:4)
(2)生產環境比開發環境多了壓縮js代碼,生產環境和開發環境將es6 模塊編譯成瀏覽器能識別的模塊
4.webpack打包樣式資源
(1)引入css樣式資源-----css-loader 和 style-loader
首先將index.js中的css引入代碼注釋放開
命令行執行npm i style-loader css-loader -D 命令安裝開發依賴
在項目最外層創建webpack.config.js 文件,該文件為webpack配置文件,插入如下代碼
// resolve用來拼接絕對路徑的方法 const { resolve } = require("path"); module.exports = { //入口文件 entry: "./src/index.js", // 輸出 output: { // 輸出文件名 filename: "build.js", // 輸出路徑 // __dirname 是node.js的變量,代表當前文件的目錄的絕對路徑 path: resolve(__dirname, "build"), // 代表輸出到當前目錄下創建的build文件夾下 }, // loader的配置 module: { rules: [ // 詳細的loader配置 { test: /\.css$/, //匹配.css結尾的文件 use: [ // 使用哪些loader進行處理,use數組中的執行順序是從后往前 //創建一個style標簽,將js中的樣式資源插入進去,添加到head中生效 "style-loader", // 將css文件編程commonjs模塊加載在js中,里面內容是樣式字符串 "css-loader", ], }, ], }, //plugin的配置 //plugins: [],// 這里要注意,里面沒有配置的時候要注釋掉,否則會報錯 // 模式 mode: "development", // 開發模式 // mode:"production"// 生產模式 };
然后執行命令 webpack即可,然后會發現控制台
接下來需要,測試引入樣式是否成功,需要在build文件下創建index.html文件,並在其中引入打包之后生成的build.js,然后再瀏覽器打開該html文件。
(2)引入less樣式資源-----less-loader
按照css資源的方式,創建index.less文件,寫入樣式,然后在index.js中引入,再次執行wbepack命令,發現報錯如下:
{ test: /\.less$/, //匹配.less結尾的文件 use: [ "style-loader", "css-loader", "less-loader"// 將less文件變異成css文件 ], },
同樣執行 webpack 命令
測試less打包成功方法同css。
5、webpack打包html文件----html-webpack-plugin
前面解決了樣式資源的打包,都用到了 loader 來處理,都需要下載依賴,然后在loader中配置,而處理htm資源,就需要用到 plugins,需要首先下載依賴,然后 webpack 引入,最后在 plugins 中配置,如下:
同樣創建 index.html 文件。
首先,下載 html-webpack-plugin : npm i html-webpak-plugin -D
然后webpack.config.js 中引入
const HtmlWebpackPlugin = require("html-webpack-plugin")
最后在plugins中配置:
//plugin的配置 plugins: [ new HtmlWebpackPlugin() ],
plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", }), ],
這就相當於復制了index.html文件,並自動引入打包生成的所有資源文件。
6、webpack打包圖片資源----url-loader 和 file-loader
由於在webpack對html文件進行打包的時候會使用我們設置的html模板,因此我們在html文件中引入img文件無法測試對圖片資源的打包,所以這里需要通過樣式資源引入的方法來測試打包圖片資源。
這里新建一個img文件夾,然后添加一張圖片,在index.css文件中修改如下代碼,並把css文件引入在index.js中
body{ padding: 0; background-image: url(./img/webpack.jpg); background-repeat: repeat; }
然后安裝依賴:npm i url-loader file-loader -D
// 這種方式無法處理html文件中的圖片 { test:/\.(jpg|png|gif)$/, loader:"url-loader", options:{ // 圖片大小小於8kb,會被解析為base64處理,優點減少請求數量減輕服務器壓力,缺點是圖片體積更大,文件請求速度更慢 limit:8*1024 } }
執行webpack打包命令,發現打包成功。
打包生成文件如下:發現圖片的名字發生了變化(將圖片修改成了對應的hash值)。
首先在html文件中寫入
<img src="./img/webpack1.jpg" alt="" />
然后下載依賴: npm i html-loader -D
{ test: /\.(jpg|png|gif)$/, loader: "url-loader", options: { // 圖片大小小於8kb,會被解析為base64處理,優點減少請求數量減輕服務器壓力,缺點是圖片體積更大,文件請求速度更慢 limit: 8 * 1024, esModule: false, // 這樣可以修改圖片名稱,[hash:10]表示取hash值的前十位,[ext]表示原文件擴展名 // name: "img/[hash:8].[name].[ext]", }, }, { // 因為url-loader默認適用了es6模塊解析,而html-loader 引入圖片適用commonJS處理,解析時會出現[object Module],需要關閉url-loader的es6模塊化解析 test: /\.html$/, // 處理html 文件的img文件 loader: "html-loader", },
然后執行webpack命令,打包成功
對應的html文件中的img路徑也發生了變化
7、打包其他資源---- file-loader
這里主要指其他不需要做任何優化之類的資源,這里以字體圖標為例(https://www.iconfont.cn/),這里選擇一個購物車圖標,選擇下載代碼.,
下載文件並解壓,打開index.html文件,會有使用圖標的方法介紹,這里使用Unicode 引用
第一步:拷貝項目下面生成的 @font-face
@font-face { font-family: 'iconfont'; src: url('iconfont.ttf?t=1637326208397') format('truetype'); }
第二步:定義使用 iconfont 的樣式
.iconfont { font-family: "iconfont" !important; font-size: 16px; font-style: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
第三步:挑選相應圖標並獲取字體編碼,應用於頁面
<span class="iconfont">3</span>
操作:首先在src文件下創建一個icont的文件夾,把下載的 iconfont.ttf 文件復制到文件夾下,然后把第一二步的代碼復制到index.css文件,把第三步的代碼復制到index.html 中,最后配置loader
{// 打包其他資源(除了css,js,html資源以外的資源) exclude:/\.(css|js|html|less|json)$/,
loader:"file-loader" }
執行webpack命令打包結果如下:
8、
我們前面測試打包是否成功,都是通過打包命令 webpak ,然后在生成的index.html 文件中測試,我們每次修改一行代碼,都需要執行這個打包命令,這樣開發就十分麻煩,不方便調試,因此,這節來學習devServe的功能和使用。
devServer 開發服務器,用來自動化(自動編譯,自動打開瀏覽器,自動刷新瀏覽器)
在webpack.config.js 中添加如下配置:
devServer: { // 項目構建后的路徑 // contentBase: resolve(__dirname, "build"),// 這個配置在新版本的webpack中使用下面的方式配置,否則會報錯 static: { // static: ['assets'] directory: resolve(__dirname, "build") }, // 啟用gzip壓縮 compress: true, // 端口號 port: 3000, open:true// 自動打開瀏覽器 },
需要注意的是:devServer只會在內存中編譯打包。不會有任何輸出。
啟動devServer 的指令為:npx webpack-dev-server(本地啟動),這里需要手動安裝依賴 npm i webpack-dev-server -D
之后執行npx webpack-dev-server 命令啟動項目,發現webpack 並沒有終止運行,還會繼續運行
然后通過 http://localhost:3000/ 就可以看編譯的結果,然后我們修改開發的文件,發現會實時更新,不再需要手動執行webpack打包命令,更加便於開發使用
注意:執行了webpack 打包命令,會輸出編譯之后的文件,執行webpack-dev-serve 並不會輸出文件,只是在內存中編譯的,沒有任何輸出。
最后:以上代碼源碼請見 https://gitee.com/zaisy/webpack.git 的 webpack01 文件夾。
寫在最后
以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長之路會持續更新一些工作中常見的問題和技術點。