webpack基础入门
我相信,有不少的朋友對(duì)webpack都有或多或少的了解。網(wǎng)上也有了各種各樣的文章,文章內(nèi)作者也寫(xiě)出了不少自己對(duì)于webpack這個(gè)工具的理解。在我剛剛接觸webpack的時(shí)候,老實(shí)說(shuō),網(wǎng)上大部分的文章我是看不懂的。。webpack里面有很多名詞,是沒(méi)有接觸和理解過(guò)模塊化的同學(xué)都難以理解的。我感覺(jué),學(xué)習(xí)任何一項(xiàng)新技術(shù),要弄清楚為什么使用它,它是什么,它有什么用等概念,弄清楚這些概念之后,我相信,在日后的webpack學(xué)習(xí)中會(huì)達(dá)到事半功倍的效果。這篇文章,我會(huì)以最簡(jiǎn)單的方式,闡述什么是webpack。當(dāng)然,這是我個(gè)人對(duì)webpack的一些理解,也是在學(xué)習(xí)中總結(jié)。
另外,最好的學(xué)習(xí)webpack的資源是webpack的官網(wǎng)。傳送門(mén):webpack
當(dāng)然,如果你早已是webpack的實(shí)踐者,對(duì)webpack認(rèn)識(shí)足夠深入,這篇文章不太適合您閱讀。如果你是小白,那就可以開(kāi)啟webpack的探索之路了。
webpack是目前流行的一款模塊化打包工具。
webpack定義:一款前端資源模塊化和打包工具。
webpack作用:
1. 將許多松散的模塊按照依賴(lài)關(guān)系和規(guī)則打包成符合生產(chǎn)環(huán)境環(huán)境部署的前端資源。 2. 將按需加載的模塊進(jìn)行代碼分割,等到實(shí)際需要的時(shí)候再異步加載。 3. 通過(guò)加載器loader的轉(zhuǎn)換,所有的前端資源都可以看作是模塊。比如說(shuō)CommonJS模塊,AMD模塊,ES6模塊,css,sass,json,圖片等。短短的幾句話(huà),就有太多讓人難以明白的地方。
1. 什么是前端資源?
2. 什么是模塊?
3. 什么是模塊化?
4. 什么叫按需加載?
5. 如何實(shí)現(xiàn)按需加載?
6. 什么是plugins?
7. 什么是loader?
什么是前端資源
所謂前端資源,就是我們?cè)趧?chuàng)建html時(shí),引入的script,link,img,json等文件。webpack足夠的優(yōu)秀,只需要在html文件中引入一個(gè)js文件,在定義一個(gè)入口文件js,用于存放依賴(lài)的模塊,就可以將其他前端資源按照依賴(lài)關(guān)系和規(guī)則打包。
以前我們需要這樣來(lái)引入文件。
<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依賴(lài)bootstrap.js,而bootstrap又依賴(lài)于jquery。我們必須按照DOM順序來(lái)寫(xiě)每一個(gè)js文件。
現(xiàn)在只需要在html中引入一個(gè)主文件index.js,其他依賴(lài)的前端資源都寫(xiě)在另外一個(gè)入口文件js中,這個(gè)入口文件不用寫(xiě)在html中,然后配置好config,在cmd中輸入webpack執(zhí)行編譯,所有前端資源都被引入了。并且webpack會(huì)幫我們?nèi)肟谖募ntry.js的每個(gè)模塊的類(lèi)型和依賴(lài)關(guān)系,等到需要的時(shí)候再按需加載。
//html什么是模塊
在webpack中,所有的前端資源都是模塊,可以通過(guò)加載器loader進(jìn)行轉(zhuǎn)換。在javascript方面,有幾大模塊系統(tǒng),CommonJS模塊,AMD模塊,CMD模塊,ES6模塊。談?wù)勎覍?duì)這幾大模塊的理解。
CommonJS
在CommonJS中,有一個(gè)全局方法require(),用于加載依賴(lài)模塊。
//main.js var jquery = require('jquery'); var bootstrap = require('bootstrap');主文件main.js模塊依賴(lài)于這兩個(gè)模塊,CommonJS缺點(diǎn)就是同步加載。也就是說(shuō),會(huì)先加載jquery模塊,等到j(luò)query加載完了再去加載bootstrap模塊。引用阮一峰老師的話(huà)
同步加載意味著阻塞加載,當(dāng)依賴(lài)的模塊太大時(shí),瀏覽器會(huì)處于假死的狀態(tài)。
假死意味著瀏覽器任然處在加載中,仍然還是空白頁(yè)面。這種假死的狀態(tài)帶來(lái)的后果就是用戶(hù)的離開(kāi)。
AMD模塊
AMD也叫異步模塊定義,英文Asynchronous Module Definition。AMD是requirejs對(duì)模塊定義時(shí)的產(chǎn)出。它采用異步方式加載模塊,每個(gè)獨(dú)立模塊的加載不影響回調(diào)函數(shù)中定義的模塊的運(yùn)行。在回調(diào)函數(shù)中定義一個(gè)模塊,只有當(dāng)依賴(lài)的模塊加載完成之后,該模塊才會(huì)編譯執(zhí)行。AMD也采用require()語(yǔ)句來(lái)加載一個(gè)模塊,但是不同于CommonJS,它有兩個(gè)參數(shù)。第一個(gè)參數(shù)是數(shù)組,需要傳入依賴(lài)模塊;第二個(gè)參數(shù)是回調(diào)函數(shù),回調(diào)函數(shù)中也接受參數(shù),而參數(shù)是形式參數(shù),來(lái)自于每一個(gè)依賴(lài)模塊。舉個(gè)例子。
//main.js require(['jquery','bootstrap'],function($, boot){ //寫(xiě)入的模塊 })主模塊main.js依賴(lài)于jquery,Bootstrap模塊,main只有在這兩個(gè)模塊加載完成之后才會(huì)編譯執(zhí)行main定義的模塊,屬于同步加載。而在兩個(gè)依賴(lài)模塊中,屬于異步加載。也就是說(shuō)bootstrap不用等到j(luò)query加載完成之后再加載,被依賴(lài)的模塊是哪一個(gè)模塊小,就先加載哪一個(gè),這就避免了CommonJS模塊中同步加載依賴(lài)模塊而出現(xiàn)瀏覽器假死的狀態(tài)。稍微總結(jié)一下,
主模塊需要等到依賴(lài)模塊加載完成之后才編譯執(zhí)行,屬于同步加載;而被依賴(lài)模塊之間屬于異步加載,哪一個(gè)模塊小,就先加載哪一個(gè)。
AMD模塊的一大不足就是所有依賴(lài)的模塊都需要提前加載,依賴(lài)前置。
CMD模塊
CMD模塊跟AMD很相似,這里引用玉伯老師的話(huà)看看CMD和AMD的區(qū)別。
對(duì)于依賴(lài)的模塊,AMD是提前執(zhí)行,CMD是延遲執(zhí)行。
CMD推從依賴(lài)就近,AMD推從依賴(lài)前置
依賴(lài)就近的意思就是當(dāng)我需要某個(gè)模塊的時(shí)候再去異步加載。也就是按需要加載前端資源,懶加載。
可以用八個(gè)字來(lái)總結(jié)CMD。依賴(lài)就近,延遲執(zhí)行。
ES6模塊
ES6模塊的設(shè)計(jì)思想,是盡量的靜態(tài)化,使得編譯時(shí)就能確定模塊的依賴(lài)關(guān)系,以及輸入和輸出的變量。ES6中與CommonJS,AMD模塊一個(gè)區(qū)別在于ES6是通過(guò)import關(guān)鍵字來(lái)輸入某個(gè)模塊提供的功能,export或者export default規(guī)定該模塊的對(duì)外接口,通俗易懂一些,也就是暴露該模塊定義的一些屬性和方法,供其他模塊調(diào)用。
ES6和CommonJS,AMD模塊最大的區(qū)別在于,ES6模塊可以實(shí)現(xiàn)編譯時(shí)加載,簡(jiǎn)單的說(shuō)就是按需加載。而后兩種方法只能是運(yùn)行時(shí)加載。上一段代碼。
ES6: import {get, post, ajax} from 'jQuery';CommonJS: var什么是模塊化
webpack是支持以上的模塊系統(tǒng)的。在頭腦中要形成某種技術(shù)的知識(shí)框架才能學(xué)好該技術(shù),所以花費(fèi)了一些時(shí)間做了些介紹。模塊化就是webpack使用某種方法將每一個(gè)松散的模塊按照依賴(lài)關(guān)系編譯的過(guò)程。webpack需要一個(gè)入口js文件,主模塊js文件,config文件就可以實(shí)現(xiàn)前端資源模塊化。看個(gè)簡(jiǎn)單的例子。
什么叫按需加載?
webpack的其中一個(gè)作用就是可以將按需加載的模塊進(jìn)行代碼分割,根據(jù)實(shí)際需要進(jìn)行異步加載。按需加載,顧名思義就是按照用戶(hù)需要某個(gè)功能的時(shí)候在加載相應(yīng)的模塊。舉個(gè)例子,當(dāng)我們?cè)跒g覽一些圖片網(wǎng)站的時(shí)候,如果圖片在你打開(kāi)該網(wǎng)站的時(shí)候就全部一起加載好,那造成的后果就是頁(yè)面會(huì)保持一段時(shí)間的空白狀態(tài),直到全部圖片加載完成之后才會(huì)顯示。如果是按需要加載,就可以在用戶(hù)剛進(jìn)入頁(yè)面的時(shí)候加載可視區(qū)域窗口的圖片,當(dāng)用戶(hù)拖動(dòng)滾動(dòng)條下拉的時(shí)候再去加載圖片,這樣不僅減少HTTP請(qǐng)求,同時(shí)提高了頁(yè)面加載速度。在舉一個(gè)例子。在單頁(yè)應(yīng)用中,為了減少http請(qǐng)求次數(shù),會(huì)把所有js文件合并為一個(gè)文件,這樣請(qǐng)求數(shù)量減少了,可是請(qǐng)求的文件體積卻變大了。按需加載就可以解決這個(gè)問(wèn)題。
如何實(shí)現(xiàn)按需加載?
ES6的一大涉及思想就是想讓前端資源靜態(tài)化,在編譯的過(guò)程中,而非運(yùn)行過(guò)程中就確定模塊的依賴(lài)關(guān)系。webpack在編譯的過(guò)程中,就會(huì)對(duì)整個(gè)代碼進(jìn)行靜態(tài)分析,分析出各個(gè)模塊的類(lèi)型和它們依賴(lài)關(guān)系,然后將不同類(lèi)型的模塊提交給適配的加載器來(lái)處理。比如一個(gè)用 Sass 寫(xiě)的樣式模塊,可以先用 Sass-Loader加載器將它轉(zhuǎn)成一個(gè)CSS 模塊,在通過(guò) CSS 模塊把他插入到頁(yè)面的 style 標(biāo)簽中執(zhí)行。并且在你編譯的時(shí)候就確定了依賴(lài)關(guān)系。
什么是plugins?
webpack跟我們提供了很多內(nèi)置的插件,可以實(shí)現(xiàn)loader做不到的事情。在這里介紹幾個(gè)常用的插件。
1. extract-text-webpack-plugin
我們?cè)谌肟谖募衖mport(或者require)進(jìn)一些css文件時(shí),webpack會(huì)幫我們把css樣式與其他前端資源打包到output的filename文件中,然后在head標(biāo)簽中會(huì)自動(dòng)加載一個(gè)style標(biāo)簽。但是,我們可能會(huì)需要獨(dú)立出一個(gè)css文件,這時(shí)候就需要使用extract-text-webpack-plugin插件了。具體用法如下:
var ExtractTextPlugin = require("extract-text-webpack-plugin"); //這里需要使用CommonJS語(yǔ)法來(lái)引入一個(gè)依賴(lài)。module.exports = { module: { loaders: [ { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") } //loader的執(zhí)行順序是 先執(zhí)行css-loader給css文件加上地址,然后執(zhí)行style-loader在頭部加上style標(biāo)簽。 ] }, plugins: [ new ExtractTextPlugin("styles.css") //使用plugins選項(xiàng)對(duì)象,使用new調(diào)用ExtractTextPlugin構(gòu)造函數(shù),傳入的參數(shù)是需要單獨(dú)生成的css文件,路徑與output中的path路徑相同。詳細(xì)的參數(shù)可以到extract-text-webpack-plugin官網(wǎng)查看。 ] }當(dāng)我們成功生成了單獨(dú)的css文件之后,就可以通過(guò)link標(biāo)簽引入了。
什么是loader?
Webpack 本身只能處理原生的 JavaScript 模塊,但是 loader 轉(zhuǎn)換器可以將各種類(lèi)型的資源轉(zhuǎn)換成 JavaScript 模塊。這樣,任何資源都可以成為 Webpack 可以處理的模塊。每一個(gè)loader都會(huì)針對(duì)入口文件entry.js的依賴(lài)模塊引入的前端資源進(jìn)行轉(zhuǎn)換。站在更高的角度上看問(wèn)題,我們?cè)趙ebpack.config.js里面的所有配置都是針對(duì)入口文件的,始終記住這點(diǎn)很重要。因?yàn)檫@就是我們配置webpack.config.js的目的。在這里介紹一些常用loader。
1. postcss-loader
我是一名sass實(shí)踐者,并且用著一個(gè)封裝了很多mixins的compass庫(kù),這個(gè)庫(kù)的最大好處就是可以直接include一些compass封裝好的的css3的mixin時(shí),編譯之后會(huì)幫我們加上css前綴。如果想在.vue中也實(shí)現(xiàn)這種自動(dòng)前綴的功能,可以使用webpack給我們提供的postcss-loader。(可以去官網(wǎng)查看相關(guān)介紹)。postcss?這又是什么鬼,其實(shí)postcss只是一個(gè)平臺(tái),我們需要用的是基于postcss平臺(tái)上的一些常用的插件。
如果想使用這個(gè)插件,需要下載一些依賴(lài)。
cnpm install autoprefixer --save-dev //autoprefixer用于添加css3前綴具體的webpack.config.js配置如下
//注意先引入依賴(lài) 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';那么當(dāng)然你在main.scss使用scss語(yǔ)法寫(xiě)一些css3屬性時(shí),在編譯之后就可以看到css3前綴了。但是如果你的樣式是寫(xiě)在*.vue組件里面的
比如說(shuō),入口文件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; 此處測(cè)試css3的屬性前綴 } } </style>在瀏覽器中查看效果,你會(huì)發(fā)現(xiàn),.vue組件中定義的style樣式并沒(méi)有加上屬性前綴。
.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失效了?其實(shí)并不是。出現(xiàn)這種情況的原因主要還是對(duì)vue-loader不熟悉導(dǎo)致的。因?yàn)槟闶前褬邮綄?xiě)在了單個(gè)*.vue組件中,所以這里會(huì)涉及另外一個(gè)lodaer,也就是Vue官方提供的vue-loader。在vue-loader中如果也想讓樣式擁有前綴,在webpack.config.js要進(jìn)行如下配置。
module.exports = { entry: ... , output: { ... }, module: { ... },這里配置vue指的是vue-loader,我們需要在vue-loader中再一次配置postcss。 vue: { postcss: [require('autoprefixer')()], autoprefixer: true }, postcss:[ autoprefixer() ] //也就是說(shuō),postcss需要配置兩處。一是解析entry.js中引入的css模塊;一處是解析 單個(gè)*.vue組件的<style>標(biāo)簽中的樣式。 }執(zhí)行編譯,你會(huì)發(fā)現(xiàn)正常顯示了。
轉(zhuǎn)載于:https://www.cnblogs.com/chenliyang/p/6548336.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的webpack基础入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Problem E: 平面上的点——Po
- 下一篇: 双足机器人简单步态生成