webpack學習

1.什么是webpack?

從本質(zhì)上來講梨撞,webpack是一個現(xiàn)代的Javascript應用的靜態(tài)模塊化打包工具。

這里的關(guān)鍵點就是模塊打包

1.1前端模塊化

(1)在這之前大家已經(jīng)知道了在前端開發(fā)中為什么要進行模塊化開發(fā),目前使用的前端模塊化方案有:AMD学歧、CMD勾效、CommonJs、ES6嵌器。

(2)在ES6之前我們要想進行模塊化開發(fā)肛真,必須借助于其他的工具,讓我們可以進行模塊化開發(fā)爽航。并且在模塊化開發(fā)完成后蚓让,我們還需要處理各種模塊之間的依賴關(guān)系,并且將他們進行整合打包讥珍。

(3)而webpack其中一個核心就是讓我們可以進行模塊化開發(fā)历极,并且會幫助我們處理模塊之間的依賴關(guān)系。

(4)在這里不僅僅是Javascript文件衷佃,我們的css趟卸、圖片、json文件等再webpack中都可以被當做模塊來使用氏义,這就是webpack模塊化的概念锄列。

1.2打包

(1)打包這個概念比較好理解了,就是利用webpack將各種資源進行打包合并為一個或者多個包(bundle)惯悠。在打包過程中邻邮,還可以對資源進行處理,比如壓圖片克婶,將scss轉(zhuǎn)成css筒严,將ES6語法轉(zhuǎn)成ES5語法丹泉,將TypeScript轉(zhuǎn)成Javascript等等操作。

(2)在這里我們會想到鸭蛙,gulp也可以進行資源的打包嘀掸,那么它和webpack有什么區(qū)別呢?

*webpack和grunt/gulp對比

(1)grunt/gulp的核心是Task

我們可以配置一系列的task规惰,并且定義task需要處理的事務(例如ES6轉(zhuǎn)ES5睬塌,ts轉(zhuǎn)化,圖片壓縮歇万,scss轉(zhuǎn)成css)揩晴,之后讓grunt/gulp來執(zhí)行這些task,而且讓整個流程自動化贪磺,所以grunt/gulp也被稱為前端自動化任務管理工具

(2)什么時候用grunt/gulp呢硫兰?

如果你的項目模塊依賴非常簡單,或者是沒有用到模塊化的概念寒锚,只需要進行簡單的合并和壓縮劫映,就使用grunt/gulp即可。但是如果整個項目使用了模塊化管理刹前,而且相互之間依賴非常強泳赋,我們就可以使用更加強大的webpack了。

(3)所以webpack和grunt/gulp有什么不同呢喇喉?

* grunt/gulp更強調(diào)的是前端流程的自動化祖今,模塊化不是它的核心。

* webpack更加強調(diào)模塊化開發(fā)管理拣技,而文件壓縮合并千诬,預處理等功能,是他附帶的功能膏斤。

2.webpack的安裝

* webpack為了可以正常運行必須依賴node環(huán)境徐绑。node自帶了包管理工具(npm)。

執(zhí)行指令:npm install webpack@3.6.0 -g 進行全局安裝莫辨。這里指定了下載3.6.0的版本傲茄。

(1)為什么全局安裝后還需要局部安裝呢?

在終端直接執(zhí)行webpack命令衔掸,使用的是全局安裝的webpack烫幕,但是當我們在package.json中定義了script時俺抽,其中包含了webpack命令敞映,那么使用的是局部的webpack。

3.webpack的基本使用

(1)在webpack打包中一般目錄結(jié)構(gòu):

src(源碼):用于存放我們的源文件

? ? ? ? main.js: 項目的入口文件(這里有時候也可以命名為index.js)磷斧。

? ? ? ? aaa.js定義了一些函數(shù)振愿,可以在其他地方引用捷犹,并且使用。

dist(distribution發(fā)布):用于存放之后打包的文件冕末。

index.html:瀏覽器打開展示的首頁html萍歉。

package.json:通過npm init 生成的,npm包管理的文件档桃。

(2)在src文件下我們寫的東西都可通過模塊化的方式去實現(xiàn)(AMD/CMD/CommonJs/ES6都可以)枪孩。

用CommonJs模塊化進行模塊化開發(fā)

CommonJs方式導出:module.exports = {}??

在入口文件main.js導入:const {add , mul} = require('./aaa.js');

用ES6的模塊化進行模塊開發(fā)

ES6方式導出:export const name = '庫里';

? ? ? ? ? ? ? ? ? ? ? ? ? ?export const age = 18;

在入口文件main.js中導入: import {name, age} from './info.js'

這個時候只需要用webpack打包一下,它會自動的幫我們處理模塊之間相互之間的依賴藻肄,處理完成后它會生成一個最終的js文件(bundle.js)蔑舞,我們在引用的時候只需要用最終生成的那個js文件就可以了。

4.webpack.config.js和package.json的配置

(1)配置webpack.config.js文件:

const path = require('path');? // 這里需要用到node里面的path模塊嘹屯,這里用到的是node里面的相關(guān)的包(執(zhí)行npm init攻询,生成一個package.json文件,這個文件是告訴我們項目中的一些相關(guān)信息的)州弟。

* 當package.json中依賴相關(guān)東西的話钧栖,我們需要執(zhí)行npm install,會根據(jù)里面所有的依賴幫助我們安裝一些所需要的東西婆翔。

module.exports= {

? ? entry: ' ./src/main.js ',? // 入口文件

? ? output: {? // 出口文件

? ? ? ? path: path.resolve(_dirname, 'dist'),? // 這里要動態(tài)獲取一個絕對路徑拯杠,這里引用到了一個path模塊中的resolve函數(shù),用來對我們兩個路徑拼接(_dirname這里對這個上下文變量進行拼接)啃奴。

? ? ? ? filename: ' bundle.js '

????}

}

當我們在webpack.config.js中進行了以上配置后阴挣,我們就可以在終端直接執(zhí)行webpack命令實現(xiàn)對項目的打包。

(2)如何用npm run build 命令替代webpack命令執(zhí)行打包效果纺腊?

這里還需要把二者進行一個映射:

打開package.json畔咧,對文件中scripts進行配置

"scripts": {

? ? "build": webpack

}

* 開發(fā)時依賴(這就是在本地安裝webpack要加--save-dev的原因,因為webpack只有在開發(fā)時需要揖膜,打包上傳到服務器后就沒用了)

*運行時依賴

前面有說到除了全局安裝一個webpack之外誓沸,我們還要在本地安裝一個webpack。執(zhí)行npm install webpack@3.6.0 --save-dev壹粟。

* 在終端中敲命令時拜隧,用到的webpack都是全局的,但是當我們在package.json中定義scripts腳本時趁仙,然后執(zhí)行npm run build洪添,此時用到的就是本地的webpack。

5.什么是loader雀费?

laoder在webpack中是一個非常核心的概念干奢。在開發(fā)中我們不僅僅有基本的js代碼處理,也需要加載css盏袄、圖片ES6的轉(zhuǎn)化忿峻,以及將.vue文件轉(zhuǎn)成js文件等等薄啥,對于webpack本身的能力來說,對于這些轉(zhuǎn)化是不支持的逛尚,這時候就需要用到loader解決垄惧。

loader使用過程:

(1)通過npm安裝需要使用的loader

(2)在webpack.config.js中的modules關(guān)鍵字下面進行配置

5.1webpack中css文件的配置

安裝style-loader: npm install style-loader --save-dev

* 注意:style-loader要放在css-loader前面,為什么呢绰寞?因為webpack在讀取使用loader的過程中到逊,是按照從右向左順序讀取的。負責將樣式添加到DOM中

安裝css-loader: npm install css-loader --save-dev? ?

* 這里如果只引入css-loader會發(fā)現(xiàn)樣式?jīng)]有生效滤钱,這是因為css-loader只負責加載css文件蕾管,但是并不負責將css具體樣式嵌入到文檔中,這個時候我們還需要引入一個style-laoder菩暗。

在webpack.config.js中進行配置(具體參考wabpack的官方文檔:https://www.webpackjs.com/)

module: {

? ? rules: [

? ? ? ? {

? ? ? ? ? ? test: /\.css$/,

? ? ? ? ? ? use: [ ' style-loader ' , ' css-loader ' ]

? ? ? ? }

? ? ]

}

5.2less文件處理

安裝less-loader: npm install less-loader less --save-dev

* 通過less加載對應的less文件掰曾,下載同時還會下載一個less的包,可以對less文件的相關(guān)代碼進行一個解析停团。

webpack.config.js中配置如下:

module: {

? ? rules: [

? ? ? ? {

? ? ? ? ? ? test: /\.css$/,

? ? ? ? ? ? use: [ ' style-loader ' , ' css-loader ' , 'less-loader']? ?// 這里也可以用對象的形式比如:loader:'style-loader'

? ? ? ? }

? ? ]

}

5.3webpack圖片文件的處理

安裝url-loader: npm install --save-dev url-loader

* 當我們需要加載比limit大的圖片時旷坦,我們需要下載file-loader。

安裝file-loader: npm install --save-dev file-loader

webpack.config.js中配置如下:

module: {

? ? rules: [

? ? ? ? {

? ? ? ? ? ? test: /\.(png|jpg|jpeg|gif)$/,

? ? ? ? ? ? use: [

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? loader: 'url-loader',

? ? ? ? ? ? ? ? ? ? options: {

? ? ? ? ? ? ? ? ? ? ? ? limit: 8192

? ? ? ? ? ? ? ? ? ? ? ? * 當加載的圖片小于limit時佑稠,會將圖片編譯成base64字符串形式秒梅。

? ? ? ? ? ? ? ? ? ? ? ? * 當加載的圖片大于limit時,需要使用file-loader模塊進行加載舌胶。

????????????????????}

????????????????}

????????????]

? ? ? ? }

? ? ]

}

* 我們發(fā)現(xiàn)捆蜀,在圖片打包的時候webpack自動幫助我們生成了一個非常長的名字,這是一個32位的hash值幔嫂,目的就是防止名字重復辆它,但是實際開發(fā)中我們對名字也有一定的要求,比如講所有的圖片放在一個文件夾中履恩,跟上原來圖片的名稱锰茉,同時還要防止重復。

所以我們可以在options中添加上如下選項:

img: 文件要打包到的文件夾

name: 獲取圖片原來的名字切心,放在該位置飒筑。

hash:8? 為了防止圖片名稱沖突,依然使用hash绽昏,但是只保留8位數(shù)协屡。

ext: 使用圖片原來的擴展名

例子: name: 'img/[name].[hash:8].[ext]';

5.4 ES6轉(zhuǎn)ES5的babel

安裝babel-loader: npm install --save-dev babel-loader@7 babel-core babel-preset-es2015

*在webpack中,ES6轉(zhuǎn)ES5需要使用對應的loader全谤,這時候就需要下載babel-loader

webpack.config.js中配置如下:

module:?{

? ? rules: [

? ? ? ? {

? ? ? ? ? ? test: /\.js$/,

????????????exclude: /(node_modules|bower_components)/, // 排除

? ? ? ? ? ? use: [

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? loader: 'babel-loader',

? ? ? ? ? ? ? ? ? ? options: {

????????????????????????presets: ['@babel/preset-env']

????????????????????}

????????????????}

????????????]

? ? ? ? }

? ? ]

}

5.5 webpack中vue配置過程

runtime-only // 這種版本代碼中不可以有任何的templete

runtime-compiler // 這種版本代碼中可以有template肤晓,因為有compiler可以用于編譯template

過程:

(1)安裝vue: npm install --save vue

(2)引入 import Vue from 'vue'

(3)由于vue版本不太對(runtime-only/runtime-complier),通過alias(別名)解決版本錯誤。

vue對應loader安裝: npm install vue-loader vue-template-compiler --save-dev

webpack.config.js中配置如下:

module: {

? ? rules: [

? ? ? ? {

? ? ? ? ? ? test: /\.vue$/,

? ? ? ? ? ? use: [

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? loader: 'vue-loader',

4? ? ? ? ? ? ? }

????????????]

? ? ? ? }

? ? ]

}

* package.json中的內(nèi)容修改后都要執(zhí)行一下npm install重新做一下安裝

5.6 el和template的區(qū)別

* 當你定義了一個template屬性材原,此時又有el屬性掛載沸久,這時候template定義的東西會替換掉el屬性所掛載的所有代碼

6. webpack-認識plugin(插件)

* plugin是插件的意思季眷,通常用于對現(xiàn)有的框架進行擴展余蟹。

*webpack中的插件,就是對webpack現(xiàn)有的功能進行各種擴展子刮,比如打包優(yōu)化威酒,文件壓縮等等。

*loader和plugin的區(qū)別: loader用于轉(zhuǎn)換某些類型的模塊它是一個轉(zhuǎn)換器挺峡。plugin是插件葵孤,它是對webpack本身的擴展,是一個擴展器橱赠。

*plugin使用過程:

通過npm安裝需要使用的plugin尤仍,在webpack.config.js中配置插件。

(1)BannerPlugin的使用,添加版權(quán)信息

plugins: [

? ? new wabpack.BannerPlugin('最終版權(quán)歸我所有')

]

(2)HtmlWebpackPlugin的使用

* 把根目錄下的index.html打包到dist文件中

* 這個插件可以自動生成一個index.html文件(可以指定模板來生成)狭姨,將打包的js文件宰啦,自動通過script標簽插入到body中

安裝:npm install html-webpack-plugin --save-dev

配置webpack.config.js:

const HtmlWebpackPlugin = require('html-webpack-plugin');? // 導入

plugins: [

? ? new wabpack.BannerPlugin('最終版權(quán)歸我所有'),

? ? new HtmlWebpackPlugin({

? ? ????template: 'index.html',? // 這里是可以指定模板的饼拍,指定某一個模板作為dist文件中生成的html文件的模板赡模。

????})

]

(3)UglifyjsWebpackPlugin的使用

* 對打包的js文件進行丑化壓縮的插件

* 我們使用一個第三方的插件uglifyjs-webpack-plugin,并且版本號指定1.1.1,和cli2保持一致

安裝: npm install uglifyjs-webpack-plugin@1.1.1 --save-dev

配置webpack.config.js:

const UglifyjsWebpackPlugin = require('html-webpack-plugin');? // 導入

plugins: [

? ? new wabpack.BannerPlugin('最終版權(quán)歸我所有')师抄,

? ? new HtmlWebpackPlugin(),

? ? new UglifyjsWebpackPlugin(),

]

7.搭建本地服務器

* webpack提供了一個可選的本地開發(fā)服務器漓柑,這個本地服務器基于nodejs搭建,內(nèi)部使用express框架叨吮,可以實現(xiàn)我們想要的讓瀏覽器自動刷新顯示我們修改后的結(jié)果辆布。

它是一個單獨的模塊,在webpack中使用它需要先安裝:

npm install --save-dev weback-dev-server@2.9.1

devserver也是作為webpack中的一個選項茶鉴,選項本身可以設置以下屬性:

contentBase: 為哪一個文件夾提供本地服務谚殊,默認是根文件夾,我們這里要填寫./dist

port: 端口號

inline: 頁面實時刷新

historyApiFallback: 在SPA頁面中蛤铜,依賴HTML5的history模式

配置webpack.config.js:

devServer: {

? ? contentBase: './dist',

? ? inline: true

}

開發(fā)時執(zhí)行腳本可以在package.json中加入'dev': 'weback-dev-server? --open',這時候執(zhí)行npm run dev就可以啟動本地服務器,加入--open可以實現(xiàn)執(zhí)行命令自動打開瀏覽器嫩絮。

* 開發(fā)階段不要加入UglifyjsWebpackPlugin插件,在發(fā)布階段再加入,因為丑化了js文件后围肥,調(diào)試階段不好閱讀

8.webpack配置文件的分離

* 有的配置是需要打包時候使用剿干,比如說丑化js等等,有的配置是需要本地開發(fā)時候使用穆刻,比如說配置本地服務器置尔。這里就需要把webpack配置進行一個分離,根據(jù)開發(fā)時候的配置和發(fā)布時候的配置氢伟。

這時候需要把以前的webpack.config.js分成三個不同的js榜轿,這三個不同的js放在根目錄下的build文件夾中分別是:

base.config.js :? 里面存放的是一些公共的配置

prod.config.js :生產(chǎn)環(huán)境的一些配置

dev.config.js : 開發(fā)環(huán)境的一些配置

這么分的思路就是我們把開發(fā)和生產(chǎn)環(huán)境的配置實現(xiàn)一個分離幽歼,這時候需要安裝一個webpack-merge的模塊,它的作用是把base和prod谬盐,base和dev甸私,分別合并,這樣就實現(xiàn)了開發(fā)和生產(chǎn)環(huán)境配置的分離飞傀。

安裝: npm install webpack-merge --save-dev

prod和base合并:

在prod.config.js中:

const baseConfig = require('./base.config.js');

module.exports = { baseConfig皇型,{

? ? plugins: [

? ??????new UglifyjsWebpackPlugin(),

????]

})

在dev.config.js中:

const baseConfig = require('./base.config.js');

module.exports = { baseConfig,{

????devServer: {

? ? ????contentBase: './dist',

? ????? inline: true

????}

})

但是這時候你要是執(zhí)行npm run build是會報錯的砸烦,因為我們現(xiàn)在已經(jīng)把webpack.config.js刪了弃鸦,這時候我們就需要在package.json中指定一下用哪個配置文件:

"scripts": {

? ? "build": ‘webpack --config ./build/prod.config.js',

? ? "dev": 'webpack-dev-server --open --config ./build/dev.config.js'

}

這時候就可以正常打包了,但是此時打包完成的dist文件是加到了build文件夾中幢痘,這個是因為我們在base.config.js中出口output拼接的目錄路徑錯誤唬格,修改一下目錄就可以了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末颜说,一起剝皮案震驚了整個濱河市购岗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌脑沿,老刑警劉巖藕畔,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異庄拇,居然都是意外死亡注服,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門措近,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溶弟,“玉大人,你說我怎么就攤上這事瞭郑」加” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵屈张,是天一觀的道長擒权。 經(jīng)常有香客問我,道長阁谆,這世上最難降的妖魔是什么碳抄? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮场绿,結(jié)果婚禮上剖效,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好璧尸,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布咒林。 她就那樣靜靜地躺著,像睡著了一般爷光。 火紅的嫁衣襯著肌膚如雪垫竞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天瞎颗,我揣著相機與錄音件甥,去河邊找鬼捌议。 笑死哼拔,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的瓣颅。 我是一名探鬼主播倦逐,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宫补!你這毒婦竟也來了檬姥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤粉怕,失蹤者是張志新(化名)和其女友劉穎健民,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贫贝,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡秉犹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了稚晚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片崇堵。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖客燕,靈堂內(nèi)的尸體忽然破棺而出鸳劳,到底是詐尸還是另有隱情,我是刑警寧澤也搓,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布赏廓,位于F島的核電站,受9級特大地震影響傍妒,放射性物質(zhì)發(fā)生泄漏幔摸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一拍顷、第九天 我趴在偏房一處隱蔽的房頂上張望抚太。 院中可真熱鬧,春花似錦、人聲如沸尿贫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庆亡。三九已至匾乓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間又谋,已是汗流浹背拼缝。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留彰亥,地道東北人咧七。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像任斋,于是被迫代替她去往敵國和親继阻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353