寫(xiě)在前面的話:以下內(nèi)容會(huì)結(jié)合實(shí)例進(jìn)行分析webpack安裝與使用過(guò)程中遇到的問(wèn)題及解決方法
1即碗、webpack安裝
webpack可以使用npm進(jìn)行安裝,首先在任意磁盤(pán)下新建一個(gè)文件夾(我的建立在E盤(pán))webpack-demo,請(qǐng)執(zhí)行以下操作步驟:
(1)E: //轉(zhuǎn)到E盤(pán)
(2)cd webpack-demo //轉(zhuǎn)到webpack-demo文件夾
(3)npm init //通過(guò)這個(gè)命令可以自動(dòng)創(chuàng)建一個(gè)package.json文件,這是一個(gè)標(biāo)準(zhǔn)的npm說(shuō)明文件,里面包含當(dāng)前項(xiàng)目的依賴模塊,自定義的腳本任務(wù)等等
(4-1)npm install webpack -g //全局安裝奈附,或是
(4-2)npm install webpack --save-dev //本地安裝
(5)在webpack-demo文件夾下新建app和dist兩個(gè)文件夾,其中app文件夾用于存放原始數(shù)據(jù)和JS模塊煮剧,dist文件夾存放之后供瀏覽器讀取的文件斥滤,一般是index.html文件(包括使用webpack打包生成的js文件)
(6)在app文件夾下新建sayHello.js和main.js文件,在dist文件夾下新建index.html和main.js文件(由于webpack4之后在打包時(shí)會(huì)生成dist文件夾和main.js文件勉盅,因此這里需要?jiǎng)?chuàng)建佑颇,不然會(huì)報(bào)錯(cuò))
2、不需任何配置使用webpack
webpack打包語(yǔ)法為:webpack {entry file} {output file}草娜,其中entry file代表入口文件的路徑挑胸,也就是上面的app/main.js文件,output file代表打包后的文件存放路徑宰闰,也就是上面的dist/main.js茬贵,然后執(zhí)行以下命令:
(1-1)webpack app/main.js dist/main.js //全局安裝webpack的使用此條命令
注意:經(jīng)過(guò)本人實(shí)際測(cè)試發(fā)現(xiàn),執(zhí)行上述命令時(shí)會(huì)報(bào)錯(cuò)移袍,根據(jù)實(shí)際的報(bào)錯(cuò)原因是需要安裝webpack-cli解藻,這是因?yàn)閣ebpack4已將webpack命令行相關(guān)內(nèi)容都遷移到了webpack-cli中,所以除了安裝webpack之外還需要安裝webpack-cli
(1-2)node_modules/.bin/webpack app/main.js dist/main.js //本地安裝webpack的使用此條命令
(2)打開(kāi)index.html文件即可查看輸出內(nèi)容
3葡盗、通過(guò)webpack.consig.js配置文件來(lái)使用webpack
正如上面第2步中看到的螟左,當(dāng)我們執(zhí)行webpack打包命令時(shí)需要輸入一長(zhǎng)串的內(nèi)容,這是非常不方便的,而且也很容易出錯(cuò)胶背,那么怎么才能方便一點(diǎn)呢虫啥,就是通過(guò)webpack.config.js文件來(lái)實(shí)現(xiàn),執(zhí)行以下操作步驟:
(1)在webpack-demo文件夾下新建webpack.config.js文件并加入如下代碼:
module.exports = {
??entry: __dirname + "/app/main.js",//唯一的入口文件奄妨,其__dirname是當(dāng)前執(zhí)行腳本所在的目錄
??output: {
????path: __dirname + "/dist",//打包后的文件存放路徑
????filename: "main.js"http://打包后輸出文件的文件名
??}
}
(2-1)webpack //全局安裝的執(zhí)行這條命令,此命令會(huì)自動(dòng)引用webpack.config.js文件中的配置選項(xiàng)
(2-2)node_modules/.bin/webpack //本地安裝的執(zhí)行這條命令
可以看出相比之前第2步(正式使用webpack)中的命令簡(jiǎn)單的很多
4苹祟、通過(guò)package.json文件使用webpack
正如上面第3步中看到的砸抛,我們?cè)趫?zhí)行webpack打包命令時(shí)還是需要輸入像webpack(或是node_modules/.bin/webpack)這樣的命令,感覺(jué)還是很繁瑣树枫,怎么辦呢直焙,就是通過(guò)package.json實(shí)現(xiàn),請(qǐng)執(zhí)行以下操作步驟:
(1)在package.json文件中對(duì)scripts對(duì)象進(jìn)行設(shè)置砂轻,代碼如下:
"scripts": {
??"test": "echo \"Error: no test specified\" && exit 1",
??"start": "webpack",
},
(2)npm start //package.json中的script會(huì)安裝一定順序?qū)ふ颐顚?duì)應(yīng)位置奔誓,本地的node_modules/.bin路徑就在這個(gè)尋找清單中,所以無(wú)論是全局還是局部安裝的webpack搔涝,你都不需要寫(xiě)前面那指明詳細(xì)的路徑了厨喂。
注意:在package.json文件的scripts對(duì)象中添加完"start":"webpack"之后執(zhí)行npm start會(huì)報(bào)錯(cuò)誤,也是類(lèi)似上文已經(jīng)提到的需要安裝webbpack-cli庄呈,但是我們?cè)谏衔膱?bào)錯(cuò)時(shí)已經(jīng)安裝了webpack-cli蜕煌,然而需要意識(shí)到我們?cè)谏衔闹皇窃谌职惭b了webpack-cli,而沒(méi)有在本地安裝诬留,因此在這里需要進(jìn)行本地安裝webpack-cli斜纪,經(jīng)過(guò)我實(shí)際測(cè)試,這樣做之后就不會(huì)再報(bào)錯(cuò)了文兑。但是盒刚,問(wèn)題又來(lái)了,此時(shí)會(huì)有一個(gè)警告绿贞,大概意思是說(shuō)'mode'沒(méi)有定義因块,這是 webpack 4x 引入的,有兩個(gè)值樟蠕,development 和 production贮聂。默認(rèn)是production。怎么解決呢寨辩?我們只需修改一下"start":"webpack"為"start":"webpack --config webpack.config.js --mode development"即可吓懈,其中--config webpack.config.js可以不寫(xiě),默認(rèn)就是它靡狞,此時(shí)再次運(yùn)行npm start那命令行真的是干干凈凈耻警,一個(gè)錯(cuò)誤和警告都沒(méi)有了!
5、webpack功能——Source Maps
我們?cè)陂_(kāi)發(fā)的過(guò)程中總是要調(diào)試代碼甘穿,方便的調(diào)試能極大的提高開(kāi)發(fā)效率腮恩,不過(guò)有時(shí)候通過(guò)打包后的文件,你是不容易找到出錯(cuò)了的地方温兼,對(duì)應(yīng)的你寫(xiě)的代碼的位置的秸滴,Source Maps就是來(lái)幫我們解決這個(gè)問(wèn)題的。通過(guò)簡(jiǎn)單的配置募判,webpack就可以在打包時(shí)為我們生成的source maps荡含,這為我們提供了一種對(duì)應(yīng)編譯文件和源文件的方法,使得編譯后的代碼可讀性更高届垫,也更容易調(diào)試释液。在webpack的配置文件中配置source maps,需要配置devtool装处,它有以下四種不同的配置選項(xiàng)误债,各具優(yōu)缺點(diǎn),描述如下:
正如上表所述妄迁,上述選項(xiàng)由上到下打包速度越來(lái)越快寝蹈,不過(guò)同時(shí)也具有越來(lái)越多的負(fù)面作用,較快的打包速度的后果就是對(duì)打包后的文件的的執(zhí)行有一定影響判族。對(duì)小到中型的項(xiàng)目中躺盛,eval-source-map是一個(gè)很好的選項(xiàng),再次強(qiáng)調(diào)你只應(yīng)該開(kāi)發(fā)階段使用它形帮,cheap-module-eval-source-map方法構(gòu)建速度更快槽惫,但是不利于調(diào)試,推薦在大型項(xiàng)目考慮時(shí)間成本時(shí)使用辩撑。我們繼續(xù)對(duì)上文新建的webpack.config.js界斜,進(jìn)行如下配置:
module.exports = {
??
devtool: 'eval-source-map',
}
6、webpack功能——構(gòu)建本地服務(wù)器
我們?cè)谄綍r(shí)調(diào)試代碼時(shí)總是修改之后要去刷新頁(yè)面合冀,那在webpack中我們可以通過(guò)構(gòu)建本地服務(wù)器來(lái)實(shí)現(xiàn)自動(dòng)刷新顯示修改后的結(jié)果各薇,webpack提供一個(gè)可選的本地開(kāi)發(fā)服務(wù)器,這個(gè)本地服務(wù)器基于node.js構(gòu)建君躺,可以實(shí)現(xiàn)你想要的這些功能峭判,不過(guò)它是一個(gè)單獨(dú)的組件,在webpack中進(jìn)行配置之前需要單獨(dú)安裝它作為項(xiàng)目依賴棕叫,請(qǐng)執(zhí)行以下操作步驟:
(1)npm install webpack-dev-server --save-dev
(2)devserver作為webpack配置選項(xiàng)中的一項(xiàng)林螃,需要添加以下代碼到webpack.config.js中
module.exports = {
??devServer: {
????contentBase: "./dist",//本地服務(wù)器所加載的頁(yè)面所在的目錄,要注意這里的./中的.千萬(wàn)不能丟失俺泣,否則啟動(dòng)服務(wù)器之后頁(yè)面會(huì)輸出Cannot GET /的錯(cuò)誤
????historyApiFallback: true,//在開(kāi)發(fā)單頁(yè)應(yīng)用時(shí)非常有用疗认,它依賴于HTML5 history API完残,如果設(shè)置為true,所有的跳轉(zhuǎn)將指向index.html(即:不跳轉(zhuǎn))
????inline: true,//設(shè)置為true横漏,當(dāng)源文件改變時(shí)會(huì)自動(dòng)刷新頁(yè)面
????port: 8080//設(shè)置默認(rèn)監(jiān)聽(tīng)端口谨设,如果省略,默認(rèn)為"8080"
??}
}
(3)添加以下命令到package.json文件中:
"scripts": {
??"server": "webpack-dev-server --open --mode development"
}
(4)啟動(dòng)服務(wù)器:npm run server缎浇,啟動(dòng)之后會(huì)自動(dòng)打開(kāi)瀏覽器頁(yè)面localhost:8080
注意:可能已經(jīng)發(fā)現(xiàn)一些與上文不一樣的東西了扎拣,什么呢?那就是為什么上文中我們配置完"start":"webpack"之后素跺,我們?cè)谶\(yùn)行時(shí)輸入的是npm start鹏秋,而現(xiàn)在配置完"server":"..."之后運(yùn)行的是npm run server,這其中多了一個(gè)run亡笑,這是因?yàn)閚pm的start命令是一個(gè)特殊的腳本名稱,其特殊性表現(xiàn)在横朋,在命令行中使用npm start就可以執(zhí)行其對(duì)于的命令仑乌,如果對(duì)應(yīng)的此腳本名稱不是start,想要在命令行中運(yùn)行時(shí)琴锭,需要這樣用npm run {script name}如npm run server
7晰甚、webpack功能——loaders
Loaders是webpack提供的最激動(dòng)人心的功能之一了。通過(guò)使用不同的loader决帖,webpack有能力調(diào)用外部的腳本或工具厕九,實(shí)現(xiàn)對(duì)不同格式的文件的處理,比如說(shuō)分析轉(zhuǎn)換scss為css地回,或者把下一代的JS文件(ES6扁远,ES7)轉(zhuǎn)換為現(xiàn)代瀏覽器兼容的JS文件,對(duì)React的開(kāi)發(fā)而言刻像,合適的Loaders可以把React的中用到的JSX文件轉(zhuǎn)換為JS文件畅买。Loaders需要單獨(dú)安裝并且需要在webpack.config.js中的modules關(guān)鍵字下進(jìn)行配置。由于在編寫(xiě)程序的過(guò)程中我們會(huì)涉及到使用ES6细睡、ES7谷羞、React等的情況,因此我在操作過(guò)程中會(huì)安裝babel溜徙,其實(shí)babel是一個(gè)兒編譯JavaScript的平臺(tái)湃缎,它可以讓你能使用最新的JavaScript代碼(ES6,ES7...)蠢壹,而不用管新標(biāo)準(zhǔn)是否被當(dāng)前使用的瀏覽器完全支持嗓违;讓你能使用基于JavaScript進(jìn)行了拓展的語(yǔ)言,比如React的JSX知残。請(qǐng)執(zhí)行以下操作步驟:
(1)安裝babel:npm install babel-core babel-loader babel-preset-env babel-preset-react --save-dev //其中babel-core是核心功能靠瞎,babel-preset-env用來(lái)解析ES6比庄,babel-preset-react用來(lái)解析JSX語(yǔ)法,并且在一次性安裝多個(gè)依賴模塊時(shí)乏盐,模塊之間用空格隔開(kāi)
(2-1)配置babel:在webpack.config.js文件中加入以下代碼:
module.exports = {
??module: {
????rules: [
??????{
????????test: /(\.jsx|\.js)$/,//一個(gè)用以匹配loaders所處理文件的拓展名的正則表達(dá)式(必須)
????????use: {
??????????loader: "babel-loader",//loader的名稱(必須)
??????????options: {
????????????presets: [
??????????????"env", "react"
????????????]
??????????}
????????},
????????exclude: /node_modules/ //include/exclude:手動(dòng)添加必須處理的文件(文件夾)或屏蔽不需要處理的文件(文件夾)(可選)佳窑;
??????}
????]
??}
}
(2-2)babel可以在webpack.config.js中進(jìn)行配置,但是由于babel有很多配置項(xiàng)會(huì)導(dǎo)致webpack.config.js文件顯得很臃腫父能,因此一般會(huì)把babel的配置項(xiàng)(options)單獨(dú)放在一個(gè)名字為".babelrc"的配置文件中神凑,配置完成后webpack會(huì)自動(dòng)調(diào)用.babelrc文件里的babelrc配置選項(xiàng)
執(zhí)行完上邊步驟(2)之后我們就可以使用ES6和JSX語(yǔ)法來(lái)編寫(xiě)程序了,但是如果我們想使用React(JSX只是編寫(xiě)React的一種方式)編寫(xiě)程序還需要安裝react和react-dom
(3)npm install react react-dom --save-dev
8何吝、webpack功能——CSS
webpack中有兩個(gè)處理樣式表的工具:css-loader和style-loader溉委,二者處理的任務(wù)不同,css-loader使你能夠使用類(lèi)似@import 和 url(...)的方法實(shí)現(xiàn) require()的功能爱榕;style-loader將所有的計(jì)算后的樣式加入頁(yè)面中瓣喊,二者組合在一起使你能夠把樣式表嵌入webpack打包后的JS文件中。請(qǐng)執(zhí)行以下操作步驟:
(1)npm install css-loader style-loader --save-dev
(2)在webpach.config.js中配置黔酥,代碼如下:
module.exports = {
??module: {
????rules: [
??????{
????????test: /\.css$/,
????????use: [
??????????{
????????????loader: "style-loader"
??????????}, {
????????????loader: "css-loader"
??????????}
????????]
??????}
????]
??}
}
9藻三、webpack功能——CSS預(yù)處理器
Sass、Less之類(lèi)的預(yù)處理器是對(duì)CSS的擴(kuò)展跪者,允許使用類(lèi)似于變量的不存在與原生CSS中的特性來(lái)寫(xiě)CSS棵帽,CSS預(yù)處理器可以這些特殊類(lèi)型的語(yǔ)句轉(zhuǎn)化為瀏覽器可識(shí)別的CSS語(yǔ)句,其實(shí)存在一個(gè)CSS處理平臺(tái)-PostCSS渣玲,幫助CSS實(shí)現(xiàn)更多的功能逗概,請(qǐng)執(zhí)行以下操作步驟:
(1)npm install postcss-loader autoprefixer --save-dev //autoprefixer是自動(dòng)添加前綴的插件
(2)在webpack.config.js中添加postcss-loader,代碼如下:
module.exports = {
??module: {
????rules: [
??????{
????????test: /\.css$/,
????????use: [
??????????{
????????????loader: "postcss-loader"
??????????}
????????]
??????}
????]
??}
}
(3)在根目錄新建postcss.config.js并添加如下代碼:
module.exports = {
??plugins: [
????require('autoprefixer')
??]
}
(4)npm start //你寫(xiě)的css會(huì)自動(dòng)添加不同前綴了
10忘衍、webpack功能——插件(Plugins)
插件(Plugins)是用來(lái)拓展Webpack功能的逾苫,它們會(huì)在整個(gè)構(gòu)建過(guò)程中生效,執(zhí)行相關(guān)的任務(wù)枚钓。與loaders的區(qū)別在于loaders是在打包構(gòu)建過(guò)程中用來(lái)處理源文件的(JSX隶垮,Scss,Less..)秘噪,一次處理一個(gè)狸吞,插件(Plugins)并不直接操作單個(gè)文件,它直接對(duì)整個(gè)構(gòu)建過(guò)程其作用指煎。