webpack最佳入門實踐系列(4)
7.使用字體
7.1.安裝字體庫-font-awesome
我們通過npm來安裝字體
npm install font-awesome --save
這個時候,我們的package.json配置文件變成這樣:
{ "name": "code", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "webpack", "start": "webpack-dev-server", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "css-loader": "^0.28.7", "file-loader": "^1.1.5", "html-webpack-plugin": "^2.30.1", "style-loader": "^0.19.0", "url-loader": "^0.6.2", "webpack": "^3.10.0", "webpack-dev-server": "^2.9.7" }, "dependencies": { "font-awesome": "^4.7.0" } }
註意:我們在安裝第三方包的時候,可以使用下面兩條命令
npm install font-awesome --save
以及
npm install font-awesome --save-dev
這兩條命令的區別是,--save 安裝的是項目依賴,會把當前安裝的包一起打包隨著項目發布到線上,而--save-dev安裝的包屬於開發依賴,不會和項目一起打包發布到線上,例如,像webpack-dev-server這樣的包,我們只是在本地開發的時候使用,方便調試,而不需要發布到線上的,通常我們都會作為開發依賴安裝,像font-awesome這樣的包,我們線上的網頁也會使用,所以會一起打包發布,所以通常我們都會作為項目依賴安裝,開發依賴包的安裝信息在package.json中devDependencies這個屬性下面,項目依賴包的安裝信息在package.json中的dependencies屬性下面
7.2.使用字體庫
在index.js 文件中引入
// 引入帶有字體的css文件,用來測試webpack是否支持字體大包 import "font-awesome/css/font-awesome.css"
這個時候,我們通過npm start命令來啟動,查看效果,此時會報一個熟悉的錯誤
RROR in ./node_modules/font-awesome/fonts/fontawesome-webfont.ttf?v=4.7.0 Module parse failed: Unexpected character ‘‘ (1:0) You may need an appropriate loader to handle this file type. (Source code omitted for this binary file) @ ./node_modules/css-loader!./node_modules/font-awesome/css/font-awesome.css 6:645-696 @ ./node_modules/font-awesome/css/font-awesome.css @ ./src/index.js @ multi (webpack)-dev-server/client?http://localhost:8080 ./src/index.js
錯誤的意思是我們需要使用一個loader來處理字體文件,現在去打開font-awesome.css這個文件,查看裏面到底有哪些內容(這個文件位置在node_modules/font-awesome/css/font-awesome.css)
@font-face { font-family: ‘FontAwesome‘; src: url(‘../fonts/fontawesome-webfont.eot?v=4.7.0‘); src: url(‘../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0‘) format(‘embedded-opentype‘), url(‘../fonts/fontawesome-webfont.woff2?v=4.7.0‘) format(‘woff2‘), url(‘../fonts/fontawesome-webfont.woff?v=4.7.0‘) format(‘woff‘), url(‘../fonts/fontawesome-webfont.ttf?v=4.7.0‘) format(‘truetype‘), url(‘../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular‘) format(‘svg‘); font-weight: normal; font-style: normal; }
通過上面font-awesome文件的內容,我們知道了它引入了它上級文件夾fonts中的字體文件,這些字體文件包括:.eot、.svg、.ttf、.woff、.woff2等格式,錯誤信息告訴我們的就是webpack不支持打包這些格式的文件,那麽,我們應該使用什麽loader來讓webpack支持打包這些文件呢?
讓我們來回顧一下file-loader做的事情
1. 將文件移動到輸出目錄
2. 自動處理url後面的文件路徑,得到一個最終的引用路徑
當文件被移動到輸出目錄,並且有一個最終正確路徑的時候,我們就可以正確使用這個文件了,所以,我們嘗試使用file-loader來支持上面那些格式的字體文件
在webpack中增加配置,通過設置字體格式的匹配規則來使用file-loader,原理和處理圖片一樣
// 處理文字 { test: /\.(eot|svg|ttf|woff|woff2)$/, use: [‘file-loader‘] }
接下來,我們通過命令打包
npm run dev
這個時候,會發現dist這個輸出目錄下已經多出來幾個字體文件了
我們接下來去測試,我們的字體能不能正常使用,我們在src下面index.html文件中輸入以下內容,引入圖標
<div id="app"> <i class="fa fa-bath" aria-hidden="true"></i> <i class="fa fa-envelope-open" aria-hidden="true"></i> <i class="fa fa-microchip" aria-hidden="true"></i> <i class="fa fa-user-circle-o" aria-hidden="true"></i> </div>
然後,我們需要再次運行命令打包
npm run dev
文件打包出來後,我們直接運行html文件,註意:這個時候不要通過服務器去訪問,直接本地瀏覽器打開就好
打開後,如果看到我們引入的圖標,證明webpack已經正常支持引入字體了
8.babel相關
8.1.babel是什麽?
Babel 是一個 JavaScript 編譯器,它使用非常廣泛,可以將es6轉換成es5,從而在一些不支持es6的瀏覽器中運行,這意味著你寫es6代碼的時候就不需要去關心瀏覽器是否支持es6
點擊進入babel中文地址
點擊進入babel官方地址
8.2.使用babel
我們新建一個babel-demo的目錄來演示bebel的使用,進入到babel-demo目錄後,運行命令初始化項目
npm init -y
這條命令的作用是在babel-demo目錄下生成一個package.json的文件
接下來,我們需要安裝babel-cli
npm install --save-dev babel-cli
babel-cli是命令行工具,安裝以後我們就可以在命令行中通過babel命令來轉碼
安裝好後,我們寫一段代碼來測試一下babel的編譯轉碼功能,在babel-demo目錄下新建index.js文件,編寫下面代碼:
() => console.log("hello nodeing.com")
接下來,通過babel命令去編譯index.js
./node_modules/.bin/babel index.js
如果你想每次運行babel的時候都輸 ./node_modules/.bin/babel這麽一長串命令, 你可以把這個命令配置到package.json中
{ "name": "babel-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "./node_modules/.bin/babel index.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-cli": "^6.26.0" } }
這個時候,我們通過npm的命令來啟動編譯
npm run build
運行後的結果,原樣輸出了index.js中的內容,為什麽babel並沒有編譯我們的index.js文件呢?
原因在於,babel是基於插件的,插件就是提供的一些擴展功能,如果沒有告訴babel用哪個插件來做事情,那麽babel就不會處理
8.3.babel插件
前面我們講到,babel是基於插件的,做不同的事情需要不同的插件,這樣讓babel非常靈活並且強大
點擊打開babel插件文檔頁,中文地址
點擊打開babel插件文檔頁,英文地址
我們去找到transform-es2015-arrow-functions這個插件,點進去查看它的使用,這個插件的功能是幫助我們把es2015(es6)的箭頭函數編譯成es5代碼
下面我們來安裝這個插件
npm install --save-dev babel-plugin-transform-es2015-arrow-functions
安裝好以後,我們需要在babel-demo目錄下新建.babelrc文件,這個文件就是babel的配置文件,我們在這個配置文件中增加配置項
{ "plugins": [ "transform-es2015-arrow-functions" ] }
然後,運行npm命令,查看效果
npm run build
運行結果:
(function () { _newArrowCheck(this, _this); return console.log(1); }).bind(this);
接下來,我們去修改index.js 文件,增加其他的es6語法
() => console.log(1) class demo{}
再去執行npm run build命令,得到的效果也是原樣輸出,這個原因和前面我們遇到的一樣,它需要安裝另一個插件才能讓babel工作起來,要不然就什麽都不做
npm install --save-dev babel-plugin-transform-es2015-classes
安裝好後,同樣需要去修改.babelrc文件,增加配置
{ "plugins": [ "transform-es2015-arrow-functions", "transform-es2015-classes" ] }
接下來就可以運行npm run build命令來查看效果了
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } (function () { return console.log(1); }); let demo = function demo() { _classCallCheck(this, demo); };
以上就是babel的插件使用方法
8.4.babel的preset
通過插件的學習,我們知道了babel要去解析轉換es6語法,需要安裝對應的插件,我們只是使用到了兩個es6的語法就裝了兩個插件,當我們需要使用很多es6語法的時候,那就需要裝非常多的插件,這樣顯得非常麻煩,那麽有沒有簡便點的方法呢?
babel通過preset來解決我們上面提出的問題,preset叫做預設,意思就是說預先設置一些常用的語法配置,把一批常用的相關的插件打包來滿足我們的開發,例如:我們處理es6語法的時候,我們就把和es6相關的語法插件打包在一起,組成一個預設,這個預設叫做es2015,所以,當我們下載一個es2015這個預設的時候,本質上就是去下載一批和es6相關的語法插件,這樣我們就不用每次去下載配置插件了
安裝preset-es2015
npm install babel-preset-es2015 --save-dev
安裝好後,需要去修改.babelrc配置文件
{ "presets": [ "es2015" ] }
最後,通過npm run build命令,查看編譯結果
8.5.webpack和babel
讓我們把目錄切換到webpack-demo目錄,修改webpack-demo下的index.js加入下面一段es6代碼
// 測試es6是否被編譯成es5 ()=>console.log("hello nodeing!!!")
然後運行命令查看結果
npm run dev
在打包出來的app.js文件中查看到,我們寫的es6代碼原樣輸出,webpack並沒有把es6代碼編譯成es5
要讓es6代碼被編譯,我們需要借助babel的力量,這裏我們需要安裝babel-loader和babel-core以及處理es6語法的預設,babel-loader的作用就是將es6代碼送給babel-core處理,babel-core就是babel工作的核心api
安裝babel-core和babel-loader以及處理es6的預設
npm install babel-loader babel-core babel-preset-es2015 --save-dev
在webpack-demo目錄中新建.babelrc文件,增加babel配置
{ "presets": [ "es2015" ] }
接下來需要在webpack.config.js文件中增加配置項
在rules規則數字中增加下面代碼
{ test: /\.js$/, use:[‘babel-loader‘] }
運行npm run dev命令把index.js打包成app.js,在app.js中我們查看到,原來的es6代碼已經成功轉換成es5代碼了
// 測試es6是否被編譯成es5 (function () { return console.log("hello nodeing!!!"); });
8.6.優化babel-loader
當我們寫這個正則表達式 (/.js$/) 的時候,表示所有js文件都會被送babel-loader加載,然後由babel-core處理一邊,這裏包括我們安裝的很多第三方包,你會發現node_modules文件夾下會有很多的js文件,但是這些js文件已經由開發者打包好了我們可以直接使用的,並不需要我們再去處理一遍,因此,如果babel-loader再去處理的話,會浪費太多的時間,導致webpack打包編譯很慢,我們現在需要優化它。具體的做法是排除不需要再次編譯的,讓babel-loader只處理我們開發的源文件,因此,我們需要修改webpack.config.js中的配置
{ test: /\.js$/, use:[‘babel-loader‘], exclude: path.resolve(__dirname, ‘node_modules‘) },
其中,exclude: path.resolve(__dirname, ‘node_modules‘) 這條語句表示排除node_modules這個文件夾,因為這個文件夾下放的都是第三方包,並不需要我們再次用babel去編譯了
再次運行npm run dev去打包的時候會發現已經快很多了
webpack最佳入門實踐系列(4)