App下載

vue-cli webpack怎么配置?配置流程詳解!

猿友 2021-06-30 11:57:03 瀏覽數(shù) (4322)
反饋

對(duì)很多的小白來(lái)說(shuō)學(xué)習(xí)框架是比較艱難的一個(gè)過(guò)程但是學(xué)會(huì)之后帶來(lái)的收獲卻不知是一點(diǎn)點(diǎn),那么今天我們就來(lái)說(shuō)下有關(guān)于“vue-cli webpack怎么配置?”怎么配置的問(wèn)題吧!


我們知道相對(duì) ?vue ?來(lái)說(shuō)? vue-cli? 是構(gòu)建 ?vue ?的單頁(yè)應(yīng)用的腳手架,我們只需要在命令行輸入 : ?vue init <template-name><project-name>? 從而就會(huì)自動(dòng)生成項(xiàng)目模板,比較常用的模板有 ?webpack? 、?webpack-simple?、?browserify?等模板。就拿 ?webpack ?來(lái)說(shuō)就在編程中發(fā)揮很大的作用,它使得我們的代碼塊模板話,還可以免除搭建項(xiàng)目的時(shí)間,我們來(lái)看下有關(guān)于webpack模板的配置文件,下面是主要目錄的截圖:

包截圖


1、package.json

對(duì)于這個(gè)文件來(lái)說(shuō)是用來(lái)描述 NPM這個(gè)包所有的相關(guān)信息的,對(duì)于格式的話則是嚴(yán)格的json格式,npm install 命令可以根據(jù)配置文件來(lái)增加或者減少管理本地文件的安裝包,代碼如下所示:

{
//從name到private都是package的配置信息,也就是我們?cè)谀_手架搭建中輸入的項(xiàng)目描述
  "name": "shop",//項(xiàng)目名稱:不能以.(點(diǎn))或者_(dá)(下劃線)開(kāi)頭,不能包含大寫字母,具有明確的的含義與現(xiàn)有項(xiàng)目名字不重復(fù)
  "version": "1.0.0",//項(xiàng)目版本號(hào):遵循“大版本.次要版本.小版本”
  "description": "A Vue.js project",//項(xiàng)目描述
  "author": "zld",//作者名字
  "private": true,//是否私有
  //scripts中的子項(xiàng)即是我們?cè)诳刂婆_(tái)運(yùn)行的腳本的縮寫
  "scripts": {
   //①webpack-dev-server:啟動(dòng)了http服務(wù)器,實(shí)現(xiàn)實(shí)時(shí)編譯;
   //inline模式會(huì)在webpack.config.js入口配置中新增webpack-dev-server/client?http://localhost:8080/的入口,使得我們?cè)L問(wèn)路徑為localhost:8080/index.html(相應(yīng)的還有另外一種模式Iframe);
   //progress:顯示打包的進(jìn)度
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",  
    "start": "npm run dev",//與npm run dev相同,直接運(yùn)行開(kāi)發(fā)環(huán)境
    "build": "node build/build.js"http://使用node運(yùn)行build文件
  },
  //②dependencies(項(xiàng)目依賴庫(kù)):在安裝時(shí)使用--save則寫入到dependencies
  "dependencies": {
    "vue": "^2.5.2",//vue.js
    "vue-router": "^3.0.1"http://vue的路由插件
  },
  //和devDependencies(開(kāi)發(fā)依賴庫(kù)):在安裝時(shí)使用--save-dev將寫入到devDependencies
  "devDependencies": {
    "autoprefixer": "^7.1.2",//autoprefixer作為postcss插件用來(lái)解析CSS補(bǔ)充前綴,例如 display: flex會(huì)補(bǔ)充為display:-webkit-box;display: -webkit-flex;display: -ms-flexbox;display: flex。
    //babel:以下幾個(gè)babel開(kāi)頭的都是針對(duì)es6解析的插件。用最新標(biāo)準(zhǔn)編寫的 JavaScript 代碼向下編譯成可以在今天隨處可用的版本
    "babel-core": "^6.22.1",//babel的核心,把 js 代碼分析成 ast ,方便各個(gè)插件分析語(yǔ)法進(jìn)行相應(yīng)的處理。
    "babel-helper-vue-jsx-merge-props": "^2.0.3",//預(yù)制babel-template函數(shù),提供給vue,jsx等使用
    "babel-loader": "^7.1.1",//使項(xiàng)目運(yùn)行使用Babel和webpack來(lái)傳輸js文件,使用babel-core提供的api進(jìn)行轉(zhuǎn)譯
    "babel-plugin-syntax-jsx": "^6.18.0",//支持jsx
    "babel-plugin-transform-runtime": "^6.22.0",//避免編譯輸出中的重復(fù),直接編譯到build環(huán)境中
    "babel-plugin-transform-vue-jsx": "^3.5.0",//babel轉(zhuǎn)譯過(guò)程中使用到的插件,避免重復(fù)
    "babel-preset-env": "^1.3.2",//轉(zhuǎn)為es5,transform階段使用到的插件之一
    "babel-preset-stage-2": "^6.22.0",//ECMAScript第二階段的規(guī)范
    "chalk": "^2.0.1",//用來(lái)在命令行輸出不同顏色文字
    "copy-webpack-plugin": "^4.0.1",//拷貝資源和文件
    "css-loader": "^0.28.0",//webpack先用css-loader加載器去解析后綴為css的文件,再使用style-loader生成一個(gè)內(nèi)容為最終解析完的css代碼的style標(biāo)簽,放到head標(biāo)簽里
    "extract-text-webpack-plugin": "^3.0.0",//將一個(gè)以上的包里面的文本提取到單獨(dú)文件中
    "file-loader": "^1.1.4",//③打包壓縮文件,與url-loader用法類似
    "friendly-errors-webpack-plugin": "^1.6.1",//識(shí)別某些類別的WebPACK錯(cuò)誤和清理,聚合和優(yōu)先排序,以提供更好的開(kāi)發(fā)經(jīng)驗(yàn)
    "html-webpack-plugin": "^2.30.1",//簡(jiǎn)化了HTML文件的創(chuàng)建,引入了外部資源,創(chuàng)建html的入口文件,可通過(guò)此項(xiàng)進(jìn)行多頁(yè)面的配置
    "node-notifier": "^5.1.2",//支持使用node發(fā)送跨平臺(tái)的本地通知
    "optimize-css-assets-webpack-plugin": "^3.2.0",//壓縮提取出的css,并解決ExtractTextPlugin分離出的js重復(fù)問(wèn)題(多個(gè)文件引入同一css文件)
    "ora": "^1.2.0",//加載(loading)的插件
    "portfinder": "^1.0.13",//查看進(jìn)程端口
    "postcss-import": "^11.0.0",//可以消耗本地文件、節(jié)點(diǎn)模塊或web_modules
    "postcss-loader": "^2.0.8",//用來(lái)兼容css的插件
    "postcss-url": "^7.2.1",//URL上重新定位、內(nèi)聯(lián)或復(fù)制
    "rimraf": "^2.6.0",//節(jié)點(diǎn)的UNIX命令RM—RF,強(qiáng)制刪除文件或者目錄的命令
    "semver": "^5.3.0",//用來(lái)對(duì)特定的版本號(hào)做判斷的
    "shelljs": "^0.7.6",//使用它來(lái)消除shell腳本在UNIX上的依賴性,同時(shí)仍然保留其熟悉和強(qiáng)大的命令,即可執(zhí)行Unix系統(tǒng)命令
    "uglifyjs-webpack-plugin": "^1.1.1",//壓縮js文件
    "url-loader": "^0.5.8",//壓縮文件,可將圖片轉(zhuǎn)化為base64
    "vue-loader": "^13.3.0",//VUE單文件組件的WebPACK加載器
    "vue-style-loader": "^3.0.1",//類似于樣式加載程序,您可以在CSS加載器之后將其鏈接,以將CSS動(dòng)態(tài)地注入到文檔中作為樣式標(biāo)簽
    "vue-template-compiler": "^2.5.2",//這個(gè)包可以用來(lái)預(yù)編譯VUE模板到渲染函數(shù),以避免運(yùn)行時(shí)編譯開(kāi)銷和CSP限制
    "webpack": "^3.6.0",//打包工具
    "webpack-bundle-analyzer": "^2.9.0",//可視化webpack輸出文件的大小
    "webpack-dev-server": "^2.9.1",//提供一個(gè)提供實(shí)時(shí)重載的開(kāi)發(fā)服務(wù)器
    "webpack-merge": "^4.1.0"http://它將數(shù)組和合并對(duì)象創(chuàng)建一個(gè)新對(duì)象。如果遇到函數(shù),它將執(zhí)行它們,通過(guò)算法運(yùn)行結(jié)果,然后再次將返回的值封裝在函數(shù)中
  },
  //engines是引擎,指定node和npm版本
  "engines": {
    "node": ">= 6.0.0",
    "npm": ">= 3.0.0"
  },
  //限制了瀏覽器或者客戶端需要什么版本才可運(yùn)行
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

這邊我們需要比較注意的是?devDependencies?和?dependencies?的區(qū)別 。

對(duì)于?devDependencies?來(lái)說(shuō):在這個(gè)里面的插件只用于開(kāi)發(fā)環(huán)境,不用于生產(chǎn)環(huán)境,屬于輔助的作用,打包的時(shí)候需要,打包完成就不需要了。

那么對(duì)于?dependencies?來(lái)說(shuō):它是需要發(fā)布到生產(chǎn)環(huán)境的,自始至終都在。


2、prostcssrc.js

對(duì)于這個(gè)文件的話,其實(shí)它就是?postcss-loader?包的一個(gè)配置,而且在?webpack?的舊版本中可以直接在?webpack.config.js?中配置,現(xiàn)版本中?postcss?的文檔示例獨(dú)立出?.postcssrc.js?,里面寫進(jìn)去需要使用到的插件,代碼如下所示:

module.exports = {
  "plugins": {
    "postcss-import": {},//①postss插件@import 通過(guò)內(nèi)聯(lián)內(nèi)容來(lái)轉(zhuǎn)換規(guī)則。
    "postcss-url": {},//②postss插件,用于在url上重新設(shè)置、內(nèi)聯(lián)或復(fù)制
    "autoprefixer": {}//③PostCSS插件解析CSS并使用Can I Use中的值將供應(yīng)商前綴添加到CSS規(guī)則。它由Google 推薦并在Twitter和阿里巴巴中使用
  }
}

postcss-import文檔地址: https://www.npmjs.com/package/postcss-import

postcss-url文檔地址 : https://www.npmjs.com/package/postcss-url

autoprefixer文檔地址 : https://www.npmjs.com/package/autoprefixer


3、babelrc

這個(gè) .babelrc 文件是 es6解析的一個(gè)配置,代碼如下所示:

{
//制定轉(zhuǎn)碼的規(guī)則
  "presets": [
  //env是使用babel-preset-env插件將js進(jìn)行轉(zhuǎn)碼成es5,并且設(shè)置不轉(zhuǎn)碼的AMD,COMMONJS的模塊文件,制定瀏覽器的兼容
    ["env", {
      "modules": false,
      "targets": {
        "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
      }
    }],
    "stage-2"
  ],
   
  "plugins": ["transform-vue-jsx", "transform-runtime"]
}

4、其他文件

下面是一些相關(guān)文件的介紹,有興趣的小伙伴可以做個(gè)了解:

?.editorconfig:?編輯器的配置文件 。

?.gitignore:?忽略git提交的一個(gè)文件,配置之后提交時(shí)將不會(huì)加載忽略的文件。

?index.html:?頁(yè)面入口,經(jīng)過(guò)編譯之后的代碼將插入到這來(lái)。

?package.lock.json:?鎖定安裝時(shí)的包的版本號(hào),并且需要上傳到git,以保證其他人在npm install時(shí)大家的依賴能保證一致 。

?README.md:?可此填寫項(xiàng)目介紹 。

?node_modules:?根據(jù)package.json安裝時(shí)候生成的的依賴(安裝包) 。


5、src文件夾

下面這些是有關(guān)于在src文件夾中的內(nèi)容介紹:

?assets文件?:腳手架自動(dòng)會(huì)放入一個(gè)圖片在里面作為初始頁(yè)面的?logo?。平常我們使用的時(shí)候會(huì)在里面建立?js?,?css?,?img?,?fonts?等文件夾,作為靜態(tài)資源調(diào)用 。

?components文件夾?:用來(lái)存放組件,合理地使用組件可以高效地實(shí)現(xiàn)復(fù)用等功能,從而更好地開(kāi)發(fā)項(xiàng)目。一般情況下比如創(chuàng)建頭部組件的時(shí)候,我們會(huì)新建一個(gè)?header?的文件夾,然后再新建一個(gè)?header.vue?的文件。

?router文件夾?:該文件夾下有一個(gè)叫?index.js?文件,用于實(shí)現(xiàn)頁(yè)面的路由跳轉(zhuǎn)。

?App.vue?:作為我們的主組件,可通過(guò)使用?<router-view/>?開(kāi)放入口讓其他的頁(yè)面組件得以顯示。

?main.js?:作為我們的入口文件,主要作用是初始化vue實(shí)例并使用需要的插件,小型項(xiàng)目省略?router?時(shí)可放在該處 。


6、config文件夾

?config/dev.env.js?

在?config?內(nèi)的文件其實(shí)都是服務(wù)于?build?,大部分是定義一個(gè)變量?export?出去的,代碼如下所示:

'use strict'//采用嚴(yán)格模式
const merge = require('webpack-merge')//①
const prodEnv = require('./prod.env')
//webpack-merge提供了一個(gè)合并函數(shù),它將數(shù)組和合并對(duì)象創(chuàng)建一個(gè)新對(duì)象。
//如果遇到函數(shù),它將執(zhí)行它們,通過(guò)算法運(yùn)行結(jié)果,然后再次將返回的值封裝在函數(shù)中.這邊將dev和prod進(jìn)行合并
module.exports = merge(prodEnv, {
  NODE_ENV: '"development"'
})

 ?config/prod.env.js ?

當(dāng)我們?cè)陂_(kāi)發(fā)時(shí)是調(diào)取dev.env.js的開(kāi)發(fā)環(huán)境配置,發(fā)布時(shí)調(diào)用prod.env.js的生產(chǎn)環(huán)境配置,代碼如下所示:

'use strict'
module.exports = {
  NODE_ENV: '"production"'
}

?config/index.js ?

這個(gè)文件的話是用來(lái)定義開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境中需要的參數(shù)的,代碼如下所示:

'use strict'

const path = require('path')

module.exports = {

dev: {

// 開(kāi)發(fā)環(huán)境下面的配置

assetsSubDirectory: 'static', //子目錄,一般存放css,js,image等文件

assetsPublicPath: '/', //根目錄

proxyTable: { //可利用該屬性解決跨域的問(wèn)題  <br data-filtered="filtered"> '/api': {//代理<br data-filtered="filtered"> target:'http://localhost:8088/api',//接口域名

<br data-filtered="filtered">

changeOrigin:true,//是否跨域

<br data-filtered="filtered">   pathRewrite: {<br data-filtered="filtered">

'^/api': '' //需要rewrite重寫

<br data-filtered="filtered">  }<br data-filtered="filtered">    },

//可利用該屬性解決跨域的問(wèn)題

host:'localhost',

// 地址

port: 8080,

//端口號(hào)設(shè)置,端口號(hào)占用出現(xiàn)問(wèn)題可在此處修改

autoOpenBrowser:false,

//是否在編譯(輸入命令行npm run dev)后打開(kāi)http://localhost:8080/頁(yè)面,以前配置為true,近些版本改為false,個(gè)人偏向習(xí)慣自動(dòng)打開(kāi)頁(yè)面

errorOverlay:true,

//瀏覽器錯(cuò)誤提示

notifyOnErrors:true,

//跨平臺(tái)錯(cuò)誤提示

poll:false,

//使用文件系統(tǒng)(file system)獲取文件改動(dòng)的通知devServer.watchOptions

devtool:'cheap-module-eval-source-map',

//增加調(diào)試,該屬性為原始源代碼(僅限行)不可在生產(chǎn)環(huán)境中使用

cacheBusting:true,

//使緩存失效

cssSourceMap:true

//代碼壓縮后進(jìn)行調(diào)bug定位將非常困難,于是引入sourcemap記錄壓縮前后的位置信息記錄,當(dāng)產(chǎn)生錯(cuò)誤時(shí)直接定位到未壓縮前的位置,將大大的方便我們調(diào)試

},

build: {

// 生產(chǎn)環(huán)境下面的配置

index: path.resolve(__dirname,'../dist/index.html'),

//index編譯后生成的位置和名字,根據(jù)需要改變后綴,比如index.php

assetsRoot: path.resolve(__dirname,'../dist'),

//編譯后存放生成環(huán)境代碼的位置

assetsSubDirectory:'static',

//js,css,images存放文件夾名

assetsPublicPath:'/',

//發(fā)布的根目錄,通常本地打包dist后打開(kāi)文件會(huì)報(bào)錯(cuò),此處修改為./。如果是上線的文件,可根據(jù)文件存放位置進(jìn)行更改路徑

productionSourceMap:true,devtool:'#source-map',

//unit的gzip命令用來(lái)壓縮文件,gzip模式下需要壓縮的文件的擴(kuò)展名有js和css

productionGzip:false,

productionGzipExtensions: ['js','css'],

bundleAnalyzerReport: process.env.npm_config_report

}}


7、build文件夾

 ?build/build.js ?

對(duì)于在這個(gè)文件夾中的?build.js?文件的話,該文件的作用是用來(lái)構(gòu)建生產(chǎn)版本,然而 ?package.json?中的?scripts?的?build?就是?node build/build.js?,我們只需要輸入命令行?npm run build?就可以對(duì)該文件進(jìn)行編譯生成生產(chǎn)環(huán)境的代碼,代碼如下:

'use strict'
require('./check-versions')()//check-versions:調(diào)用檢查版本的文件。加()代表直接調(diào)用該函數(shù)
process.env.NODE_ENV = 'production'//設(shè)置當(dāng)前是生產(chǎn)環(huán)境
//下面定義常量引入插件
const ora = require('ora')//①加載動(dòng)畫
const rm = require('rimraf')//②刪除文件
const path = require('path')
const chalk = require('chalk')//③對(duì)文案輸出的一個(gè)彩色設(shè)置
const webpack = require('webpack')
const config = require('../config')//默認(rèn)讀取下面的index.js文件
const webpackConfig = require('./webpack.prod.conf')
//調(diào)用start的方法實(shí)現(xiàn)加載動(dòng)畫,優(yōu)化用戶體驗(yàn)
const spinner = ora('building for production...')
spinner.start()
//先刪除dist文件再生成新文件,因?yàn)橛袝r(shí)候會(huì)使用hash來(lái)命名,刪除整個(gè)文件可避免冗余
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  if (err) throw err
  webpack(webpackConfig, (err, stats) => {
    spinner.stop()
    if (err) throw err
    process.stdout.write(stats.toString({
      colors: true,
      modules: false,
      children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
      chunks: false,
      chunkModules: false
    }) + '\n\n')
 
    if (stats.hasErrors()) {
      process.exit(1)
    }
 
    console.log(chalk.cyan('  Build complete.\n'))
    console.log(chalk.yellow(
      '  Tip: built files are meant to be served over an HTTP server.\n' +
      '  Opening index.html over file:// won\'t work.\n'
    ))
  })
})

    

?build/check-version.js ?

那么在build文件夾下的version.js文件的話是用來(lái)檢測(cè)我們的node和npm版本的,代碼如下所示:

'use strict'
const chalk = require('chalk')
const semver = require('semver')//①對(duì)版本進(jìn)行檢查
const packageConfig = require('../package.json')
const shell = require('shelljs')
 
function exec (cmd) {
//返回通過(guò)child_process模塊的新建子進(jìn)程,執(zhí)行 Unix 系統(tǒng)命令后轉(zhuǎn)成沒(méi)有空格的字符串
  return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
  {
    name: 'node',
    currentVersion: semver.clean(process.version),//使用semver格式化版本
    versionRequirement: packageConfig.engines.node//獲取package.json中設(shè)置的node版本
  }
]
if (shell.which('npm')) {
  versionRequirements.push({
    name: 'npm',
    currentVersion: exec('npm --version'),// 自動(dòng)調(diào)用npm --version命令,并且把參數(shù)返回給exec函數(shù),從而獲取純凈的版本號(hào)
    versionRequirement: packageConfig.engines.npm
  })
}
 
module.exports = function () {
  const warnings = []
  for (let i = 0; i < versionRequirements.length; i++) {
    const mod = versionRequirements[i]
 
    if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
    //上面這個(gè)判斷就是如果版本號(hào)不符合package.json文件中指定的版本號(hào),就執(zhí)行下面錯(cuò)誤提示的代碼
      warnings.push(mod.name + ': ' +
        chalk.red(mod.currentVersion) + ' should be ' +
        chalk.green(mod.versionRequirement)
      )
    }
  }
 
  if (warnings.length) {
    console.log('')
    console.log(chalk.yellow('To use this template, you must update following to modules:'))
    console.log()
 
    for (let i = 0; i < warnings.length; i++) {
      const warning = warnings[i]
      console.log('  ' + warning)
    }
 
    console.log()
    process.exit(1)
  }
}

? build/utils.js?

那么對(duì)于在build中的utils.js文件來(lái)說(shuō)這則是一個(gè)工具,是用來(lái)處理css的文件,代碼如下所示:

'use strict'

const path = require('path')

const config = require('../config')

const ExtractTextPlugin = require('extract-text-webpack-plugin')

const packageConfig = require('../package.json')

//導(dǎo)出文件的位置,根據(jù)環(huán)境判斷開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境,為config文件中index.js文件中定義的build.assetsSubDirectory或dev.assetsSubDirectory

exports.assetsPath = function (_path) {

const assetsSubDirectory = process.env.NODE_ENV === 'production'? config.build.assetsSubDirectory: config.dev.assetsSubDirectory

//Node.js path 模塊提供了一些用于處理文件路徑的小工具①

return path.posix.join(assetsSubDirectory, _path)

}

exports.cssLoaders = function (options) {

options = options || {}

//使用了css-loader和postcssLoader,通過(guò)options.usePostCSS屬性來(lái)判斷是否使用postcssLoader中壓縮等方法

const cssLoader = {

loader: 'css-loader',

options: {

sourceMap: options.sourceMap

}}

const postcssLoader = {

loader: 'postcss-loader',

options: {

sourceMap: options.sourceMap}}

function generateLoaders (loader, loaderOptions) {

const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]

if (loader) {

loaders.push({

loader: loader + '-loader',

//Object.assign是es6語(yǔ)法的淺復(fù)制,后兩者合并后復(fù)制完成賦值

options: Object.assign({}, loaderOptions, {

sourceMap: options.sourceMap

})})}

if (options.extract) {

//ExtractTextPlugin可提取出文本,代表首先使用上面處理的loaders,當(dāng)未能正確引入時(shí)使用vue-style-loader

return ExtractTextPlugin.extract({

use: loaders,

fallback: 'vue-style-loader'

})

} else {

//返回vue-style-loader連接loaders的最終值

return ['vue-style-loader'].concat(loaders)

}}

return {

css: generateLoaders(),//需要css-loader 和 vue-style-loader

postcss: generateLoaders(),//需要css-loader和postcssLoader 和 vue-style-loader

less: generateLoaders('less'),//需要less-loader 和 vue-style-loader

sass: generateLoaders('sass', { indentedSyntax: true }),//需要sass-loader 和 vue-style-loader

scss: generateLoaders('sass'),//需要sass-loader 和 vue-style-loader

stylus: generateLoaders('stylus'),//需要stylus-loader 和 vue-style-loader

styl: generateLoaders('stylus')//需要stylus-loader 和 vue-style-loader

}}

exports.styleLoaders = function (options) {

const output = []

const loaders = exports.cssLoaders(options)

//將各種css,less,sass等綜合在一起得出結(jié)果輸出output

for (const extension in loaders) {

const loader = loaders[extension]

output.push({

test: new RegExp('\\.' + extension + '$'),

use: loader

})}

return output}

exports.createNotifierCallback = () => {

//發(fā)送跨平臺(tái)通知系統(tǒng)

const notifier = require('node-notifier')

return (severity, errors) => {

if (severity !== 'error') return

//當(dāng)報(bào)錯(cuò)時(shí)輸出錯(cuò)誤信息的標(biāo)題,錯(cuò)誤信息詳情,副標(biāo)題以及圖標(biāo)

const error = errors[0]

const filename = error.file && error.file.split('!').pop()

notifier.notify({

title: packageConfig.name,

message: severity + ': ' + error.name,

subtitle: filename || '',

icon: path.join(__dirname, 'logo.png')

})}}

? vue-loader.conf.js ?

關(guān)于這個(gè)文件的話,我們就直接看下面代碼吧!

'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
  ? config.build.productionSourceMap
  : config.dev.cssSourceMap
//處理項(xiàng)目中的css文件,生產(chǎn)環(huán)境和測(cè)試環(huán)境默認(rèn)是打開(kāi)sourceMap,而extract中的提取樣式到單獨(dú)文件只有在生產(chǎn)環(huán)境中才需要
module.exports = {
  loaders: utils.cssLoaders({
    sourceMap: sourceMapEnabled,
    extract: isProduction
  }),
  cssSourceMap: sourceMapEnabled,
  cacheBusting: config.dev.cacheBusting,
  transformToRequire: {
    video: ['src', 'poster'],
    source: 'src',
    img: 'src',
    image: 'xlink:href'
  }
}

?webpack.base.conf.js ?

這個(gè)文件的是屬于開(kāi)發(fā)和生產(chǎn)共同使用提出來(lái)的基礎(chǔ)文件,主要是實(shí)現(xiàn)配置入口、輸出環(huán)境和配置模板resolve和插件等等的作用。代碼如下所示:

'use strict'

const path = require('path')

const utils = require('./utils')

const config = require('../config')

const vueLoaderConfig = require('./vue-loader.conf')

function resolve (dir) {

//拼接出絕對(duì)路徑

return path.join(__dirname, '..', dir)}

module.exports = {

//path.join將路徑片段進(jìn)行拼接,而path.resolve將以/開(kāi)始的路徑片段作為根目錄,在此之前的路徑將會(huì)被丟棄

//path.join('/a', '/b') // 'a/b',path.resolve('/a', '/b') // '/b'

context: path.resolve(__dirname, '../'),

//配置入口,默認(rèn)為單頁(yè)面所以只有app一個(gè)入口

entry: {app: './src/main.js'},

//配置出口,默認(rèn)是/dist作為目標(biāo)文件夾的路徑

output: {path: config.build.assetsRoot,//路徑

filename: '[name].js',//文件名

publicPath: process.env.NODE_ENV === 'production'? config.build.assetsPublicPath: config.dev.assetsPublicPath//公共存放路徑},

resolve: {

//自動(dòng)的擴(kuò)展后綴,比如一個(gè)js文件,則引用時(shí)書寫可不要寫.js

extensions: ['.js', '.vue', '.json'],

//創(chuàng)建路徑的別名,比如增加'components': resolve('src/components')等

alias: {

'vue$': 'vue/dist/vue.esm.js',

'@': resolve('src'),

}},

//使用插件配置相應(yīng)文件的處理方法

module: {rules: [

//使用vue-loader將vue文件轉(zhuǎn)化成js的模塊①

{test: /\.vue$/,loader: 'vue-loader',options: vueLoaderConfig},

//js文件需要通過(guò)babel-loader進(jìn)行編譯成es5文件以及壓縮等操作②

{test: /\.js$/,loader: 'babel-loader',include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]

},

//圖片、音像、字體都使用url-loader進(jìn)行處理,超過(guò)10000會(huì)編譯成base64③

{test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,loader: 'url-loader',

options: {limit: 10000,name: utils.assetsPath('img/[name].[hash:7].[ext]')

}},{

test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,loader: 'url-loader',

options: {

limit: 10000,

name: utils.assetsPath('media/[name].[hash:7].[ext]')

}},{

test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,loader: 'url-loader',

options: {

limit: 10000,

name: utils.assetsPath('fonts/[name].[hash:7].[ext]')}}]},

//以下選項(xiàng)是Node.js全局變量或模塊,這里主要是防止webpack注入一些Node.js的東西到vue中

node:setImmediate: false,dgram: 'empty',fs: 'empty',net: 'empty',tls: 'empty',child_process: 'empty'

}}

?webpack.dev.conf.js?

這個(gè)文件是在vue開(kāi)發(fā)環(huán)境中的webpack相關(guān)文件,代碼如下所示:

'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
//通過(guò)webpack-merge實(shí)現(xiàn)webpack.dev.conf.js對(duì)wepack.base.config.js的繼承
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
//美化webpack的錯(cuò)誤信息和日志的插件①
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')// 查看空閑端口位置,默認(rèn)情況下搜索8000這個(gè)端口②
const HOST = process.env.HOST//③processs為node的一個(gè)全局對(duì)象獲取當(dāng)前程序的環(huán)境變量,即host
const PORT = process.env.PORT && Number(process.env.PORT)

const devWebpackConfig = merge(baseWebpackConfig, {
module: {
//規(guī)則是工具utils中處理出來(lái)的styleLoaders,生成了css,less,postcss等規(guī)則
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},

devtool: config.dev.devtool, //增強(qiáng)調(diào)試,上文有提及
//此處的配置都是在config的index.js中設(shè)定好了
devServer: {//④
clientLogLevel: 'warning',//控制臺(tái)顯示的選項(xiàng)有none, error, warning 或者 info
//當(dāng)使用 HTML5 History API 時(shí),任意的 404 響應(yīng)都可能需要被替代為 index.html
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,//熱加載
contentBase: false,
compress: true,//壓縮
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,//調(diào)試時(shí)自動(dòng)打開(kāi)瀏覽器
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,// warning 和 error 都要顯示
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,//接口代理
quiet: true, //控制臺(tái)是否禁止打印警告和錯(cuò)誤,若用FriendlyErrorsPlugin 此處為 true
watchOptions: {
poll: config.dev.poll,//// 文件系統(tǒng)檢測(cè)改動(dòng)
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),//⑤模塊熱替換插件,修改模塊時(shí)不需要刷新頁(yè)面
new webpack.NamedModulesPlugin(), // 顯示文件的正確名字
new webpack.NoEmitOnErrorsPlugin(),//當(dāng)webpack編譯錯(cuò)誤的時(shí)候,來(lái)中端打包進(jìn)程,防止錯(cuò)誤代碼打包到文件中
// https://github.com/ampedandwired/html-webpack-plugin
// 該插件可自動(dòng)生成一個(gè) html5 文件或使用模板文件將編譯好的代碼注入進(jìn)去⑥
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
new CopyWebpackPlugin([//復(fù)制插件
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']//忽略.*的文件
}
])
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
//查找端口號(hào)
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
//端口被占用時(shí)就重新設(shè)置evn和devServer的端口
process.env.PORT = port
devWebpackConfig.devServer.port = port
//友好地輸出信息
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})

?webpack.prod.conf.js ?

這個(gè)文件和上面的類似它是vue生產(chǎn)環(huán)境的webpack相關(guān)配置文件,代碼如下所示:

'use strict'

const path = require('path')

const utils = require('./utils')// 工具函數(shù)集合

const webpack = require('webpack')

const config = require('../config')

const merge = require('webpack-merge')// webpack 配置合并插件

const baseWebpackConfig = require('./webpack.base.conf')// webpack 基本配置

const CopyWebpackPlugin = require('copy-webpack-plugin')// webpack 復(fù)制文件和文件夾的插件

const HtmlWebpackPlugin = require('html-webpack-plugin')// 自動(dòng)生成 html 并且注入到 .html 文件中的插件

const ExtractTextPlugin = require('extract-text-webpack-plugin')// 提取css的插件

const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')//webpack 優(yōu)化壓縮和優(yōu)化 css 的插件

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const env = require('../config/prod.env')

const webpackConfig = merge(baseWebpackConfig, {

module: {

//調(diào)用utils.styleLoaders的方法

rules: utils.styleLoaders({

sourceMap: config.build.productionSourceMap,//開(kāi)啟調(diào)試的模式。默認(rèn)為true

extract: true,

usePostCSS: true

})

},

devtool: config.build.productionSourceMap ? config.build.devtool : false,

output: {

path: config.build.assetsRoot,

filename: utils.assetsPath('js/[name].[chunkhash].js'),

chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')

},

plugins: [

// http://vuejs.github.io/vue-loader/en/workflow/production.html

new webpack.DefinePlugin({

'process.env': env

}),

// 壓縮 js

new UglifyJsPlugin({

uglifyOptions: {

compress: {

warnings: false

}

},

sourceMap: config.build.productionSourceMap,

parallel: true

}),

// extract css into its own file

new ExtractTextPlugin({

filename: utils.assetsPath('css/[name].[contenthash].css'),

// Setting the following option to `false` will not extract CSS from codesplit chunks.

// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.

// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when

it's `false`,

// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110

allChunks: true,

}),

// Compress extracted CSS. We are using this plugin so that possible

// duplicated CSS from different components can be deduped.

new OptimizeCSSPlugin({

cssProcessorOptions: config.build.productionSourceMap

? { safe: true, map: { inline: false } }

: { safe: true }

}),

// generate dist index.html with correct asset hash for caching.

// you can customize output by editing /index.html

// see https://github.com/ampedandwired/html-webpack-plugin

new HtmlWebpackPlugin({

filename: config.build.index,

template: 'index.html',

inject: true,

minify: {

removeComments: true,

collapseWhitespace: true,

removeAttributeQuotes: true

// more options:

// https://github.com/kangax/html-minifier#options-quick-reference

},

// necessary to consistently work with multiple chunks via CommonsChunkPlugin

chunksSortMode: 'dependency'

}),

// keep module.id stable when vendor modules does not change

new webpack.HashedModuleIdsPlugin(),

// enable scope hoisting

new webpack.optimize.ModuleConcatenationPlugin(),

// 分割公共 js 到獨(dú)立的文件

new webpack.optimize.CommonsChunkPlugin({

name: 'vendor',

minChunks (module) {

// node_modules中的任何所需模塊都提取到vendor

return (

module.resource &&

/\.js$/.test(module.resource) &&

module.resource.indexOf(

path.join(__dirname, '../node_modules')

) === 0

)

}

}),

// extract webpack runtime and module manifest to its own file in order to

// prevent vendor hash from being updated whenever app bundle is updated

new webpack.optimize.CommonsChunkPlugin({

name: 'manifest',

minChunks: Infinity

}),

// This instance extracts shared chunks from code splitted chunks and bundles them

// in a separate chunk, similar to the vendor chunk

// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk

new webpack.optimize.CommonsChunkPlugin({

name: 'app',

async: 'vendor-async',

children: true,

minChunks: 3

}),

// 復(fù)制靜態(tài)資源

new CopyWebpackPlugin([

{

from: path.resolve(__dirname, '../static'),

to: config.build.assetsSubDirectory,

ignore: ['.*']

}

])

]

})

if (config.build.productionGzip) {

const CompressionWebpackPlugin = require('compression-webpack-plugin')

webpackConfig.plugins.push(

new CompressionWebpackPlugin({

asset: '[path].gz[query]',

algorithm: 'gzip',

test: new RegExp(

'\\.(' +

config.build.productionGzipExtensions.join('|') +

')$'

),

threshold: 10240,

minRatio: 0.8

})

)

}

if (config.build.bundleAnalyzerReport) {

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

webpackConfig.plugins.push(new BundleAnalyzerPlugin())

}

module.exports = webpackConfig

webpack.prod.conf.js

<a title="postcss"  target="_blank"> </a>

總結(jié):

以上就是有關(guān)于:“vue-cli webpack怎么配置?”這個(gè)問(wèn)題的相關(guān)內(nèi)容,如果你有其他的辯解也可以分享出來(lái)和大家一同探討,更多有關(guān)于VUE相關(guān)的內(nèi)容和知識(shí)我們都可以在W3cschool中進(jìn)行學(xué)習(xí)和了解。


1 人點(diǎn)贊