寫在前面的話:
在當前grunt、gulp、webpack成為日常工具的情況下,如果你還只是熟練的使用html、css和激塊瑞的話,已經遠遠不能滿足項目的需求,所以你得變強,你需要懂得更多。現在前端不僅僅是用那幾句蹩腳的JavaScript代碼在瀏覽器渲染幾個頁面然后提交幾個表單在寫點交互了。現在WebGL協議可以為HTML5 Canvas提供硬件3D加速渲染,你可以用JavaScript語法可以渲染3D模型,你也可以用nodejs搭建后臺,還可以用react-native、weex做一個app。js發展的也越來越像后臺語言,畢竟js已經將它的魔爪伸到了很多領域,這讓你可以猥瑣欲為。。。確實每個前端都應該有一統前端界的野心,寄人籬下只是暫時的 ⌒_⌒....
一、webpack安裝及概念
webpack是現代JavaScript應用程序的靜態模塊打包工具
,webpack是通過npm來安裝的,npm是跟node一起下載的包管理工具,所以你得保證電腦上已經安裝了node。在安裝之前先來說下cnpm,因為npm安裝插件是從國外服務器下載,受網絡影響大,可能出現異常,那下載速度讓人不由得喊一聲“王德發”,所以我們‘偉大的’淘寶團隊干了一件偉大的事:“這是一個完整 npmjs.org 鏡像,你可以用此代替官方版本(只讀),同步頻率目前為 10分鐘 一次以保證盡量與官方服務同步。” 你只要執行以下命令:
$ npm install -g cnpm
用了cnpm之后那速度讓人爽得不要不要的,再也不用擔心摔鍵盤的問題了。
那么下面就來介紹一下webpack的安裝,安裝包括本地安裝和全局安裝(我用的是webpack4版本):
webpack-bundle-analyzer?全局安裝(全局安裝是安裝到你C盤里,在任何地方都可以使用):
cnpm i webpack -g
本地安裝(是安裝到當前目錄,只能在當前目錄使用):
cnpm i webpack -D?//i 是install 的縮寫
如果你想安裝webpack特定的版本,比如說2.2:
cnpm i webpack@2.2 -D
在以前的版本中webpack和webpack-cli是一體的,但在webpack4中,它把webpack和它的cli分開來以方便于管理,所以還需要安裝:
cnpm i webpack-cli -D
到這里我們已經懷著美滋滋的心情介紹完webpack的安裝方法了,現在介紹一下webpack的基本概念,它的基本概念有四個,是的只有四個,你沒有看錯(是不是很高興?你高興的太早了):
- 入口(entry)
- 輸出(output)
- loader
- 插件(plugins)
我們來簡單說一下家伙的功能先李姐李姐:
webpack打包、entry:顧名思義就是入口,就好像一個口袋的袋口,要裝東西(比如說一支筆)進去就要通過這里。
output:肯定就是出口啦,你把一個裝筆的袋子拿繩子捆起來后放到一個地方,這個地方就是出口。
loader:這個單詞的意思是裝貨的人
,那么在這里就是指的是那個裝筆的人,意思是因為筆不可能自己跑進袋子里,需要一個人代勞。其實正確的解釋是webpack自身只能理解javascript,它不認識這支筆是什么東西,所以就需要loader告訴webpack這是一支筆,那么webpack就能理解這支筆了。
plugins:這個就是插件,我們對插件肯定很熟悉了,在項目中我們用過很多各種各樣的插件,它可以用來處理各種各樣的任務。
二、一個簡單的項目
介紹完了webpack的安裝以及概念,讓我們釋放一下蠢蠢欲動的心做一個小項目吧:
- 讓我們新建一個文件夾
mkdir webpack_lesson_one
- 進入到新建的文件夾內
cd webpack_lesson_one
- 新建一個項目
npm init -y
- 安裝webpack以及webpack-cli
cnpm i webpack webpack-cli -D
- 接下來我們在根目錄新建一個
index.html
和一個webpack的配置文件webpack.config.js
以及一個資源文件夾src
,完成以上流程以后我們的目錄應該是這個樣子的:
webpack vue?
- 我們在
src
目錄里面新建一個入口文件index.js
,然后編輯文件如圖:
- 然后我們開始編輯
webpack.config.js
:
const path = require('path');module.exports = {entry:{ //入口文件配置,當然這里可以配置多個入口文件,在此對象內增加增加鍵值對即可 app: './src/index.js' }, output:{ //出口文件配置 filename:'[name].bundle.js', path: path.resolve(__dirname, 'dist') } } //path.resolve()是nodejs中的語法,拼接路徑, __dirname代表項目根目錄
- 修改package.json文件增加
"scripts"
命令,如下:
接下來在根目錄的index.html
中引入app.bundle.js
:
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src="dist/app.bundle.js"></script> </body> </html>
- 接下來打開終端執行命令:
npm run build
接下來就是見證奇跡的時刻了,你的項目根目錄會生成dist
文件夾,瀏覽器運行index.html
就會看到hello world!
,那么我們的一個超級森破的項目就這樣完成了。
三、引入css、圖片、字體
Webpack插件按需加載組件?在介紹上面幾個功能前先說一下項目目錄的合理分配,一個合適的項目目錄可以降低整體項目的依賴性,大大提高工作中的開發效率,所以資源管理一定做好。那么在src
目錄中新建components
目錄,然后新建文件如下:
|- /src
|- |- /components
|- | |- /News |- | |- |- /img |- | |- |- index.js |- | |- |- style.css |- index.js
- 接下來我們呢先安裝
style-loader
和css-loader
以及file-loader
:
cnpm i style-loader css-loader file-loader -D
- 下面在
webpack.config.js
中配置:
const path = require('path');module.exports = {entry:{ app: './src/index.js' }, output:{ filename:'[name].bundle.js', path: path.resolve(__dirname, 'dist') }, module:{ rules:[ { test:/\.css$/, use:['style-loader', 'css-loader'] //這里需要注意下,style-loader 必須要寫在 css-loader 之前喲 }, { test:/\.(jpg|png|gif|svg)$/, use:[ { loader:'file-loader', options:{ name:'img/'+'[name].[ext]?[hash]', //可以重寫css中引入圖片部分 publicPath: 'dist/' //可以重新生成圖片到新的目錄 } } ] } ] } }
我們來修改src
目錄下的index.js
編寫News
目錄下的style.css
文件
body{background: #fff url(img/banben.png) 0 0 no-repeat; }
編寫News
目錄下的index.js
文件
import './style.css';console.log('有一天我希望站在這個世界的頂端說出八個大字:我的,我的,都是我的!');
前端webpack,現在你再運行npm run build
命令,再運行index.html
看看是不是這樣的效果(啊,多么漂亮的圖標啊!):
再看看里面加載的css:
圖片后面自動加上了參數,這就是上面的配置項name:'img/'+'[name].[ext]?[hash]'
的作用。你可以去看看file-loader的使用方法,讓我們姿勢一起漲,1(yao)3(san)一起裝。
- 那么引入字體也是同樣的道理,編輯
webpack.config.js
文件:
const path = require('path');module.exports = {entry:{ app: './src/index.js' }, output:{ filename:'[name].bundle.js', path: path.resolve(__dirname, 'dist') }, module:{ rules:[ { test:/\.css$/, use:['style-loader', 'css-loader'] //這里需要注意下,style-loader 必須要寫在 css-loader 之前喲 }, { test:/\.(jpg|png|gif|svg)$/, use:[ { loader:'file-loader', options:{ name:'img/'+'[name].[ext]?[hash]', //可以重寫css中引入圖片部分 publicPath: 'dist/' //可以重新生成圖片到新的目錄 } } ] }, { test:/\.(woff|woff2|eot|otf|ttf)$/, use:['file-loader'] } ] } }
- 在
src
目錄下新建public
文件夾,放入字體文件資源:
webpack怎么實現按需加載?
- 在
src
目錄下的index.js
引入字體css文件:
- 在
index.html
中添加字體標簽:
再去News
里改變一下字體的大小,做人就是要大氣一些:
webpack按需加載原理,然后再npm run build
一下看看字體圖標已經加載出來了!!!
四、圖片的壓縮以及舊文件的刪除
我們已經能加載圖片了,那么試著壓縮一下吧,畢竟濃縮的才是精華、O(∩_∩)O哈哈~。。另附直通車image-webpack-loader,一條龍式服務必須滴。
還是老樣子,當然還是先安裝image-webpack-loader
cnpm?i?image-webpack-loader -D
修改webpack.config.js
module里的rules:
module:{rules:[{test:/\.css$/,use:['style-loader', 'css-loader'] }, { test:/\.(jpg|png|gif|svg)$/, use:[ { loader:'file-loader', options:{ name:'img/'+'[name].[ext]?[hash]', publicPath: 'dist/' } }, { //壓縮圖片要在file-loader之后使用 loader:'image-webpack-loader', options:{ bypassOnDebug: true } } ] }, { test:/\.(woff|woff2|eot|ttf|otf)$/, use:['file-loader'] } ] },
現在你npm run build
之后看看dist
文件夾內的banben.png
和之前的圖片大小對比,是不是小了一半,就是這么方便。
- 還有我們在做項目時很多時候都需要刪除之前廢棄的文件。舉個栗子:現在我們把上面的
file-loader
里的name
參數變一下:
{loader:'file-loader',options:{name:'img/'+'[hash].[ext]', //把[name] 換成 [hash] publicPath: 'dist/' } }
webpack文檔。這樣我們生成的文件是一個以哈希值命名的圖片,當我們改變原圖片名字的時候再打包后會重新生成一個圖片文件,但是之前生成的依然還在那里一動不動。這個時候我們就需要用到clean-webpack-plugin了,當然這個是插件
不是loader
喲~ 那就讓我們來安裝吧:
cnpm i clean-webpack-plugin?-D
- 同理配置一下
webpack.config.js
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin'); //插件是需要引入的,這里可別忘了引入 module.exports = { entry:{ app: './src/index.js' }, output:{ filename:'[name].bundle.js', path: path.resolve(__dirname, 'dist') }, module:{ rules:[ { test:/\.css$/, use:['style-loader', 'css-loader'] }, { test:/\.(jpg|png|gif|svg)$/, use:[ { loader:'file-loader', options:{ name:'img/'+'[hash].[ext]', publicPath: 'dist/' } }, { loader:'image-webpack-loader', options:{ bypassOnDebug: true } } ] }, { test:/\.(woff|woff2|eot|ttf|otf)$/, use:['file-loader'] } ] }, plugins:[ new CleanWebpackPlugin(['dist/img']) //數組內的是需要清理的目錄 ] }
來來來,我們npm run build
一下,是不是你的img
文件消失一下后又重新浮現在你的眼前了,如果沒有消失過可能是你的眼花了。
當然你還可以設置其它參數,詳見clean-webpack-plugin
plugins:[new CleanWebpackPlugin(['dist/img'],{exclude: [ 'banben.png' ] //這個配置意思就是不刪除 img 文件里面的 banben.png 圖片 }) ]
現在本期webpack筆記已經到此結束了,另附上github項目練習素材地址:https://github.com/zgf123/web...
五、知識小結
webpack遵循commonJs規范,每個文件就是一個模塊,有自己的作用域。在一個文件里面定義的變量、函數、類,都是私有的,對其他文件不可見。CommonJS規范規定,每個模塊內部,module變量代表當前模塊。這個變量就是一個對象,它的exports屬性就是對外的接口,所謂加載某個模塊,其實就是加載這個模塊的modules.exports屬性。