溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

vue-cli目錄結(jié)構(gòu)詳細(xì)講解

發(fā)布時(shí)間:2021-09-02 10:52:51 來(lái)源:億速云 閱讀:134 作者:chen 欄目:web開(kāi)發(fā)

這篇文章主要講解了“vue-cli目錄結(jié)構(gòu)詳細(xì)講解”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“vue-cli目錄結(jié)構(gòu)詳細(xì)講解”吧!

一個(gè)vue-cli的項(xiàng)目結(jié)構(gòu)如下:

目錄

結(jié)構(gòu)預(yù)覽

├─build         // 保存一些webpack的初始化配置,項(xiàng)目構(gòu)建
│ ├─build.js      // 生產(chǎn)環(huán)境構(gòu)建
│ ├─check-version.js  // 檢查npm、node版本
│ ├─vue-loader.conf.js // webpack loader配置
│ ├─webpack.base.conf.js// webpack基礎(chǔ)配置
│ ├─webpack.dev.conf.js // 開(kāi)發(fā)環(huán)境配置,構(gòu)建本地開(kāi)發(fā)服務(wù)器
│ ├─webpack.prod.conf.js// 生產(chǎn)環(huán)境的配置
│
├─config        // config文件夾保存一些項(xiàng)目初始化的配置
│ ├─dev.env.js     // 開(kāi)發(fā)環(huán)境的配置
│ ├─index.js      // 項(xiàng)目一些配置變量
│ ├─prod.env.js     // 生產(chǎn)環(huán)境的配置
│
├─dist         // 打包后的項(xiàng)目
├─node_modules     // 依賴(lài)包
│
├─src          // 源碼目錄
│ ├─assets       // 靜態(tài)文件目錄
│ ├─components     // 組件文件
│ ├─router       // 路由
│ ├─App.vue       // 是項(xiàng)目入口文件
│ ├─main.js       // 是項(xiàng)目的核心文件,入口
├─static        // 靜態(tài)資源目錄 
├─.babelrc       // Babel的配置文件
├─.editorconfig     // 代碼規(guī)范配置文件
├─.gitignore      // git忽略配置文件
├─.postcssrc.js     // postcss插件配置文件
├─index.html      // 頁(yè)面入口文件
├─package-lock.json   // 項(xiàng)目包管控文件
├─package.json     // 項(xiàng)目配置
└─README.md       // 項(xiàng)目說(shuō)明書(shū)

結(jié)構(gòu)解析

build

dev-server.js

首先來(lái)看執(zhí)行”npm run dev”時(shí)候最先執(zhí)行的build/dev-server.js文件。該文件主要完成下面幾件事情:

  • 檢查node和npm的版本、引入相關(guān)插件和配置

  • webpack對(duì)源碼進(jìn)行編譯打包并返回compiler對(duì)象

  • 創(chuàng)建express服務(wù)器

  • 配置開(kāi)發(fā)中間件(webpack-dev-middleware)和+ 熱重載中間件(webpack-hot-middleware)

  • 掛載代理服務(wù)和中間件

  • 配置靜態(tài)資源

  • 啟動(dòng)服務(wù)器監(jiān)聽(tīng)特定端口(8080)

  • 自動(dòng)打開(kāi)瀏覽器并打開(kāi)特定網(wǎng)址(localhost:8080)

說(shuō)明: express服務(wù)器提供靜態(tài)文件服務(wù),不過(guò)它還使用了http-proxy-middleware,一個(gè)http請(qǐng)求代理的中間件。前端開(kāi)發(fā)過(guò)程中需要使用到后臺(tái)的API的話(huà),可以通過(guò)配置proxyTable來(lái)將相應(yīng)的后臺(tái)請(qǐng)求代理到專(zhuān)用的API服務(wù)器。

// 檢查NodeJS和npm的版本
require('./check-versions')()

// 獲取基本配置
var config = require('../config')
// 如果Node的環(huán)境變量中沒(méi)有設(shè)置當(dāng)前的環(huán)境(NODE_ENV),則使用config中的dev環(huán)境配置作為當(dāng)前的環(huán)境
if (!process.env.NODE_ENV) {
 process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}

// opn是一個(gè)可以調(diào)用默認(rèn)軟件打開(kāi)網(wǎng)址、圖片、文件等內(nèi)容的插件
// 這里用它來(lái)調(diào)用默認(rèn)瀏覽器打開(kāi)dev-server監(jiān)聽(tīng)的端口,例如:localhost:8080
var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack')
// http-proxy-middleware是一個(gè)express中間件,用于將http請(qǐng)求代理到其他服務(wù)器
// 例:localhost:8080/api/xxx --> localhost:3000/api/xxx
// 這里使用該插件可以將前端開(kāi)發(fā)中涉及到的請(qǐng)求代理到提供服務(wù)的后臺(tái)服務(wù)器上,方便與服務(wù)器對(duì)接
var proxyMiddleware = require('http-proxy-middleware')
// 開(kāi)發(fā)環(huán)境下的webpack配置
var webpackConfig = require('./webpack.dev.conf')

// dev-server 監(jiān)聽(tīng)的端口,如果沒(méi)有在命令行傳入端口號(hào),則使用config.dev.port設(shè)置的端口,例如8080
var port = process.env.PORT || config.dev.port
// 用于判斷是否要自動(dòng)打開(kāi)瀏覽器的布爾變量,當(dāng)配置文件中沒(méi)有設(shè)置自動(dòng)打開(kāi)瀏覽器的時(shí)候其值為 false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// HTTP代理表,指定規(guī)則,將某些API請(qǐng)求代理到相應(yīng)的服務(wù)器
var proxyTable = config.dev.proxyTable
// 創(chuàng)建express服務(wù)器
var app = express()
// webpack根據(jù)配置開(kāi)始編譯打包源碼并返回compiler對(duì)象
var compiler = webpack(webpackConfig)
// webpack-dev-middleware將webpack編譯打包后得到的產(chǎn)品文件存放在內(nèi)存中而沒(méi)有寫(xiě)進(jìn)磁盤(pán)
// 將這個(gè)中間件掛到express上使用之后即可提供這些編譯后的產(chǎn)品文件服務(wù)
var devMiddleware = require('webpack-dev-middleware')(compiler, {
 publicPath: webpackConfig.output.publicPath, // 設(shè)置訪(fǎng)問(wèn)路徑為webpack配置中的output里面所對(duì)應(yīng)的路徑
 quiet: true // 設(shè)置為true,使其不要在控制臺(tái)輸出日志
})
// webpack-hot-middleware,用于實(shí)現(xiàn)熱重載功能的中間件
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
 log: false, // 關(guān)閉控制臺(tái)的日志輸出
 heartbeat: 2000 // 發(fā)送心跳包的頻率
})
// webpack(重新)編譯打包完成后并將js、css等文件inject到html文件之后,通過(guò)熱重載中間件強(qiáng)制頁(yè)面刷新
compiler.plugin('compilation', function (compilation) {
 compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
  hotMiddleware.publish({ action: 'reload' })
  cb()
 })
})

// 根據(jù) proxyTable 中的代理請(qǐng)求配置來(lái)設(shè)置express服務(wù)器的http代理規(guī)則
Object.keys(proxyTable).forEach(function (context) {
 var options = proxyTable[context]
 // 格式化options,例如將'www.example.com'變成{ target: 'www.example.com' }
 if (typeof options === 'string') {
  options = { target: options }
 }
 app.use(proxyMiddleware(options.filter || context, options))
})

// handle fallback for HTML5 history API
// 重定向不存在的URL,用于支持SPA(單頁(yè)應(yīng)用)
// 例如使用vue-router并開(kāi)啟了history模式
app.use(require('connect-history-api-fallback')())

// serve webpack bundle output
// 掛載webpack-dev-middleware中間件,提供webpack編譯打包后的產(chǎn)品文件服務(wù)
app.use(devMiddleware)

// enable hot-reload and state-preserving
// compilation error display
// 掛載熱重載中間件
app.use(hotMiddleware)

// serve pure static assets
// 提供static文件夾上的靜態(tài)文件服務(wù)
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))

// 訪(fǎng)問(wèn)鏈接
var uri = 'http://localhost:' + port

// 創(chuàng)建promise,在應(yīng)用服務(wù)啟動(dòng)之后resolve
// 便于外部文件require了這個(gè)dev-server之后的代碼編寫(xiě)
var _resolve
var readyPromise = new Promise(resolve => {
 _resolve = resolve
})

console.log('> Starting dev server...')
// webpack-dev-middleware等待webpack完成所有編譯打包之后輸出提示語(yǔ)到控制臺(tái),表明服務(wù)正式啟動(dòng)
// 服務(wù)正式啟動(dòng)才自動(dòng)打開(kāi)瀏覽器進(jìn)入頁(yè)面
devMiddleware.waitUntilValid(() => {
 console.log('> Listening at ' + uri + '\n')
 // when env is testing, don't need open it
 if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
  opn(uri)
 }
 _resolve()
})

// 啟動(dòng)express服務(wù)器并監(jiān)聽(tīng)相應(yīng)的端口
var server = app.listen(port)

// 暴露本模塊的功能給外部使用,例如下面這種用法
// var devServer = require('./build/dev-server')
// devServer.ready.then(() => {...})
// if (...) { devServer.close() }
module.exports = {
 ready: readyPromise,
 close: () => {
  server.close()
 }
}

webpack.base.conf.js

從代碼中看到,dev-server使用的webpack配置來(lái)自build/webpack.dev.conf.js文件(測(cè)試環(huán)境下使用的是build/webpack.prod.conf.js,這里暫時(shí)不考慮測(cè)試環(huán)境)。而build/webpack.dev.conf.js中又引用了webpack.base.conf.js,所以這里我先分析webpack.base.conf.js。

webpack.base.conf.js主要完成了下面這些事情:

  • 配置webpack編譯入口

  • 配置webpack輸出路徑和命名規(guī)則

  • 配置模塊resolve規(guī)則

  • 配置不同類(lèi)型模塊的處理規(guī)則

說(shuō)明: 這個(gè)配置里面只配置了.js、.vue、圖片、字體等幾類(lèi)文件的處理規(guī)則,如果需要處理其他文件可以在module.rules里面另行配置。

var path = require('path')
var fs = require('fs')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')

// 獲取絕對(duì)路徑
function resolve (dir) {
 return path.join(__dirname, '..', dir)
}

module.exports = {
 // webpack入口文件
 entry: {
  app: './src/main.js'
 },
 // webpack輸出路徑和命名規(guī)則
 output: {
  // webpack輸出的目標(biāo)文件夾路徑(例如:/dist)
  path: config.build.assetsRoot,
  // webpack輸出bundle文件命名格式
  filename: '[name].js',
  // webpack編譯輸出的發(fā)布路徑(例如'//cdn.xxx.com/app/')
  publicPath: process.env.NODE_ENV === 'production'
   ? config.build.assetsPublicPath
   : config.dev.assetsPublicPath
 },
 // 模塊resolve的規(guī)則
 resolve: {
  extensions: ['.js', '.vue', '.json'],
  // 別名,方便引用模塊,例如有了別名之后,
  // import Vue from 'vue/dist/vue.common.js'可以寫(xiě)成 import Vue from 'vue'
  alias: {
   'vue$': 'vue/dist/vue.esm.js',
   '@': resolve('src'),
  },
  symlinks: false
 },
 // 不同類(lèi)型模塊的處理規(guī)則
 module: {
  rules: [
   {// 對(duì)src和test文件夾下的.js和.vue文件使用eslint-loader進(jìn)行代碼規(guī)范檢查
    test: /\.(js|vue)$/,
    loader: 'eslint-loader',
    enforce: 'pre',
    include: [resolve('src'), resolve('test')],
    options: {
     formatter: require('eslint-friendly-formatter')
    }
   },
   {// 對(duì)所有.vue文件使用vue-loader進(jìn)行編譯
    test: /\.vue$/,
    loader: 'vue-loader',
    options: vueLoaderConfig
   },
   {// 對(duì)src和test文件夾下的.js文件使用babel-loader將es6+的代碼轉(zhuǎn)成es5
    test: /\.js$/,
    loader: 'babel-loader',
    include: [resolve('src'), resolve('test')]
   },
   {// 對(duì)圖片資源文件使用url-loader
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
     // 小于10K的圖片轉(zhuǎn)成base64編碼的dataURL字符串寫(xiě)到代碼中
     limit: 10000,
     // 其他的圖片轉(zhuǎn)移到靜態(tài)資源文件夾
     name: utils.assetsPath('img/[name].[hash:7].[ext]')
    }
   },
   {// 對(duì)多媒體資源文件使用url-loader
    test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
    loader: 'url-loader',
    options: {
     // 小于10K的資源轉(zhuǎn)成base64編碼的dataURL字符串寫(xiě)到代碼中
     limit: 10000,
     // 其他的資源轉(zhuǎn)移到靜態(tài)資源文件夾
     name: utils.assetsPath('media/[name].[hash:7].[ext]')
    }
   },
   {// 對(duì)字體資源文件使用url-loader
    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
    loader: 'url-loader',
    options: {
     // 小于10K的資源轉(zhuǎn)成base64編碼的dataURL字符串寫(xiě)到代碼中
     limit: 10000,
     // 其他的資源轉(zhuǎn)移到靜態(tài)資源文件夾
     name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
    }
   }
  ]
 }
}

webpack.dev.conf.js

接下來(lái)看webpack.dev.conf.js,這里面在webpack.base.conf的基礎(chǔ)上增加完善了開(kāi)發(fā)環(huán)境下面的配置,主要包括下面幾件事情:

  • 將webpack的熱重載客戶(hù)端代碼添加到每個(gè)entry對(duì)應(yīng)的應(yīng)用

  • 合并基礎(chǔ)的webpack配置

  • 配置樣式文件的處理規(guī)則,styleLoaders

  • 配置Source Maps

  • 配置webpack插件

var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
// webpack-merge是一個(gè)可以合并數(shù)組和對(duì)象的插件
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
// html-webpack-plugin用于將webpack編譯打包后的產(chǎn)品文件注入到html模板中
// 即自動(dòng)在index.html里面加上<link>和<script>標(biāo)簽引用webpack打包后的文件
var HtmlWebpackPlugin = require('html-webpack-plugin')
// friendly-errors-webpack-plugin用于更友好地輸出webpack的警告、錯(cuò)誤等信息
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')

// add hot-reload related code to entry chunks
// 給每個(gè)入口頁(yè)面(應(yīng)用)加上dev-client,用于跟dev-server的熱重載插件通信,實(shí)現(xiàn)熱更新
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
 baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})

module.exports = merge(baseWebpackConfig, {
 module: {
  // 樣式文件的處理規(guī)則,對(duì)css/sass/scss等不同內(nèi)容使用相應(yīng)的styleLoaders
  // 由utils配置出各種類(lèi)型的預(yù)處理語(yǔ)言所需要使用的loader,例如sass需要使用sass-loader
  rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
 },
 // cheap-module-eval-source-map is faster for development
 // 使用這種source-map更快
 devtool: '#cheap-module-eval-source-map',
 // webpack插件
 plugins: [
  new webpack.DefinePlugin({
   'process.env': config.dev.env
  }),
  // 開(kāi)啟webpack熱更新功能
  new webpack.HotModuleReplacementPlugin(),
  // webpack編譯過(guò)程中出錯(cuò)的時(shí)候跳過(guò)報(bào)錯(cuò)階段,不會(huì)阻塞編譯,在編譯結(jié)束后報(bào)錯(cuò)
  new webpack.NoEmitOnErrorsPlugin(),
  // 自動(dòng)將依賴(lài)注入html模板,并輸出最終的html文件到目標(biāo)文件夾
  new HtmlWebpackPlugin({
   filename: 'index.html',
   template: 'index.html',
   inject: true
  }),
  new FriendlyErrorsPlugin()
 ]
})

utils

此配置文件是vue開(kāi)發(fā)環(huán)境的wepack相關(guān)配置文件,主要用來(lái)處理css-loader和vue-style-loader

// 引入nodejs路徑模塊
var path = require('path')
// 引入config目錄下的index.js配置文件
var config = require('../config')
// 引入extract-text-webpack-plugin插件,用來(lái)將css提取到單獨(dú)的css文件中
// 詳情請(qǐng)看(1)
var ExtractTextPlugin = require('extract-text-webpack-plugin')
// exports其實(shí)就是一個(gè)對(duì)象,用來(lái)導(dǎo)出方法的最終還是使用module.exports,此處導(dǎo)出assetsPath
exports.assetsPath = function (_path) {
 // 如果是生產(chǎn)環(huán)境assetsSubDirectory就是'static',否則還是'static',哈哈哈
 var assetsSubDirectory = process.env.NODE_ENV === 'production'
  ? config.build.assetsSubDirectory
  : config.dev.assetsSubDirectory
 // path.join和path.posix.join的區(qū)別就是,前者返回的是完整的路徑,后者返回的是完整路徑的相對(duì)根路徑
 // 也就是說(shuō)path.join的路徑是C:a/a/b/xiangmu/b,那么path.posix.join就是b
 return path.posix.join(assetsSubDirectory, _path)
 // 所以這個(gè)方法的作用就是返回一個(gè)干凈的相對(duì)根路徑
}
 
// 下面是導(dǎo)出cssLoaders的相關(guān)配置
exports.cssLoaders = function (options) {
 // options如果沒(méi)值就是空對(duì)象
 options = options || {}
 // cssLoader的基本配置
 var cssLoader = {
  loader: 'css-loader',
  options: {
   // options是用來(lái)傳遞參數(shù)給loader的
   // minimize表示壓縮,如果是生產(chǎn)環(huán)境就壓縮css代碼
   minimize: process.env.NODE_ENV === 'production',
   // 是否開(kāi)啟cssmap,默認(rèn)是false
   sourceMap: options.sourceMap
  }
 }
 
 // generate loader string to be used with extract text plugin
 function generateLoaders (loader, loaderOptions) {
  // 將上面的基礎(chǔ)cssLoader配置放在一個(gè)數(shù)組里面
  var loaders = [cssLoader]
  // 如果該函數(shù)傳遞了單獨(dú)的loader就加到這個(gè)loaders數(shù)組里面,這個(gè)loader可能是less,sass之類(lèi)的
  if (loader) {
   loaders.push({
    // 加載對(duì)應(yīng)的loader
    loader: loader + '-loader',
    // Object.assign是es6的方法,主要用來(lái)合并對(duì)象的,淺拷貝
    options: Object.assign({}, loaderOptions, {
     sourceMap: options.sourceMap
    })
   })
  }
 
  // Extract CSS when that option is specified
  // (which is the case during production build)
  // 注意這個(gè)extract是自定義的屬性,可以定義在options里面,主要作用就是當(dāng)配置為true就把文件單獨(dú)提取,false表示不單獨(dú)提取,這個(gè)可以在使用的時(shí)候單獨(dú)配置,瞬間覺(jué)得vue作者好牛逼
  if (options.extract) {
   return ExtractTextPlugin.extract({
    use: loaders,
    fallback: 'vue-style-loader'
   })
  } else {
   return ['vue-style-loader'].concat(loaders)
  }
  // 上面這段代碼就是用來(lái)返回最終讀取和導(dǎo)入loader,來(lái)處理對(duì)應(yīng)類(lèi)型的文件
 }
 
 // https://vue-loader.vuejs.org/en/configurations/extract-css.html
 return {
  css: generateLoaders(), // css對(duì)應(yīng) vue-style-loader 和 css-loader
  postcss: generateLoaders(), // postcss對(duì)應(yīng) vue-style-loader 和 css-loader
  less: generateLoaders('less'), // less對(duì)應(yīng) vue-style-loader 和 less-loader
  sass: generateLoaders('sass', { indentedSyntax: true }), // sass對(duì)應(yīng) vue-style-loader 和 sass-loader
  scss: generateLoaders('sass'), // scss對(duì)應(yīng) vue-style-loader 和 sass-loader
  stylus: generateLoaders('stylus'), // stylus對(duì)應(yīng) vue-style-loader 和 stylus-loader
  styl: generateLoaders('stylus') // styl對(duì)應(yīng) vue-style-loader 和 styl-loader 
 }
}
 
// Generate loaders for standalone style files (outside of .vue)
// 下面這個(gè)主要處理import這種方式導(dǎo)入的文件類(lèi)型的打包,上面的exports.cssLoaders是為這一步服務(wù)的
exports.styleLoaders = function (options) {
 var output = []
 // 下面就是生成的各種css文件的loader對(duì)象
 var loaders = exports.cssLoaders(options)
 for (var extension in loaders) {
  // 把每一種文件的laoder都提取出來(lái)
  var loader = loaders[extension]
  output.push({
   // 把最終的結(jié)果都push到output數(shù)組中,大事搞定
   test: new RegExp('\\.' + extension + '$'),
   use: loader
  })
 }
 return output
}

extract-text-webpack-plugin插件是用來(lái)將文本從bundle中提取到一個(gè)單獨(dú)的文件中

const ExtractTextPlugin = require("extract-text-webpack-plugin");
 module.exports = {
  module: {
   rules: [
    {
     test: /\.css$/, //主要用來(lái)處理css文件
     use: ExtractTextPlugin.extract({
      fallback: "style-loader", // fallback表示如果css文件沒(méi)有成功導(dǎo)入就使用style-loader導(dǎo)入
      use: "css-loader" // 表示使用css-loader從js讀取css文件
     })
    }
   ],
   plugins: [
    new ExtractTextPlugin("styles.css") //表示生成styles.css文件
   ]
  }
 }

vue-loader.conf.js

var utils = require('./utils')
var config = require('../config')
var isProduction = process.env.NODE_ENV === 'production'

module.exports = {
 // 處理.vue文件中的樣式
 loaders: utils.cssLoaders({
  // 是否打開(kāi)source-map
  sourceMap: isProduction
   ? config.build.productionSourceMap
   : config.dev.cssSourceMap,
  // 是否提取樣式到單獨(dú)的文件
  extract: isProduction
 }),
 transformToRequire: {
  video: 'src',
  source: 'src',
  img: 'src',
  image: 'xlink:href'
 }
}

dev-client.js

dev-client.js里面主要寫(xiě)了瀏覽器端代碼,用于實(shí)現(xiàn)webpack的熱更新。

/* eslint-disable */
// 實(shí)現(xiàn)瀏覽器端的EventSource,用于跟服務(wù)器雙向通信
// webpack熱重載客戶(hù)端跟dev-server上的熱重載插件之間需要進(jìn)行雙向通信
// 服務(wù)端webpack重新編譯后,會(huì)向客戶(hù)端推送信息,告訴客戶(hù)端進(jìn)行更新
require('eventsource-polyfill')
// webpack熱重載客戶(hù)端
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')

// 客戶(hù)端收到更新動(dòng)作,執(zhí)行頁(yè)面刷新
hotClient.subscribe(function (event) {
 if (event.action === 'reload') {
  window.location.reload()
 }
})

build.js

執(zhí)行”npm run build”的時(shí)候首先執(zhí)行的是build/build.js文件,build.js主要完成下面幾件事:

  • loading動(dòng)畫(huà)

  • 刪除目標(biāo)文件夾

  • 執(zhí)行webpack構(gòu)建

  • 輸出信息

說(shuō)明: webpack編譯之后會(huì)輸出到配置里面指定的目標(biāo)文件夾;刪除目標(biāo)文件夾之后再創(chuàng)建是為了去除舊的內(nèi)容,以免產(chǎn)生不可預(yù)測(cè)的影響。

// 檢查NodeJS和npm的版本
require('./check-versions')()

process.env.NODE_ENV = 'production'

// ora,一個(gè)可以在終端顯示spinner的插件
var ora = require('ora')
// rm,用于刪除文件或文件夾的插件
var rm = require('rimraf')
var path = require('path')
// chalk,用于在控制臺(tái)輸出帶顏色字體的插件
var chalk = require('chalk')
var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prod.conf')

var spinner = ora('building for production...')
spinner.start() // 開(kāi)啟loading動(dòng)畫(huà)

// 首先將整個(gè)dist文件夾以及里面的內(nèi)容刪除,以免遺留舊的沒(méi)用的文件
// 刪除完成后才開(kāi)始webpack構(gòu)建打包
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
 if (err) throw err
 // 執(zhí)行webpack構(gòu)建打包,完成之后在終端輸出構(gòu)建完成的相關(guān)信息或者輸出報(bào)錯(cuò)信息并退出程序
 webpack(webpackConfig, function (err, stats) {
  spinner.stop()
  if (err) throw err
  process.stdout.write(stats.toString({
   colors: true,
   modules: false,
   children: false,
   chunks: false,
   chunkModules: false
  }) + '\n\n')

  if (stats.hasErrors()) {
   console.log(chalk.red(' Build failed with errors.\n'))
   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'
  ))
 })
})

webpack.prod.conf.js

構(gòu)建的時(shí)候用到的webpack配置來(lái)自webpack.prod.conf.js,該配置同樣是在webpack.base.conf基礎(chǔ)上的進(jìn)一步完善。主要完成下面幾件事情:

  • 合并基礎(chǔ)的webpack配置

  • 配置樣式文件的處理規(guī)則,styleLoaders

  • 配置webpack的輸出

  • 配置webpack插件

  • gzip模式下的webpack插件配置

  • webpack-bundle分析

說(shuō)明: webpack插件里面多了丑化壓縮代碼以及抽離css文件等插件。

var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
// copy-webpack-plugin,用于將static中的靜態(tài)文件復(fù)制到產(chǎn)品文件夾dist
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
// optimize-css-assets-webpack-plugin,用于優(yōu)化和最小化css資源
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

var env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
 module: {
  // 樣式文件的處理規(guī)則,對(duì)css/sass/scss等不同內(nèi)容使用相應(yīng)的styleLoaders
  // 由utils配置出各種類(lèi)型的預(yù)處理語(yǔ)言所需要使用的loader,例如sass需要使用sass-loader
  rules: utils.styleLoaders({
   sourceMap: config.build.productionSourceMap,
   extract: true
  })
 },
 // 是否使用source-map
 devtool: config.build.productionSourceMap ? '#source-map' : false,
 // webpack輸出路徑和命名規(guī)則
 output: {
  path: config.build.assetsRoot,
  filename: utils.assetsPath('js/[name].[chunkhash].js'),
  chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
 },
 // webpack插件
 plugins: [
  // http://vuejs.github.io/vue-loader/en/workflow/production.html
  new webpack.DefinePlugin({
   'process.env': env
  }),
  // 丑化壓縮JS代碼
  new webpack.optimize.UglifyJsPlugin({
   compress: {
    warnings: false
   },
   sourceMap: true
  }),
  // extract css into its own file
  // 將css提取到單獨(dú)的文件
  new ExtractTextPlugin({
   filename: utils.assetsPath('css/[name].[contenthash].css')
  }),
  // Compress extracted CSS. We are using this plugin so that possible
  // duplicated CSS from different components can be deduped.
  // 優(yōu)化、最小化css代碼,如果只簡(jiǎn)單使用extract-text-plugin可能會(huì)造成css重復(fù)
  // 具體原因可以看npm上面optimize-css-assets-webpack-plugin的介紹
  new OptimizeCSSPlugin({
   cssProcessorOptions: {
    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
  // 將產(chǎn)品文件的引用注入到index.html
  new HtmlWebpackPlugin({
   filename: config.build.index,
   template: 'index.html',
   inject: true,
   minify: {
    // 刪除index.html中的注釋
    removeComments: true,
    // 刪除index.html中的空格
    collapseWhitespace: true,
    // 刪除各種html標(biāo)簽屬性值的雙引號(hào)
    removeAttributeQuotes: true
    // more options:
    // https://github.com/kangax/html-minifier#options-quick-reference
   },
   // necessary to consistently work with multiple chunks via CommonsChunkPlugin
   // 注入依賴(lài)的時(shí)候按照依賴(lài)先后順序進(jìn)行注入,比如,需要先注入vendor.js,再注入app.js
   chunksSortMode: 'dependency'
  }),
  // keep module.id stable when vender modules does not change
  new webpack.HashedModuleIdsPlugin(),
  // split vendor js into its own file
  // 將所有從node_modules中引入的js提取到vendor.js,即抽取庫(kù)文件
  new webpack.optimize.CommonsChunkPlugin({
   name: 'vendor',
   minChunks: function (module, count) {
    // any required modules inside node_modules are extracted to 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
  // 從vendor中提取出manifest,原因如上
  new webpack.optimize.CommonsChunkPlugin({
   name: 'manifest',
   chunks: ['vendor']
  }),
  // copy custom static assets
  // 將static文件夾里面的靜態(tài)資源復(fù)制到dist/static
  new CopyWebpackPlugin([
   {
    from: path.resolve(__dirname, '../static'),
    to: config.build.assetsSubDirectory,
    ignore: ['.*']
   }
  ])
 ]
})

// 如果開(kāi)啟了產(chǎn)品gzip壓縮,則利用插件將構(gòu)建后的產(chǎn)品文件進(jìn)行壓縮
if (config.build.productionGzip) {
 // 一個(gè)用于壓縮的webpack插件
 var 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
  })
 )
}

// 如果啟動(dòng)了report,則通過(guò)插件給出webpack構(gòu)建打包后的產(chǎn)品文件分析報(bào)告
if (config.build.bundleAnalyzerReport) {
 var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
 webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig

check-versions.js

// chalk, 用于在控制臺(tái)輸出帶顏色字體的插件
var chalk = require('chalk')
// semver, 語(yǔ)義化版本檢查插件(The semantic version parser used by npm)
var semver = require('semver')
var packageConfig = require('../package.json')
// shelljs, 執(zhí)行Unix命令行的插件
var shell = require('shelljs')
// 開(kāi)辟子進(jìn)程執(zhí)行指令cmd并返回結(jié)果
function exec (cmd) {
 return require('child_process').execSync(cmd).toString().trim()
}

// node和npm版本需求
var versionRequirements = [
 {
  name: 'node',
  currentVersion: semver.clean(process.version),
  versionRequirement: packageConfig.engines.node
 }
]

if (shell.which('npm')) {
 versionRequirements.push({
  name: 'npm',
  currentVersion: exec('npm --version'),
  versionRequirement: packageConfig.engines.npm
 })
}

module.exports = function () {
 var warnings = []
 // 依次判斷版本是否符合要求
 for (var i = 0; i < versionRequirements.length; i++) {
  var mod = versionRequirements[i]
  if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
   warnings.push(mod.name + ': ' +
    chalk.red(mod.currentVersion) + ' should be ' +
    chalk.green(mod.versionRequirement)
   )
  }
 }
 // 如果有警告則將其輸出到控制臺(tái)
 if (warnings.length) {
  console.log('')
  console.log(chalk.yellow('To use this template, you must update following to modules:'))
  console.log()
  for (var i = 0; i < warnings.length; i++) {
   var warning = warnings[i]
   console.log(' ' + warning)
  }
  console.log()
  process.exit(1)
 }
}

config

index.js

config文件夾下最主要的文件就是index.js了,在這里面描述了開(kāi)發(fā)和構(gòu)建兩種環(huán)境下的配置,前面的build文件夾下也有不少文件引用了index.js里面的配置

// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')

module.exports = {
 // 構(gòu)建產(chǎn)品時(shí)使用的配置
 build: {
  // 環(huán)境變量
  env: require('./prod.env'),
  // html入口文件
  index: path.resolve(__dirname, '../dist/index.html'),
  // 產(chǎn)品文件的存放路徑
  assetsRoot: path.resolve(__dirname, '../dist'),
  // 二級(jí)目錄,存放靜態(tài)資源文件的目錄,位于dist文件夾下
  assetsSubDirectory: 'static',
  // 發(fā)布路徑,如果構(gòu)建后的產(chǎn)品文件有用于發(fā)布CDN或者放到其他域名的服務(wù)器,可以在這里進(jìn)行設(shè)置
  // 設(shè)置之后構(gòu)建的產(chǎn)品文件在注入到index.html中的時(shí)候就會(huì)帶上這里的發(fā)布路徑
  assetsPublicPath: '/',
  // 是否使用source-map
  productionSourceMap: true,
  // Gzip off by default as many popular static hosts such as
  // Surge or Netlify already gzip all static assets for you.
  // Before setting to `true`, make sure to:
  // npm install --save-dev compression-webpack-plugin
  // 是否開(kāi)啟gzip壓縮
  productionGzip: false,
  // gzip模式下需要壓縮的文件的擴(kuò)展名,設(shè)置js、css之后就只會(huì)對(duì)js和css文件進(jìn)行壓縮
  productionGzipExtensions: ['js', 'css'],
  // Run the build command with an extra argument to
  // View the bundle analyzer report after build finishes:
  // `npm run build --report`
  // Set to `true` or `false` to always turn it on or off
  // 是否展示webpack構(gòu)建打包之后的分析報(bào)告
  bundleAnalyzerReport: process.env.npm_config_report
 },
 // 開(kāi)發(fā)過(guò)程中使用的配置
 dev: {
  // 環(huán)境變量
  env: require('./dev.env'),
  // dev-server監(jiān)聽(tīng)的端口
  port: 8080,
  // 是否自動(dòng)打開(kāi)瀏覽器
  autoOpenBrowser: true,
  // 靜態(tài)資源文件夾
  assetsSubDirectory: 'static',
  // 發(fā)布路徑
  assetsPublicPath: '/',
  // 代理配置表,在這里可以配置特定的請(qǐng)求代理到對(duì)應(yīng)的API接口
  // 例如將'localhost:8080/api/xxx'代理到'www.example.com/api/xxx'
  proxyTable: {},
  // CSS Sourcemaps off by default because relative paths are "buggy"
  // with this option, according to the CSS-Loader README
  // (https://github.com/webpack/css-loader#sourcemaps)
  // In our experience, they generally work as expected,
  // just be aware of this issue when enabling this option.
  // 是否開(kāi)啟 cssSourceMap
  cssSourceMap: false
 }
}
'use strict'
const path = require('path')

module.exports = {
 dev: {
  // 開(kāi)發(fā)環(huán)境下面的配置
  assetsSubDirectory: 'static',//子目錄,一般存放css,js,image等文件
  assetsPublicPath: '/',//根目錄
  proxyTable: {},//可利用該屬性解決跨域的問(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ò),此處修改為./。如果是上線(xiàn)的文件,可根據(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
 }
}

prod.env.js

當(dāng)開(kāi)發(fā)是調(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"'
}

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"'
})

src

①、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),具體使用請(qǐng)點(diǎn)擊→vue-router傳送門(mén)

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

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

.babelrc

{
//制定轉(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"]//①
}

.postcessrc.js

.postcssrc.js文件其實(shí)是postcss-loader包的一個(gè)配置,在webpack的舊版本可以直接在webpack.config.js中配置,現(xiàn)版本中postcss的文檔示例獨(dú)立出.postcssrc.js,里面寫(xiě)進(jìn)去需要使用到的插件

module.exports = {
 "plugins": {
  "postcss-import": {},//①
  "postcss-url": {},//②
  "autoprefixer": {}//③
 }
}

package.json

package.json來(lái)制定名單,需要哪些npm包來(lái)參與到項(xiàng)目中來(lái),npm install命令根據(jù)這個(gè)配置文件增減來(lái)管理本地的安裝包

{
//從name到private都是package的配置信息,也就是我們?cè)谀_手架搭建中輸入的項(xiàng)目描述
 "name": "shop",//項(xiàng)目名稱(chēng):不能以.(點(diǎn))或者_(dá)(下劃線(xiàn))開(kāi)頭,不能包含大寫(xiě)字母,具有明確的的含義與現(xiàn)有項(xiàng)目名字不重復(fù)
 "version": "1.0.0",//項(xiàng)目版本號(hào):遵循“大版本.次要版本.小版本”
 "description": "A Vue.js project",//項(xiàng)目描述
 "author": "qietuniu",//作者名字
 "private": true,//是否私有
 //scripts中的子項(xiàng)即是我們?cè)诳刂婆_(tái)運(yùn)行的腳本的縮寫(xiě)
 "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"//使用node運(yùn)行build文件
 },
 //②dependencies(項(xiàng)目依賴(lài)庫(kù)):在安裝時(shí)使用--save則寫(xiě)入到dependencies
 "dependencies": {
  "vue": "^2.5.2",//vue.js
  "vue-router": "^3.0.1"//vue的路由插件
 },
 //和devDependencies(開(kāi)發(fā)依賴(lài)庫(kù)):在安裝時(shí)使用--save-dev將寫(xiě)入到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)編寫(xiě)的 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用法類(lèi)似
  "friendly-errors-webpack-plugin": "^1.6.1",//識(shí)別某些類(lèi)別的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上的依賴(lài)性,同時(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",//類(lèi)似于樣式加載程序,您可以在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)銷(xiāo)和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"//它將數(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"
 },
 //限制了瀏覽器或者客戶(hù)端需要什么版本才可運(yùn)行
 "browserslist": [
  "> 1%",
  "last 2 versions",
  "not ie <= 8"
 ]
}

注釋?zhuān)?/p>

①、webpack運(yùn)行時(shí)的配置文檔

②、devDependencies和dependencies的區(qū)別: devDependencies里面的插件只用于開(kāi)發(fā)環(huán)境,不用于生產(chǎn)環(huán)境,即輔助作用,打包的時(shí)候需要,打包完成就不需要了。而dependencies是需要發(fā)布到生產(chǎn)環(huán)境的,自始至終都在。比如wepack等只是在開(kāi)發(fā)中使用的包就寫(xiě)入到devDependencies,而像vue這種項(xiàng)目全程依賴(lài)的包要寫(xiě)入到dependencies

點(diǎn)這里→更多安裝包文檔搜索頁(yè)傳送門(mén)

③、file-loader和url-loader的區(qū)別:以圖片為例,file-loader可對(duì)圖片進(jìn)行壓縮,但是還是通過(guò)文件路徑進(jìn)行引入,當(dāng)http請(qǐng)求增多時(shí)會(huì)降低頁(yè)面性能,而url-loader通過(guò)設(shè)定limit參數(shù),小于limit字節(jié)的圖片會(huì)被轉(zhuǎn)成base64的文件,大于limit字節(jié)的將進(jìn)行圖片壓縮的操作。總而言之,url-loader是file-loader的上層封裝。

其他文件

①、.editorconfig:編輯器的配置文件

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

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

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

⑤、README.md:可此填寫(xiě)項(xiàng)目介紹

⑥、node_modules:根據(jù)package.json安裝時(shí)候生成的的依賴(lài)(安裝包)

感謝各位的閱讀,以上就是“vue-cli目錄結(jié)構(gòu)詳細(xì)講解”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)vue-cli目錄結(jié)構(gòu)詳細(xì)講解這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

vue
AI