vue-cli?腳手架中webpack?配置基礎(chǔ)文件詳解
一加酵、前言
vue-cli是構(gòu)建vue單頁(yè)應(yīng)用的腳手架,輸入一串指定的命令行從而自動(dòng)生成vue.js+wepack的項(xiàng)目模板钦勘。這其中webpack發(fā)揮了很大的作用,它使得我們的代碼模塊化肛响,引入一些插件幫我們完善功能可以將文件打包壓縮,圖片轉(zhuǎn)base64等雹有。后期對(duì)項(xiàng)目的配置使得我們對(duì)于腳手架自動(dòng)生成的代碼的理解更為重要,接下來我將基于webpack3.6.0版本結(jié)合文檔將文件各個(gè)擊破质帅,純干料。
重點(diǎn)章節(jié)點(diǎn)擊查看:package.json魄揉;config/index.js洛退;webpack.base.conf.js;webpack.dev.conf.js媒区;webpack.prod.conf.js
二谅畅、主體結(jié)構(gòu)
1.?├─build
2.?├─config
3.?├─dist
4.?├─node_modules
5.?├─src
6.?│ ├─assets
7.?│ ├─components
8.?│ ├─router
9.?│ ├─App.vue
10.?│ ├─main.js
11.?├─static
12.?├─.babelrc
13.?├─.editorconfig
14.?├─.gitignore
15.?├─.postcssrc.js
16.?├─index.html
17.?├─package-lock.json
18.?├─package.json
19.?└─README.md
1粘优、?package.json
項(xiàng)目作為一個(gè)大家庭,每個(gè)文件都各司其職嬉愧。package.json來制定名單没酣,需要哪些npm包來參與到項(xiàng)目中來,npm install命令根據(jù)這個(gè)配置文件增減來管理本地的安裝包偿衰。
1.?{
2.?//從name到private都是package的配置信息,也就是我們?cè)谀_手架搭建中輸入的項(xiàng)目描述
3.??"name":?"shop",//項(xiàng)目名稱:不能以.(點(diǎn))或者_(dá)(下劃線)開頭视事,不能包含大寫字母,具有明確的的含義與現(xiàn)有項(xiàng)目名字不重復(fù)
4.??"version":?"1.0.0",//項(xiàng)目版本號(hào):遵循“大版本.次要版本.小版本”
5.??"description":?"AVue.js project",//項(xiàng)目描述
6.??"author":?"qietuniu",//作者名字
7.??"private":?true,//是否私有
8.??//scripts中的子項(xiàng)即是我們?cè)诳刂婆_(tái)運(yùn)行的腳本的縮寫
9.??"scripts": {
10.???//①webpack-dev-server:啟動(dòng)了http服務(wù)器犬性,實(shí)現(xiàn)實(shí)時(shí)編譯;
11.???//inline模式會(huì)在webpack.config.js入口配置中新增webpack-dev-server/client?http://localhost:8080/的入口,使得我們?cè)L問路徑為localhost:8080/index.html(相應(yīng)的還有另外一種模式Iframe);
12.???//progress:顯示打包的進(jìn)度
13.??"dev":?"webpack-dev-server --inline --progress --configbuild/webpack.dev.conf.js", ?
14.??"start":?"npmrun dev",//與npm rundev相同,直接運(yùn)行開發(fā)環(huán)境
15.??"build":?"nodebuild/build.js"http://使用node運(yùn)行build文件
16.??},
17.??//②dependencies(項(xiàng)目依賴庫(kù)):在安裝時(shí)使用--save則寫入到dependencies
18.??"dependencies": {
19.??"vue":?"^2.5.2",//vue.js
20.??"vue-router":?"^3.0.1"http://vue的路由插件
21.??},
22.??//和devDependencies(開發(fā)依賴庫(kù)):在安裝時(shí)使用--save-dev將寫入到devDependencies
23.??"devDependencies": {
24.??"autoprefixer":?"^7.1.2",//autoprefixer作為postcss插件用來解析CSS補(bǔ)充前綴肉迫,例如 display: flex會(huì)補(bǔ)充為display:-webkit-box;display:-webkit-flex;display: -ms-flexbox;display: flex喊衫。
25.??//babel:以下幾個(gè)babel開頭的都是針對(duì)es6解析的插件。用最新標(biāo)準(zhǔn)編寫的 JavaScript 代碼向下編譯成可以在今天隨處可用的版本
26.??"babel-core":?"^6.22.1",//babel的核心寝杖,把 js?代碼分析成ast ,方便各個(gè)插件分析語(yǔ)法進(jìn)行相應(yīng)的處理只盹。
27.??"babel-helper-vue-jsx-merge-props":?"^2.0.3",//預(yù)制babel-template函數(shù),提供給vue,jsx等使用
28.??"babel-loader":?"^7.1.1",//使項(xiàng)目運(yùn)行使用Babel和webpack來傳輸js文件懦鼠,使用babel-core提供的api進(jìn)行轉(zhuǎn)譯
29.??"babel-plugin-syntax-jsx":?"^6.18.0",//支持jsx
30.??"babel-plugin-transform-runtime":?"^6.22.0",//避免編譯輸出中的重復(fù)肛冶,直接編譯到build環(huán)境中
31.??"babel-plugin-transform-vue-jsx":?"^3.5.0",//babel轉(zhuǎn)譯過程中使用到的插件睦袖,避免重復(fù)
32.??"babel-preset-env":?"^1.3.2",//轉(zhuǎn)為es5,transform階段使用到的插件之一
33.??"babel-preset-stage-2":?"^6.22.0",//ECMAScript第二階段的規(guī)范
34.??"chalk":?"^2.0.1",//用來在命令行輸出不同顏色文字
35.??"copy-webpack-plugin":?"^4.0.1",//拷貝資源和文件
36.??"css-loader":?"^0.28.0",//webpack先用css-loader加載器去解析后綴為css的文件董习,再使用style-loader生成一個(gè)內(nèi)容為最終解析完的css代碼的style標(biāo)簽皿淋,放到head標(biāo)簽里
37.??"extract-text-webpack-plugin":?"^3.0.0",//將一個(gè)以上的包里面的文本提取到單獨(dú)文件中
38.??"file-loader":?"^1.1.4",//③打包壓縮文件,與url-loader用法類似
39.??"friendly-errors-webpack-plugin":?"^1.6.1",//識(shí)別某些類別的WebPACK錯(cuò)誤和清理妇拯,聚合和優(yōu)先排序,以提供更好的開發(fā)經(jīng)驗(yàn)
40.??"html-webpack-plugin":?"^2.30.1",//簡(jiǎn)化了HTML文件的創(chuàng)建,引入了外部資源吏祸,創(chuàng)建html的入口文件,可通過此項(xiàng)進(jìn)行多頁(yè)面的配置
41.??"node-notifier":?"^5.1.2",//支持使用node發(fā)送跨平臺(tái)的本地通知
42.??"optimize-css-assets-webpack-plugin":?"^3.2.0",//壓縮提取出的css鸣驱,并解決ExtractTextPlugin分離出的js重復(fù)問題(多個(gè)文件引入同一css文件)
43.??"ora":?"^1.2.0",//加載(loading)的插件
44.??"portfinder":?"^1.0.13",//查看進(jìn)程端口
45.??"postcss-import":?"^11.0.0",//可以消耗本地文件踊东、節(jié)點(diǎn)模塊或web_modules
46.??"postcss-loader":?"^2.0.8",//用來兼容css的插件
47.??"postcss-url":?"^7.2.1",//URL上重新定位、內(nèi)聯(lián)或復(fù)制
48.??"rimraf":?"^2.6.0",//節(jié)點(diǎn)的UNIX命令RM—RF,強(qiáng)制刪除文件或者目錄的命令
49.??"semver":?"^5.3.0",//用來對(duì)特定的版本號(hào)做判斷的
50.??"shelljs":?"^0.7.6",//使用它來消除shell腳本在UNIX上的依賴性,同時(shí)仍然保留其熟悉和強(qiáng)大的命令记某,即可執(zhí)行Unix系統(tǒng)命令
51.??"uglifyjs-webpack-plugin":?"^1.1.1",//壓縮js文件
52.??"url-loader":?"^0.5.8",//壓縮文件,可將圖片轉(zhuǎn)化為base64
53.??"vue-loader":?"^13.3.0",//VUE單文件組件的WebPACK加載器
54.??"vue-style-loader":?"^3.0.1",//類似于樣式加載程序贺拣,您可以在CSS加載器之后將其鏈接闪幽,以將CSS動(dòng)態(tài)地注入到文檔中作為樣式標(biāo)簽
55.??"vue-template-compiler":?"^2.5.2",//這個(gè)包可以用來預(yù)編譯VUE模板到渲染函數(shù),以避免運(yùn)行時(shí)編譯開銷和CSP限制
56.??"webpack":?"^3.6.0",//打包工具
57.??"webpack-bundle-analyzer":?"^2.9.0",//可視化webpack輸出文件的大小
58.??"webpack-dev-server":?"^2.9.1",//提供一個(gè)提供實(shí)時(shí)重載的開發(fā)服務(wù)器
59.??"webpack-merge":?"^4.1.0"http://它將數(shù)組和合并對(duì)象創(chuàng)建一個(gè)新對(duì)象腕够。如果遇到函數(shù)扑媚,它將執(zhí)行它們,通過算法運(yùn)行結(jié)果贯卦,然后再次將返回的值封裝在函數(shù)中
60.??},
61.??//engines是引擎贿堰,指定node和npm版本
62.??"engines": {
63.??"node":?">= 6.0.0",
64.??"npm":?">= 3.0.0"
65.??},
66.??//限制了瀏覽器或者客戶端需要什么版本才可運(yùn)行
67.??"browserslist": [
68.??"> 1%",
69.??"last 2 versions",
70.??"not ie <= 8"
71.??]
72.?}
注釋:
§?①、點(diǎn)這里→webpack運(yùn)行時(shí)的配置文檔傳送門
§?②注簿、devDependencies和dependencies的區(qū)別: devDependencies里面的插件只用于開發(fā)環(huán)境,不用于生產(chǎn)環(huán)境,即輔助作用眼耀,打包的時(shí)候需要干花,打包完成就不需要了。而dependencies是需要發(fā)布到生產(chǎn)環(huán)境的肿仑,自始至終都在。比如wepack等只是在開發(fā)中使用的包就寫入到devDependencies伟端,而像vue這種項(xiàng)目全程依賴的包要寫入到devDependencies。
§?點(diǎn)這里→更多安裝包文檔搜索頁(yè)傳送門
§?③昧港、file-loader和url-loader的區(qū)別:以圖片為例创肥,file-loader可對(duì)圖片進(jìn)行壓縮巩搏,但是還是通過文件路徑進(jìn)行引入撒强,當(dāng)http請(qǐng)求增多時(shí)會(huì)降低頁(yè)面性能胚想,而url-loader通過設(shè)定limit參數(shù),小于limit字節(jié)的圖片會(huì)被轉(zhuǎn)成base64的文件牙躺,大于limit字節(jié)的將進(jìn)行圖片壓縮的操作愁憔。總而言之述呐,url-loader是file-loader的上層封裝惩淳。
§?點(diǎn)這里→file-loader和 url-loader詳解
§?點(diǎn)這里→file-loader文檔傳送門
§?點(diǎn)這里→url-loader文檔傳送門
2、.postcssrc.js
.postcssrc.js文件其實(shí)是postcss-loader包的一個(gè)配置乓搬,在webpack的舊版本可以直接在webpack.config.js中配置思犁,現(xiàn)版本中postcss的文檔示例獨(dú)立出.postcssrc.js,里面寫進(jìn)去需要使用到的插件抬吟。
1.?module.exports ={
2.??"plugins": {
3.??"postcss-import": {},//①
4.??"postcss-url": {},//②
5.??"autoprefixer": {}//③
6.??}
7.?}
注釋:
§?①茫陆、點(diǎn)這里→postcss-import文檔傳送門
§?②讨盒、點(diǎn)這里→postcss-url文檔傳送門
§?③振乏、點(diǎn)這里→autoprefixer文檔傳送門
3忆谓、?.babelrc
該文件是es6解析的一個(gè)配置。
1.?{
2.?//制定轉(zhuǎn)碼的規(guī)則
3.??"presets": [
4.??//env是使用babel-preset-env插件將js進(jìn)行轉(zhuǎn)碼成es5身辨,并且設(shè)置不轉(zhuǎn)碼的AMD,COMMONJS的模塊文件蔬浙,制定瀏覽器的兼容
5.??["env", {
6.??"modules":?false,
7.??"targets": {
8.??"browsers": [">1%",?"last 2 versions",?"notie <= 8"]
9.??}
10.??}],
11.??"stage-2"
12.??],
13.??
14.??"plugins": ["transform-vue-jsx",?"transform-runtime"]//①
15.?}
注釋:
§?點(diǎn)這里→transform-vue-jsx文檔傳送門
§?點(diǎn)這里→transform-runtime文檔傳送門
4、src內(nèi)文件
我們開發(fā)的代碼都存放在src目錄下维费,根據(jù)需要我們通常會(huì)再建一些文件夾恶阴。比如pages的文件夾摔笤,用來存放頁(yè)面讓components文件夾專門做好組件的工作尔艇;api文件夾昧辽,來封裝請(qǐng)求的參數(shù)和方法;store文件夾,使用vuex來作為vue的狀態(tài)管理工具,我也常叫它作前端的數(shù)據(jù)庫(kù)等。
①、assets文件:腳手架自動(dòng)回放入一個(gè)圖片在里面作為初始頁(yè)面的logo茂契。平常我們使用的時(shí)候會(huì)在里面建立js癣蟋,css瘦麸,img呵曹,fonts等文件夾富腊,作為靜態(tài)資源調(diào)用
②、components文件夾:用來存放組件,合理地使用組件可以高效地實(shí)現(xiàn)復(fù)用等功能劲蜻,從而更好地開發(fā)項(xiàng)目哀九。一般情況下比如創(chuàng)建頭部組件的時(shí)候蝇更,我們會(huì)新建一個(gè)header的文件夾,然后再新建一個(gè)header.vue的文件夾
③呼盆、router文件夾:該文件夾下有一個(gè)叫index.js文件年扩,用于實(shí)現(xiàn)頁(yè)面的路由跳轉(zhuǎn),具體使用請(qǐng)點(diǎn)擊→vue-router傳送門
④访圃、App.vue:作為我們的主組件厨幻,可通過使用開放入口讓其他的頁(yè)面組件得以顯示。
⑤腿时、main.js:作為我們的入口文件况脆,主要作用是初始化vue實(shí)例并使用需要的插件,小型項(xiàng)目省略router時(shí)可放在該處
注釋:具體vue的用法可查看vue官方中文文檔傳送門
5批糟、其他文件
①格了、.editorconfig:編輯器的配置文件
②、.gitignore:忽略git提交的一個(gè)文件徽鼎,配置之后提交時(shí)將不會(huì)加載忽略的文件
③盛末、index.html:頁(yè)面入口,經(jīng)過編譯之后的代碼將插入到這來纬傲。
④满败、package.lock.json:鎖定安裝時(shí)的包的版本號(hào),并且需要上傳到git叹括,以保證其他人在npm install時(shí)大家的依賴能保證一致
⑤算墨、README.md:可此填寫項(xiàng)目介紹
⑥、node_modules:根據(jù)package.json安裝時(shí)候生成的的依賴(安裝包)
三汁雷、config文件夾
1.?├─config
2.?│ ├─dev.env.js
3.?│ ├─index.js
4.?│ ├─prod.env.js
1净嘀、config/dev.env.js
config內(nèi)的文件其實(shí)是服務(wù)于build的,大部分是定義一個(gè)變量export出去侠讯。
1.?'use strict'//采用嚴(yán)格模式
2.?const?merge =?require('webpack-merge')//①
3.?const?prodEnv =require('./prod.env')
4.?//webpack-merge提供了一個(gè)合并函數(shù)挖藏,它將數(shù)組和合并對(duì)象創(chuàng)建一個(gè)新對(duì)象。
5.?//如果遇到函數(shù)厢漩,它將執(zhí)行它們膜眠,通過算法運(yùn)行結(jié)果,然后再次將返回的值封裝在函數(shù)中.這邊將dev和prod進(jìn)行合并
6.?module.exports =merge(prodEnv, {
7.??NODE_ENV:?'"development"'
8.?})
注釋:點(diǎn)這里→webpack-merge文檔傳送門
2、config/prod.env.js
當(dāng)開發(fā)是調(diào)取dev.env.js的開發(fā)環(huán)境配置宵膨,發(fā)布時(shí)調(diào)用prod.env.js的生產(chǎn)環(huán)境配置架谎。
1.?'use strict'
2.?module.exports ={
3.??NODE_ENV:?'"production"'
4.?}
3、config/index.js
1.?'use strict'
2.?const?path =?require('path')
3.??
4.?module.exports ={
5.??dev: {
6.??//?開發(fā)環(huán)境下面的配置
7.??assetsSubDirectory:?'static',//子目錄辟躏,一般存放css,js,image等文件
8.??assetsPublicPath:?'/',//根目錄
9.??proxyTable: {},//可利用該屬性解決跨域的問題
10.??host:'localhost',?//?地址
11.??port:8080,?//端口號(hào)設(shè)置谷扣,端口號(hào)占用出現(xiàn)問題可在此處修改
12.??autoOpenBrowser:?false,//是否在編譯(輸入命令行npm run dev)后打開http://localhost:8080/頁(yè)面,以前配置為true捎琐,近些版本改為false会涎,個(gè)人偏向習(xí)慣自動(dòng)打開頁(yè)面
13.??errorOverlay:?true,//瀏覽器錯(cuò)誤提示
14.??notifyOnErrors:?true,//跨平臺(tái)錯(cuò)誤提示
15.??poll:false,?//使用文件系統(tǒng)(file system)獲取文件改動(dòng)的通知devServer.watchOptions
16.??devtool:?'cheap-module-eval-source-map',//增加調(diào)試,該屬性為原始源代碼(僅限行)不可在生產(chǎn)環(huán)境中使用
17.??cacheBusting:?true,//使緩存失效
18.??cssSourceMap:?true//代碼壓縮后進(jìn)行調(diào)bug定位將非常困難瑞凑,于是引入sourcemap記錄壓縮前后的位置信息記錄末秃,當(dāng)產(chǎn)生錯(cuò)誤時(shí)直接定位到未壓縮前的位置,將大大的方便我們調(diào)試
19.??},
20.??
21.??build: {
22.??//?生產(chǎn)環(huán)境下面的配置
23.??index: path.resolve(__dirname,?'../dist/index.html'),//index編譯后生成的位置和名字拨黔,根據(jù)需要改變后綴蛔溃,比如index.php
24.??assetsRoot: path.resolve(__dirname,?'../dist'),//編譯后存放生成環(huán)境代碼的位置
25.??assetsSubDirectory:?'static',//js,css,images存放文件夾名
26.??assetsPublicPath:?'/',//發(fā)布的根目錄,通常本地打包dist后打開文件會(huì)報(bào)錯(cuò)篱蝇,此處修改為./贺待。如果是上線的文件,可根據(jù)文件存放位置進(jìn)行更改路徑
27.??productionSourceMap:?true,
28.??devtool:?'#source-map',//①
29.??//unit的gzip命令用來壓縮文件零截,gzip模式下需要壓縮的文件的擴(kuò)展名有js和css
30.??productionGzip:?false,
31.??productionGzipExtensions: ['js',?'css'],
32.??bundleAnalyzerReport: process.env.npm_config_report
33.??}
34.?}
注釋:點(diǎn)擊→devtool文檔傳送門
四麸塞、build文件夾
1.?├─build
2.?│ ├─build.js
3.?│ ├─check-versions.js
4.?│ ├─utils.js
5.?│ ├─vue-loader.conf.js
6.?│ ├─webpack.base.conf.js
7.?│ ├─webpack.dev.conf.js
8.?│ ├─webpack.prod.conf.js
1、build/build.js
該文件作用涧衙,即構(gòu)建生產(chǎn)版本哪工。package.json中的scripts的build就是node build/build.js,輸入命令行npm run build對(duì)該文件進(jìn)行編譯生成生產(chǎn)環(huán)境的代碼弧哎。
1.?'use strict'
2.?require('./check-versions')()//check-versions:調(diào)用檢查版本的文件雁比。加()代表直接調(diào)用該函數(shù)
3.?process.env.NODE_ENV =?'production'//設(shè)置當(dāng)前是生產(chǎn)環(huán)境
4.?//下面定義常量引入插件
5.?const?ora =?require('ora')//①加載動(dòng)畫
6.?const?rm =?require('rimraf')//②刪除文件
7.?const?path =?require('path')
8.?const?chalk =?require('chalk')//③對(duì)文案輸出的一個(gè)彩色設(shè)置
9.?const?webpack =require('webpack')
10.?const?config =?require('../config')//默認(rèn)讀取下面的index.js文件
11.?constwebpackConfig =?require('./webpack.prod.conf')
12.?//調(diào)用start的方法實(shí)現(xiàn)加載動(dòng)畫,優(yōu)化用戶體驗(yàn)
13.?const?spinner =ora('building for production...')
14.?spinner.start()
15.?//先刪除dist文件再生成新文件撤嫩,因?yàn)橛袝r(shí)候會(huì)使用hash來命名偎捎,刪除整個(gè)文件可避免冗余
16.?rm(path.join(config.build.assetsRoot,config.build.assetsSubDirectory), err => {
17.??if?(err)?throw?err
18.??webpack(webpackConfig, (err, stats)=> {
19.??spinner.stop()
20.??if?(err)?throw?err
21.??process.stdout.write(stats.toString({
22.??colors:?true,
23.??modules:?false,
24.??children:?false,?// If youare using ts-loader, setting this to true will make TypeScript errors show upduring build.
25.??chunks:?false,
26.??chunkModules:?false
27.??}) +?'\n\n')
28.??
29.??if(stats.hasErrors()) {
30.??process.exit(1)
31.??}
32.??
33.??console.log(chalk.cyan('?Build complete.\n'))
34.??console.log(chalk.yellow(
35.??' ?Tip: built files are meant to beserved over an HTTP server.\n'?+
36.??' ?Opening index.html over file://won\'t work.\n'
37.??))
38.??})
39.?})
注釋:
§?①、點(diǎn)這里→ora文檔傳送門
§?②序攘、點(diǎn)這里→chalk文檔傳送門
§?③茴她、點(diǎn)這里→rimraf文檔傳送門
2、build/check-version.js
該文件用于檢測(cè)node和npm的版本程奠,實(shí)現(xiàn)版本依賴
1.?'use strict'
2.?const?chalk =?require('chalk')
3.?const?semver =?require('semver')//①對(duì)版本進(jìn)行檢查
4.?constpackageConfig =?require('../package.json')
5.?const?shell =?require('shelljs')
6.??
7.?functionexec?(cmd) {
8.?//返回通過child_process模塊的新建子進(jìn)程丈牢,執(zhí)行 Unix 系統(tǒng)命令后轉(zhuǎn)成沒有空格的字符串
9.??returnrequire('child_process').execSync(cmd).toString().trim()
10.?}
11.??
12.?constversionRequirements = [
13.??{
14.??name:'node',
15.??currentVersion: semver.clean(process.version),//使用semver格式化版本
16.??versionRequirement: packageConfig.engines.node//獲取package.json中設(shè)置的node版本
17.??}
18.?]
19.??
20.?if(shell.which('npm')) {
21.??versionRequirements.push({
22.??name:'npm',
23.??currentVersion:?exec('npm--version'),//?自動(dòng)調(diào)用npm--version命令,并且把參數(shù)返回給exec函數(shù)瞄沙,從而獲取純凈的版本號(hào)
24.??versionRequirement: packageConfig.engines.npm
25.??})
26.?}
27.??
28.?module.exports =function?() {
29.??const?warnings= []
30.??for?(let?i =?0; i < versionRequirements.length;i++) {
31.??const?mod =versionRequirements[i]
32.??
33.??if(!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
34.??//上面這個(gè)判斷就是如果版本號(hào)不符合package.json文件中指定的版本號(hào)己沛,就執(zhí)行下面錯(cuò)誤提示的代碼
35.??warnings.push(mod.name +?': '?+
36.??chalk.red(mod.currentVersion) +?' should be '?+
37.??chalk.green(mod.versionRequirement)
38.??)
39.??}
40.??}
41.??
42.??if(warnings.length) {
43.??console.log('')
44.??console.log(chalk.yellow('To usethis template, you must update following to modules:'))
45.??console.log()
46.??
47.??for?(let?i =?0; i <warnings.length; i++) {
48.??const?warning = warnings[i]
49.??console.log(' ?'?+ warning)
50.??}
51.??
52.??console.log()
53.??process.exit(1)
54.??}
55.?}
注釋:
§?點(diǎn)這里→chalk文檔傳送門
§?點(diǎn)這里→semver文檔傳送門
3慌核、build/utils.js
utils是工具的意思,是一個(gè)用來處理css的文件申尼。
1.?'use strict'
2.?const?path =?require('path')
3.?const?config =?require('../config')
4.?constExtractTextPlugin?=?require('extract-text-webpack-plugin')
5.?constpackageConfig =?require('../package.json')
6.?//導(dǎo)出文件的位置遂铡,根據(jù)環(huán)境判斷開發(fā)環(huán)境和生產(chǎn)環(huán)境,為config文件中index.js文件中定義的build.assetsSubDirectory或dev.assetsSubDirectory
7.?exports.assetsPath =?function?(_path) {
8.??constassetsSubDirectory = process.env.NODE_ENV ===?'production'
9.???config.build.assetsSubDirectory
10.??:config.dev.assetsSubDirectory
11.?//Node.js path?模塊提供了一些用于處理文件路徑的小工具①
12.??returnpath.posix.join(assetsSubDirectory, _path)
13.?}
14.??
15.?exports.cssLoaders =?function?(options){
16.??options =options || {}
17.?//使用了css-loader和postcssLoader晶姊,通過options.usePostCSS屬性來判斷是否使用postcssLoader中壓縮等方法
18.??const?cssLoader= {
19.??loader:?'css-loader',
20.??options: {
21.??sourceMap: options.sourceMap
22.??}
23.??}
24.??
25.??constpostcssLoader = {
26.??loader:?'postcss-loader',
27.??options: {
28.??sourceMap: options.sourceMap
29.??}
30.??}
31.??functiongenerateLoaders (loader, loaderOptions) {
32.??const?loaders =options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
33.??if?(loader){
34.??loaders.push({
35.??loader: loader +?'-loader',
36.??//Object.assign是es6語(yǔ)法的淺復(fù)制,后兩者合并后復(fù)制完成賦值
37.??options:?Object.assign({}, loaderOptions, {
38.??sourceMap: options.sourceMap
39.??})
40.??})
41.??}
42.??
43.??if(options.extract) {
44.??//ExtractTextPlugin可提取出文本伪货,代表首先使用上面處理的loaders们衙,當(dāng)未能正確引入時(shí)使用vue-style-loader
45.??returnExtractTextPlugin.extract({
46.??use: loaders,
47.??fallback:?'vue-style-loader'
48.??})
49.??}?else?{
50.??//返回vue-style-loader連接loaders的最終值
51.??return?['vue-style-loader'].concat(loaders)
52.??}
53.??}
54.??return?{
55.??css:generateLoaders(),//需要css-loader?和vue-style-loader
56.??postcss: generateLoaders(),//需要css-loader和postcssLoader?和 vue-style-loader
57.??less:generateLoaders('less'),//需要less-loader?和vue-style-loader
58.??sass:generateLoaders('sass', { indentedSyntax:?true?}),//需要sass-loader和 vue-style-loader
59.??scss:generateLoaders('sass'),//需要sass-loader?和vue-style-loader
60.??stylus: generateLoaders('stylus'),//需要stylus-loader?和 vue-style-loader
61.??styl:generateLoaders('stylus')//需要stylus-loader?和 vue-style-loader
62.??}
63.?}
64.?exports.styleLoaders =?function?(options){
65.??const?output =[]
66.??const?loaders =exports.cssLoaders(options)
67.??//將各種css,less,sass等綜合在一起得出結(jié)果輸出output
68.??for?(const?extensionin?loaders){
69.??const?loader =loaders[extension]
70.??output.push({
71.??test:?newRegExp('\\.'?+ extension +?'$'),
72.??use: loader
73.??})
74.??}
75.??
76.??return?output
77.?}
78.??
79.?exports.createNotifierCallback = () => {
80.?//發(fā)送跨平臺(tái)通知系統(tǒng)
81.??const?notifier=?require('node-notifier')
82.??
83.??return(severity, errors) => {
84.??if?(severity!==?'error')?return
85.?//當(dāng)報(bào)錯(cuò)時(shí)輸出錯(cuò)誤信息的標(biāo)題,錯(cuò)誤信息詳情碱呼,副標(biāo)題以及圖標(biāo)
86.??const?error =errors[0]
87.??const?filename= error.file && error.file.split('!').pop()
88.??
89.??notifier.notify({
90.??title: packageConfig.name,
91.??message: severity +?': '?+ error.name,
92.??subtitle: filename ||?'',
93.??icon: path.join(__dirname,?'logo.png')
94.??})
95.??}
96.?}
注釋:
§?path.posix:提供對(duì)路徑方法的POSIX(可移植性操作系統(tǒng)接口)特定實(shí)現(xiàn)的訪問蒙挑,即可跨平臺(tái),區(qū)別于win32愚臀。
§?path.join:用于連接路徑忆蚀,會(huì)正確使用當(dāng)前系統(tǒng)的路徑分隔符,Unix系統(tǒng)是"/"姑裂,Windows系統(tǒng)是"\"
§?點(diǎn)擊→path用法傳送門
4馋袜、vue-loader.conf.js
該文件的主要作用就是處理.vue文件,解析這個(gè)文件中的每個(gè)語(yǔ)言塊(template舶斧、script欣鳖、style),轉(zhuǎn)換成js可用的js模塊。
1.?'use strict'
2.?const?utils =?require('./utils')
3.?const?config =?require('../config')
4.?constisProduction = process.env.NODE_ENV ===?'production'
5.?constsourceMapEnabled = isProduction
6.???config.build.productionSourceMap
7.??:config.dev.cssSourceMap
8.?//處理項(xiàng)目中的css文件茴厉,生產(chǎn)環(huán)境和測(cè)試環(huán)境默認(rèn)是打開sourceMap泽台,而extract中的提取樣式到單獨(dú)文件只有在生產(chǎn)環(huán)境中才需要
9.?module.exports ={
10.??loaders:utils.cssLoaders({
11.??sourceMap: sourceMapEnabled,
12.??extract: isProduction
13.??}),
14.??cssSourceMap: sourceMapEnabled,
15.??cacheBusting: config.dev.cacheBusting,
16.???//?在模版編譯過程中,編譯器可以將某些屬性矾缓,如 src?路徑怀酷,轉(zhuǎn)換為require調(diào)用,以便目標(biāo)資源可以由 webpack 處理.
17.??transformToRequire: {
18.??video: ['src',?'poster'],
19.??source:?'src',
20.??img:?'src',
21.??image:?'xlink:href'
22.??}
23.?}
5嗜闻、webpack.base.conf.js
webpack.base.conf.js是開發(fā)和生產(chǎn)共同使用提出來的基礎(chǔ)配置文件蜕依,主要實(shí)現(xiàn)配制入口,配置輸出環(huán)境泞辐,配置模塊resolve和插件等笔横。
1.?'use strict'
2.?const?path =?require('path')
3.?const?utils =?require('./utils')
4.?const?config =?require('../config')
5.?constvueLoaderConfig =?require('./vue-loader.conf')
6.??
7.?function?resolve(dir) {
8.?//拼接出絕對(duì)路徑
9.??returnpath.join(__dirname,?'..', dir)
10.?}
11.?module.exports ={
12.?//path.join將路徑片段進(jìn)行拼接,而path.resolve將以/開始的路徑片段作為根目錄咐吼,在此之前的路徑將會(huì)被丟棄
13.?//path.join('/a', '/b') // 'a/b',path.resolve('/a', '/b')// '/b'
14.??context:path.resolve(__dirname,?'../'),
15.??//配置入口吹缔,默認(rèn)為單頁(yè)面所以只有app一個(gè)入口
16.??entry: {
17.??app:?'./src/main.js'
18.??},
19.??//配置出口,默認(rèn)是/dist作為目標(biāo)文件夾的路徑
20.??output: {
21.??path:config.build.assetsRoot,//路徑
22.??filename:?'[name].js',//文件名
23.??publicPath: process.env.NODE_ENV ===?'production'
24.??? config.build.assetsPublicPath
25.??: config.dev.assetsPublicPath//公共存放路徑
26.??},
27.??resolve: {
28.??//自動(dòng)的擴(kuò)展后綴锯茄,比如一個(gè)js文件厢塘,則引用時(shí)書寫可不要寫.js
29.??extensions: ['.js',?'.vue',?'.json'],
30.??//創(chuàng)建路徑的別名茶没,比如增加'components': resolve('src/components')等
31.??alias: {
32.??'vue$':?'vue/dist/vue.esm.js',
33.??'@': resolve('src'),
34.??}
35.??},
36.??//使用插件配置相應(yīng)文件的處理方法
37.??module: {
38.??rules: [
39.??//使用vue-loader將vue文件轉(zhuǎn)化成js的模塊①
40.??{
41.??test:?/\.vue$/,
42.??loader:?'vue-loader',
43.??options: vueLoaderConfig
44.??},
45.??//js文件需要通過babel-loader進(jìn)行編譯成es5文件以及壓縮等操作②
46.??{
47.??test:?/\.js$/,
48.??loader:?'babel-loader',
49.??include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
50.??},
51.??//圖片、音像晚碾、字體都使用url-loader進(jìn)行處理抓半,超過10000會(huì)編譯成base64③
52.??{
53.??test:?/\.(png|jpe?g|gif|svg)(\?.*)?$/,
54.??loader:?'url-loader',
55.??options: {
56.??limit:?10000,
57.??name: utils.assetsPath('img/[name].[hash:7].[ext]')
58.??}
59.??},
60.??{
61.??test:?/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
62.??loader:?'url-loader',
63.??options: {
64.??limit:?10000,
65.??name: utils.assetsPath('media/[name].[hash:7].[ext]')
66.??}
67.??},
68.??{
69.??test:?/\.(woff2?|eot|ttf|otf)(\?.*)?$/,
70.??loader:?'url-loader',
71.??options: {
72.??limit:?10000,
73.??name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
74.??}
75.??}
76.??]
77.??},
78.??//以下選項(xiàng)是Node.js全局變量或模塊,這里主要是防止webpack注入一些Node.js的東西到vue中
79.??node:
80.??setImmediate:?false,
81.??dgram:?'empty',
82.??fs:?'empty',
83.??net:?'empty',
84.??tls:?'empty',
85.??child_process:?'empty'
86.??}
87.?}
注釋:
§?①格嘁、點(diǎn)擊→vue-loader文檔傳送門
§?②笛求、點(diǎn)擊→babel-loader文檔傳送門
6、webpack.dev.conf.js
1.?'use strict'
2.?const?utils =?require('./utils')
3.?const?webpack =require('webpack')
4.?const?config =?require('../config')
5.?//通過webpack-merge實(shí)現(xiàn)webpack.dev.conf.js對(duì)wepack.base.config.js的繼承
6.?const?merge =?require('webpack-merge')
7.?const?path =?require('path')
8.?constbaseWebpackConfig =?require('./webpack.base.conf')
9.?constCopyWebpackPlugin?=?require('copy-webpack-plugin')
10.?constHtmlWebpackPlugin?=?require('html-webpack-plugin')
11.?//美化webpack的錯(cuò)誤信息和日志的插件①
12.?constFriendlyErrorsPlugin?=?require('friendly-errors-webpack-plugin')
13.?constportfinder =?require('portfinder')//?查看空閑端口位置糕簿,默認(rèn)情況下搜索8000這個(gè)端口②
14.?const?HOST =process.env.HOST//③processs為node的一個(gè)全局對(duì)象獲取當(dāng)前程序的環(huán)境變量探入,即host
15.?const?PORT =process.env.PORT &&?Number(process.env.PORT)
16.??
17.?constdevWebpackConfig = merge(baseWebpackConfig, {
18.??module: {
19.??//規(guī)則是工具utils中處理出來的styleLoaders,生成了css懂诗,less,postcss等規(guī)則
20.??rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap,usePostCSS:?true?})
21.??},
22.??
23.??devtool:config.dev.devtool,//增強(qiáng)調(diào)試蜂嗽,上文有提及
24.??//此處的配置都是在config的index.js中設(shè)定好了
25.??devServer: {//④
26.??clientLogLevel:?'warning',//控制臺(tái)顯示的選項(xiàng)有none, error, warning?或者 info
27.??//當(dāng)使用HTML5 History API?時(shí),任意的 404 響應(yīng)都可能需要被替代為 index.html
28.??historyApiFallback: {
29.??rewrites: [
30.??{?from:?/.*/, to: path.posix.join(config.dev.assetsPublicPath,?'index.html') },
31.??],
32.??},
33.??hot:?true,//熱加載
34.??contentBase:?false,
35.??compress:?true,//壓縮
36.??host:HOST || config.dev.host,
37.??port:PORT || config.dev.port,
38.??open:config.dev.autoOpenBrowser,//調(diào)試時(shí)自動(dòng)打開瀏覽器
39.??overlay: config.dev.errorOverlay
40.??? { warnings:?false, errors:?true?}
41.??:?false,// warning和 error?都要顯示
42.??publicPath: config.dev.assetsPublicPath,
43.??proxy: config.dev.proxyTable,//接口代理
44.??quiet:?true,?//控制臺(tái)是否禁止打印警告和錯(cuò)誤,若用FriendlyErrorsPlugin 此處為 true
45.??watchOptions: {
46.??poll: config.dev.poll,////?文件系統(tǒng)檢測(cè)改動(dòng)
47.??}
48.??},
49.??plugins: [
50.??new?webpack.DefinePlugin({
51.??'process.env':?require('../config/dev.env')
52.??}),
53.??new?webpack.HotModuleReplacementPlugin(),//⑤模塊熱替換插件殃恒,修改模塊時(shí)不需要刷新頁(yè)面
54.??new?webpack.NamedModulesPlugin(),?//?顯示文件的正確名字
55.??new?webpack.NoEmitOnErrorsPlugin(),//當(dāng)webpack編譯錯(cuò)誤的時(shí)候植旧,來中端打包進(jìn)程,防止錯(cuò)誤代碼打包到文件中
56.??// https://github.com/ampedandwired/html-webpack-plugin
57.??//?該插件可自動(dòng)生成一個(gè) html5?文件或使用模板文件將編譯好的代碼注入進(jìn)去⑥
58.??newHtmlWebpackPlugin({
59.??filename:?'index.html',
60.??template:?'index.html',
61.??inject:?true
62.??}),
63.??newCopyWebpackPlugin([//復(fù)制插件
64.??{
65.??from: path.resolve(__dirname,?'../static'),
66.??to: config.dev.assetsSubDirectory,
67.??ignore: ['.*']//忽略.*的文件
68.??}
69.??])
70.??]
71.?})
72.??
73.?module.exports =newPromise((resolve,reject) => {
74.??portfinder.basePort = process.env.PORT|| config.dev.port
75.??//查找端口號(hào)
76.??portfinder.getPort((err, port) => {
77.??if?(err) {
78.??reject(err)
79.??}?else?{
80.??//端口被占用時(shí)就重新設(shè)置evn和devServer的端口
81.??process.env.PORT = port
82.??devWebpackConfig.devServer.port = port
83.??//友好地輸出信息
84.??devWebpackConfig.plugins.push(newFriendlyErrorsPlugin({
85.??compilationSuccessInfo: {
86.??messages: [`Yourapplication is running here: http://${devWebpackConfig.devServer.host}:${port}`],
87.??},
88.??onErrors: config.dev.notifyOnErrors
89.??? utils.createNotifierCallback()
90.??:?undefined
91.??}))
92.??resolve(devWebpackConfig)
93.??}
94.??})
95.?})
7离唐、webpack.prod.conf.js
1.?'use strict'
2.?const?path =?require('path')
3.?const?utils =?require('./utils')
4.?const?webpack =require('webpack')
5.?const?config =?require('../config')
6.?const?merge =?require('webpack-merge')
7.?constbaseWebpackConfig =?require('./webpack.base.conf')
8.?constCopyWebpackPlugin?=?require('copy-webpack-plugin')
9.?constHtmlWebpackPlugin?=?require('html-webpack-plugin')
10.?constExtractTextPlugin?=?require('extract-text-webpack-plugin')
11.?constOptimizeCSSPlugin?=?require('optimize-css-assets-webpack-plugin')
12.?constUglifyJsPlugin?=?require('uglifyjs-webpack-plugin')
13.??
14.?const?env =?require('../config/prod.env')
15.??
16.?constwebpackConfig = merge(baseWebpackConfig, {
17.??module: {
18.??//調(diào)用utils.styleLoaders的方法
19.??rules: utils.styleLoaders({
20.??sourceMap: config.build.productionSourceMap,//開啟調(diào)試的模式病附。默認(rèn)為true
21.??extract:?true,
22.??usePostCSS:?true
23.??})
24.??},
25.??devtool:config.build.productionSourceMap ? config.build.devtool :?false,
26.??output: {
27.??path:config.build.assetsRoot,
28.??filename: utils.assetsPath('js/[name].[chunkhash].js'),
29.??chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
30.??},
31.??plugins: [
32.??new?webpack.DefinePlugin({
33.??'process.env': env
34.??}),
35.??newUglifyJsPlugin({
36.??uglifyOptions: {
37.??compress: {//壓縮
38.??warnings:?false//警告:true保留警告,false不保留
39.??}
40.??},
41.??sourceMap: config.build.productionSourceMap,
42.??parallel:?true
43.??}),
44.??newExtractTextPlugin({//抽取文本亥鬓。比如打包之后的index頁(yè)面有style插入胖喳,就是這個(gè)插件抽取出來的,減少請(qǐng)求
45.??filename: utils.assetsPath('css/[name].[contenthash].css'), ?
46.??allChunks:?true,
47.??}),
48.??
49.??newOptimizeCSSPlugin({//優(yōu)化css的插件
50.??cssProcessorOptions: config.build.productionSourceMap
51.??? { safe:?true, map: {?inline:?false?} }
52.??: { safe:?true?}
53.??}),
54.??
55.??newHtmlWebpackPlugin({//html打包
56.??filename: config.build.index,
57.??template:?'index.html',
58.??inject:?true,
59.??minify: {//壓縮
60.??removeComments:?true,//刪除注釋
61.??collapseWhitespace:?true,//刪除空格
62.??removeAttributeQuotes:?true//刪除屬性的引號(hào)?
63.??},
64.??
65.??chunksSortMode:?'dependency'//模塊排序贮竟,按照我們需要的順序排序
66.??}),
67.??
68.??new?webpack.HashedModuleIdsPlugin(),
69.??newwebpack.optimize.ModuleConcatenationPlugin(),
70.??newwebpack.optimize.CommonsChunkPlugin({//抽取公共的模塊
71.??name:?'vendor',
72.??minChunks (module) { ?
73.??return?(
74.??module.resource &&
75.??/\.js$/.test(module.resource) &&
76.??module.resource.indexOf(
77.??path.join(__dirname,?'../node_modules')
78.??) ===?0
79.??)
80.??}
81.??}),
82.??newwebpack.optimize.CommonsChunkPlugin({
83.??name:?'manifest',
84.??minChunks:?Infinity
85.??}),
86.??newwebpack.optimize.CommonsChunkPlugin({
87.??name:?'app',
88.??async:?'vendor-async',
89.??children:?true,
90.??minChunks:?3
91.??}),
92.??newCopyWebpackPlugin([//復(fù)制丽焊,比如打包完之后需要把打包的文件復(fù)制到dist里面
93.??{
94.??from: path.resolve(__dirname,?'../static'),
95.??to: config.build.assetsSubDirectory,
96.??ignore: ['.*']
97.??}
98.??])
99.??]
100.?})
101.??
102.?if(config.build.productionGzip) {
103.??constCompressionWebpackPlugin?=?require('compression-webpack-plugin')
104.??
105.??webpackConfig.plugins.push(
106.??newCompressionWebpackPlugin({
107.??asset:?'[path].gz[query]',
108.??algorithm:?'gzip',
109.??test:?newRegExp(
110.??'\\.('?+
111.??config.build.productionGzipExtensions.join('|') +
112.??')$'
113.??),
114.??threshold:?10240,
115.??minRatio:?0.8
116.??})
117.??)
118.?}
119.??
120.?if(config.build.bundleAnalyzerReport) {
121.??constBundleAnalyzerPlugin?=?require('webpack-bundle-analyzer').BundleAnalyzerPlugin
122.??webpackConfig.plugins.push(newBundleAnalyzerPlugin())
123.?}
124.??
125.?module.exports =webpackConfig