8-webpack之loader
1、關於loader
在之前的例項中,主要是用 webpack 來處理 js 程式碼,並且 webpack 會自動處理 js 之間相關的依賴,
但在開發中往往不僅僅有基本的 js 程式碼處理,也需要載入 css、圖片,也包括一些高階的將 ES6、TypeScript 轉成 ES5 程式碼,
將scss、less 轉成 css,將 .jsx、.vue 檔案轉成 js 檔案等;
對於webpack本身的能力來說,對於這些轉化是不支援的,我們需要給 webpack 擴充套件對應的 loader;
loader 是 webpack 中一個非常核心的概念,webpack 可以使用 loader 來預處理檔案;
2、css-loader
(1)loader的安裝配置
通過 npm 安裝需要使用的 loader:
npm install style-loader css-loader --save-dev
style-loader
:將模組的匯出作為樣式新增到 DOM 中
css-loader
:解析 CSS 檔案後,使用 import 載入,並且返回 CSS 程式碼
在 webpack.config.js 中的 module關鍵字下進行配置:
module.exports = {
…, module: { rules: [ { test: /\.css$/, // webpack 在讀取使用的loader的過程中,是按照從右向左的順序讀取的,所以順序不能顛倒 use: [ 'style-loader', 'css-loader' ] } ] } }
3、CSS檔案的處理
專案開發過程中,我們必然需要新增很多的樣式,而樣式我們往往寫到一個單獨的檔案中;
結構如下,CSS檔案和js檔案分別有不同的目錄:
在 normal.css 中,將 body 設定為 red:
body { background-color: red; }
這時,normal.css 中的樣式是不會生效的,因為我們還沒有引用它,所以 webpack 不能找到該檔案;
在入口檔案 main.js 中引用 css 檔案:
// 引用 css 檔案 require('./css/normal.css')
配置完成以後,可以使用 npm run build
命令將 css 檔案程式碼也一併打包到 bundle.js 檔案中了,此時,css 中的程式碼會生效:
4、less檔案處理
less-loader
載入和轉譯 LESS 檔案;
安裝:
npm install --save-dev less-loader less
在 css 資料夾中新建 less 檔案 special.less:
@fontSize:50px; @fontColor:orange; body{ color: @fontColor; font-size: @fontSize; }
配置:
{ test: /\.less$/, use: [{ loader: "style-loader", // creates style nodes from JS strings }, { loader: "css-loader" // translates CSS into CommonJS }, { loader: "less-loader", // compiles Less to CSS }] }
在 main.js 中引入 less 檔案:
// 引用 less 檔案 require('./css/special.less') // 為了檢視 less 生效的程式碼,新增一些文字 document.writeln('<h2>你好,小鳴</h2>')
使用npm run build打包,檢視效果;
5、url-loader 和 file-loader
file-loader
:將檔案傳送到輸出資料夾,並返回(相對)URL;
url-loader
:像 file loader 一樣工作,但如果檔案小於限制,可以返回 data URL;
(1)url-loader
在src/img下準備兩張圖片,一張(test.jpg)小於13kb,一張(timg.jpg)大於13kb;
修改normal.css檔案,設定test.jpg為背景:
body { /*background-color: darkgray;*/ background: url("../img/timg.jpg"); }
安裝 url-loader:
npm install --save-dev url-loader
修改 webpack.config.js 配置檔案,配置 url-loader:
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 13000
}
}]
}
打包,執行 index.html,就會發現背景圖片渲染出來了;
此時的背景圖是通過base64顯示出來的;
其實,這是limit屬性的作用,當圖片小於13kb時,對圖片進行base64編碼:
(2)、file-loader
那麼問題來了,如果圖片大於 13kb 呢?
將 background 的圖片改成 timg.jpg:
body { /* background-color: red; */ background: url(../img/timg.jpg); }
此時再打包就會報錯,這是因為大於 13kb 的圖片,會通過 file-loader 進行處理,但專案中並沒有 file-loader,所以需要安裝一下 file-loader:
npm install --save-dev file-loader
再次打包執行,會發現 dist 資料夾下多了一個圖片檔案;
但是,我們發現圖片並沒有顯示出來,這是因為圖片使用的路徑不正確,
預設情況下,webpack 會將生成的路徑直接返回給使用者,但我們整個程式是打包到了 dist 資料夾下的,所以這裡需要在路徑下再新增一個 dist/
:
再次打包執行,發現 timg.jpg 的背景能夠顯示出來了;
(3)修改圖片檔名稱
webpack 自動幫助我們為圖片生成了一個非常長的名字,這是一個32位 hash 值,目的是防止名字重複;
但在真實開發中,我們可能對打包的圖片名字有一定的要求,比如:將所有的圖片放在一個資料夾中,跟上圖片原來的名稱,同時也要防止重複;
所以,我們可以在 options 中新增如下選項:
- img:檔案要打包到的資料夾
- name:獲取圖片原來的名字,放在該位置
- hash:8:為了防止圖片名稱衝突,依然使用 hash,但是我們只保留8位
- ext:使用圖片原來的副檔名
再次打包,發現在 dist/img 資料夾中的圖片是按照我們預先設定的名字命名:
6、babel-loader
webpack 打包的 js 檔案中,ES6 語法並沒有轉成 ES5,那麼就意味著可能一些對 ES6 還不支援的瀏覽器沒有辦法很好的執行我們的程式碼;
如果希望將 ES6 的語法轉成 ES5,那麼就需要使用 babel;
在webpack中,直接使用 babel 對應的 loader 就可以了;
安裝babel-loader:
npm install --save-dev babel-loader@7 babel-core babel-preset-es2015
配置 webpack.config.js 檔案:
{
test: /\.js$/,
// exclude: 排除
// include: 包含
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015']
}
}
}
重新打包,檢視 bundle.js 檔案,發現其中的內容變成了 ES5 的語法;