webpack基礎入門

我相信,有很多的朋友對webpack都有或多或少的瞭解。網上也有了各類各樣的文章,文章內做者也寫出了很多本身對於webpack這個工具的理解。在我剛剛接觸webpack的時候,老實說,網上大部分的文章我是看不懂的。。webpack裏面有不少名詞,是沒有接觸和理解過模塊化的同窗都難以理解的。我感受,學習任何一項新技術,要弄清楚爲何使用它,它是什麼,它有什麼用等概念,弄清楚這些概念以後,我相信,在往後的webpack學習中會達到事半功倍的效果。這篇文章,我會以最簡單的方式,闡述什麼是webpack。固然,這是我我的對webpack的一些理解,也是在學習中總結。javascript

另外,最好的學習webpack的資源是webpack的官網。傳送門:webpackcss

固然,若是你早已經是webpack的實踐者,對webpack認識足夠深刻,這篇文章不太適合您閱讀。若是你是小白,那就能夠開啓webpack的探索之路了。html

webpack是目前流行的一款模塊化打包工具。前端

webpack定義:一款前端資源模塊化和打包工具。vue

webpack做用:java

1. 將許多鬆散的模塊按照依賴關係和規則打包成符合生產環境環境部署的前端資源。 2. 將按需加載的模塊進行代碼分割,等到實際須要的時候再異步加載。 3. 經過加載器loader的轉換,全部的前端資源均可以看做是模塊。好比說CommonJS模塊,AMD模塊,ES6模塊,css,sass,json,圖片等。

短短的幾句話,就有太多讓人難以明白的地方。python

1. 什麼是前端資源?jquery

2. 什麼是模塊?webpack

3. 什麼是模塊化?css3

4. 什麼叫按需加載?

5. 如何實現按需加載?

6. 什麼是plugins?

7. 什麼是loader?

什麼是前端資源

所謂前端資源,就是咱們在建立html時,引入的script,link,img,json等文件。webpack足夠的優秀,只須要在html文件中引入一個js文件,在定義一個入口文件js,用於存放依賴的模塊,就能夠將其餘前端資源按照依賴關係和規則打包。

之前咱們須要這樣來引入文件。

<link rel="stylesheet" href="style/stylesheets/screen.css" media='screen'/ > <script src='script/jquery-2.2.1.min.js'></script> <script src='script/bootstrap.js'></script> <script src="script/index.js" ></script>

index.js依賴bootstrap.js,而bootstrap又依賴於jquery。咱們必須按照DOM順序來寫每個js文件。

如今只須要在html中引入一個主文件index.js,其餘依賴的前端資源都寫在另一個入口文件js中,這個入口文件不用寫在html中,而後配置好config,在cmd中輸入webpack執行編譯,全部前端資源都被引入了。而且webpack會幫咱們入口文件entry.js的每一個模塊的類型和依賴關係,等到須要的時候再按需加載。

//html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src='js/main.js'></script> <!-- 引入引入主模塊 main.js --> </body> </html> //entry.js import $ from 'jquery'; import other...

什麼是模塊

在webpack中,全部的前端資源都是模塊,能夠經過加載器loader進行轉換。在javascript方面,有幾大模塊系統,CommonJS模塊,AMD模塊,CMD模塊,ES6模塊。談談我對這幾大模塊的理解。

CommonJS

在CommonJS中,有一個全局方法require(),用於加載依賴模塊。

//main.js var jquery = require('jquery'); var bootstrap = require('bootstrap');

主文件main.js模塊依賴於這兩個模塊,CommonJS缺點就是同步加載。也就是說,會先加載jquery模塊,等到jquery加載完了再去加載bootstrap模塊。引用阮一峯老師的話

同步加載意味着阻塞加載,當依賴的模塊太大時,瀏覽器會處於假死的狀態。

假死意味着瀏覽器任然處在加載中,仍然仍是空白頁面。這種假死的狀態帶來的後果就是用戶的離開。

AMD模塊

AMD也叫異步模塊定義,英文Asynchronous Module Definition。AMD是requirejs對模塊定義時的產出。它採用異步方式加載模塊,每一個獨立模塊的加載不影響回調函數中定義的模塊的運行。在回調函數中定義一個模塊,只有當依賴的模塊加載完成以後,該模塊纔會編譯執行。AMD也採用require()語句來加載一個模塊,可是不一樣於CommonJS,它有兩個參數。第一個參數是數組,須要傳入依賴模塊;第二個參數是回調函數,回調函數中也接受參數,而參數是形式參數,來自於每個依賴模塊。舉個例子。

//main.js require(['jquery','bootstrap'],function($, boot){ //寫入的模塊 })

主模塊main.js依賴於jquery,Bootstrap模塊,main只有在這兩個模塊加載完成以後纔會編譯執行main定義的模塊,屬於同步加載。而在兩個依賴模塊中,屬於異步加載。也就是說bootstrap不用等到jquery加載完成以後再加載,被依賴的模塊是哪個模塊小,就先加載哪個,這就避免了CommonJS模塊中同步加載依賴模塊而出現瀏覽器假死的狀態。稍微總結一下,
主模塊須要等到依賴模塊加載完成以後才編譯執行,屬於同步加載;而被依賴模塊之間屬於異步加載,哪個模塊小,就先加載哪個。

AMD模塊的一大不足就是全部依賴的模塊都須要提早加載,依賴前置。

CMD模塊

CMD模塊跟AMD很類似,這裏引用玉伯老師的話看看CMD和AMD的區別。

對於依賴的模塊,AMD是提早執行,CMD是延遲執行。

CMD推從依賴就近,AMD推從依賴前置

依賴就近的意思就是當我須要某個模塊的時候再去異步加載。也就是按須要加載前端資源,懶加載。
能夠用八個字來總結CMD。依賴就近,延遲執行。

ES6模塊

ES6模塊的設計思想,是儘可能的靜態化,使得編譯時就能肯定模塊的依賴關係,以及輸入和輸出的變量。ES6中與CommonJS,AMD模塊一個區別在於ES6是經過import關鍵字來輸入某個模塊提供的功能,export或者export default規定該模塊的對外接口,通俗易懂一些,也就是暴露該模塊定義的一些屬性和方法,供其餘模塊調用。

ES6和CommonJS,AMD模塊最大的區別在於,ES6模塊能夠實現編譯時加載,簡單的說就是按需加載。然後兩種方法只能是運行時加載。上一段代碼。

ES6:
import {get, post, ajax} from 'jQuery'; CommonJS: var 

什麼是模塊化

webpack是支持以上的模塊系統的。在頭腦中要造成某種技術的知識框架才能學好該技術,因此花費了一些時間作了些介紹。模塊化就是webpack使用某種方法將每個鬆散的模塊按照依賴關係編譯的過程。webpack須要一個入口js文件,主模塊js文件,config文件就能夠實現前端資源模塊化。看個簡單的例子。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script src='js/main.js'></script> 1. <!-- 引入主模塊 main.js --> </body> </html> 2. //入口文件 entry.js document.write("<h1>I'm Uncke Keith!</h1>"); 3. //webpack.config.js module.exports = { entry :'./app/js/entry.js', output : { path: './dist/js' filename: 'main.js' } }; 4. //打開cmd,在文件目錄下,輸入webpack執行編譯就能夠看到document.write()的結果了。

什麼叫按需加載?

webpack的其中一個做用就是能夠將按需加載的模塊進行代碼分割,根據實際須要進行異步加載。按需加載,顧名思義就是按照用戶須要某個功能的時候在加載相應的模塊。舉個例子,當咱們在瀏覽一些圖片網站的時候,若是圖片在你打開該網站的時候就所有一塊兒加載好,那形成的後果就是頁面會保持一段時間的空白狀態,直到所有圖片加載完成以後纔會顯示。若是是按須要加載,就能夠在用戶剛進入頁面的時候加載可視區域窗口的圖片,當用戶拖動滾動條下拉的時候再去加載圖片,這樣不只減小HTTP請求,同時提升了頁面加載速度。在舉一個例子。在單頁應用中,爲了減小http請求次數,會把全部js文件合併爲一個文件,這樣請求數量減小了,但是請求的文件體積卻變大了。按需加載就能夠解決這個問題。

如何實現按需加載?

ES6的一大涉及思想就是想讓前端資源靜態化,在編譯的過程當中,而非運行過程當中就肯定模塊的依賴關係。webpack在編譯的過程當中,就會對整個代碼進行靜態分析,分析出各個模塊的類型和它們依賴關係,而後將不一樣類型的模塊提交給適配的加載器來處理。好比一個用 Sass 寫的樣式模塊,能夠先用 Sass-Loader加載器將它轉成一個CSS 模塊,在經過 CSS 模塊把他插入到頁面的 style 標籤中執行。而且在你編譯的時候就肯定了依賴關係。

什麼是plugins?

webpack跟咱們提供了不少內置的插件,能夠實現loader作不到的事情。在這裏介紹幾個經常使用的插件。

1. extract-text-webpack-plugin

咱們在入口文件中import(或者require)進一些css文件時,webpack會幫咱們把css樣式與其餘前端資源打包到output的filename文件中,而後在head標籤中會自動加載一個style標籤。可是,咱們可能會須要獨立出一個css文件,這時候就須要使用extract-text-webpack-plugin插件了。具體用法以下:

var ExtractTextPlugin = require("extract-text-webpack-plugin"); //這裏須要使用CommonJS語法來引入一個依賴。 module.exports = { module: { loaders: [ { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") } //loader的執行順序是 先執行css-loader給css文件加上地址,而後執行style-loader在頭部加上style標籤。 ] }, plugins: [ new ExtractTextPlugin("styles.css") //使用plugins選項對象,使用new調用ExtractTextPlugin構造函數,傳入的參數是須要單獨生成的css文件,路徑與output中的path路徑相同。詳細的參數能夠到extract-text-webpack-plugin官網查看。 ] }

當咱們成功生成了單獨的css文件以後,就能夠經過link標籤引入了。

什麼是loader?

Webpack 自己只能處理原生的 JavaScript 模塊,可是 loader 轉換器能夠將各類類型的資源轉換成 JavaScript 模塊。這樣,任何資源均可以成爲 Webpack 能夠處理的模塊。每個loader都會針對入口文件entry.js的依賴模塊引入的前端資源進行轉換。站在更高的角度上看問題,咱們在webpack.config.js裏面的全部配置都是針對入口文件的,始終記住這點很重要。由於這就是咱們配置webpack.config.js的目的。在這裏介紹一些經常使用loader。

1. postcss-loader

我是一名sass實踐者,而且用着一個封裝了不少mixins的compass庫,這個庫的最大好處就是能夠直接include一些compass封裝好的的css3的mixin時,編譯以後會幫咱們加上css前綴。若是想在.vue中也實現這種自動前綴的功能,可使用webpack給咱們提供的postcss-loader。(能夠去官網查看相關介紹)。postcss?這又是什麼鬼,其實postcss只是一個平臺,咱們須要用的是基於postcss平臺上的一些經常使用的插件。

若是想使用這個插件,須要下載一些依賴。

cnpm install autoprefixer --save-dev //autoprefixer用於添加css3前綴

具體的webpack.config.js配置以下

//注意先引入依賴 var ExtractTextPlugin = require('extract-text-webpack-plugin'); var autoprefixer = require('autoprefixer'); module.exports = { entry: __dirname + '/app/entry.js', output: { path: __dirname + '/dist', filename: 'bundle.js' }, module: { config... }, postcss:[ autoprefixer() ] };

若是你的入口文件entry.js是這樣的。

...
import './assets/main.scss';

那麼固然你在main.scss使用scss語法寫一些css3屬性時,在編譯以後就能夠看到css3前綴了。可是若是你的樣式是寫在*.vue組件裏面的

好比說,入口文件entry.js是這樣的。

...
import app from './app.vue';

topBar.vue

<template> config... </template> <script> config... </script> <style lang='sass' scoped> .main{ font-weight: bold; p { border-radius: 10px; box-shadow: 3px 3px 3px #ccc; transition: all 0.3s; 此處測試css3的屬性前綴 } } </style>

在瀏覽器中查看效果,你會發現,.vue組件中定義的style樣式並無加上屬性前綴。

.main p[data-v-a64cfc10] { background-color: red; border-radius: 10px; box-shadow: 3px 3px 3px #ccc; color: red; display: inline-block; font-weight: bold; height: 100px; transition: all 0.3s ease 0s; }

難道是postcss-loader失效了?其實並非。出現這種狀況的緣由主要仍是對vue-loader不熟悉致使的。由於你是把樣式寫在了單個*.vue組件中,因此這裏會涉及另一個lodaer,也就是Vue官方提供的vue-loader。在vue-loader中若是也想讓樣式擁有前綴,在webpack.config.js要進行以下配置。

module.exports = {
 entry: ... ,  output: { ... },  module: { ... }, 這裏配置vue指的是vue-loader,咱們須要在vue-loader中再一次配置postcss。  vue: {  postcss: [require('autoprefixer')()],  autoprefixer: true },  postcss:[ autoprefixer() ] //也就是說,postcss須要配置兩處。一是解析entry.js中引入的css模塊;一處是解析 單個*.vue組件的<style>標籤中的樣式。 }

執行編譯,你會發現正常顯示了。

相關文章
相關標籤/搜索