国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

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

2019-11-19 12:17:30
字體:
供稿:網(wǎng)友

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

目錄

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

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

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

build

dev-server.js

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

  • 檢查node和npm的版本、引入相關(guān)插件和配置
  • webpack對源碼進(jìn)行編譯打包并返回compiler對象
  • 創(chuàng)建express服務(wù)器
  • 配置開發(fā)中間件(webpack-dev-middleware)和+ 熱重載中間件(webpack-hot-middleware)
  • 掛載代理服務(wù)和中間件
  • 配置靜態(tài)資源
  • 啟動服務(wù)器監(jiān)聽特定端口(8080)
  • 自動打開瀏覽器并打開特定網(wǎng)址(localhost:8080)

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

// 檢查NodeJS和npm的版本require('./check-versions')()// 獲取基本配置var config = require('../config')// 如果Node的環(huán)境變量中沒有設(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是一個可以調(diào)用默認(rèn)軟件打開網(wǎng)址、圖片、文件等內(nèi)容的插件// 這里用它來調(diào)用默認(rèn)瀏覽器打開dev-server監(jiān)聽的端口,例如:localhost:8080var opn = require('opn')var path = require('path')var express = require('express')var webpack = require('webpack')// http-proxy-middleware是一個express中間件,用于將http請求代理到其他服務(wù)器// 例:localhost:8080/api/xxx --> localhost:3000/api/xxx// 這里使用該插件可以將前端開發(fā)中涉及到的請求代理到提供服務(wù)的后臺服務(wù)器上,方便與服務(wù)器對接var proxyMiddleware = require('http-proxy-middleware')// 開發(fā)環(huán)境下的webpack配置var webpackConfig = require('./webpack.dev.conf')// dev-server 監(jiān)聽的端口,如果沒有在命令行傳入端口號,則使用config.dev.port設(shè)置的端口,例如8080var port = process.env.PORT || config.dev.port// 用于判斷是否要自動打開瀏覽器的布爾變量,當(dāng)配置文件中沒有設(shè)置自動打開瀏覽器的時候其值為 falsevar autoOpenBrowser = !!config.dev.autoOpenBrowser// HTTP代理表,指定規(guī)則,將某些API請求代理到相應(yīng)的服務(wù)器var proxyTable = config.dev.proxyTable// 創(chuàng)建express服務(wù)器var app = express()// webpack根據(jù)配置開始編譯打包源碼并返回compiler對象var compiler = webpack(webpackConfig)// webpack-dev-middleware將webpack編譯打包后得到的產(chǎn)品文件存放在內(nèi)存中而沒有寫進(jìn)磁盤// 將這個中間件掛到express上使用之后即可提供這些編譯后的產(chǎn)品文件服務(wù)var devMiddleware = require('webpack-dev-middleware')(compiler, { publicPath: webpackConfig.output.publicPath, // 設(shè)置訪問路徑為webpack配置中的output里面所對應(yīng)的路徑 quiet: true // 設(shè)置為true,使其不要在控制臺輸出日志})// webpack-hot-middleware,用于實現(xiàn)熱重載功能的中間件var hotMiddleware = require('webpack-hot-middleware')(compiler, { log: false, // 關(guān)閉控制臺的日志輸出 heartbeat: 2000 // 發(fā)送心跳包的頻率})// webpack(重新)編譯打包完成后并將js、css等文件inject到html文件之后,通過熱重載中間件強(qiáng)制頁面刷新compiler.plugin('compilation', function (compilation) { compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {  hotMiddleware.publish({ action: 'reload' })  cb() })})// 根據(jù) proxyTable 中的代理請求配置來設(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īng)用)// 例如使用vue-router并開啟了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'))// 訪問鏈接var uri = 'http://localhost:' + port// 創(chuàng)建promise,在應(yīng)用服務(wù)啟動之后resolve// 便于外部文件require了這個dev-server之后的代碼編寫var _resolvevar readyPromise = new Promise(resolve => { _resolve = resolve})console.log('> Starting dev server...')// webpack-dev-middleware等待webpack完成所有編譯打包之后輸出提示語到控制臺,表明服務(wù)正式啟動// 服務(wù)正式啟動才自動打開瀏覽器進(jìn)入頁面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()})// 啟動express服務(wù)器并監(jiān)聽相應(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配置來自build/webpack.dev.conf.js文件(測試環(huán)境下使用的是build/webpack.prod.conf.js,這里暫時不考慮測試環(huán)境)。而build/webpack.dev.conf.js中又引用了webpack.base.conf.js,所以這里我先分析webpack.base.conf.js。

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

  • 配置webpack編譯入口
  • 配置webpack輸出路徑和命名規(guī)則
  • 配置模塊resolve規(guī)則
  • 配置不同類型模塊的處理規(guī)則

說明: 這個配置里面只配置了.js、.vue、圖片、字體等幾類文件的處理規(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')// 獲取絕對路徑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'可以寫成 import Vue from 'vue'  alias: {   'vue$': 'vue/dist/vue.esm.js',   '@': resolve('src'),  },  symlinks: false }, // 不同類型模塊的處理規(guī)則 module: {  rules: [   {// 對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')    }   },   {// 對所有.vue文件使用vue-loader進(jìn)行編譯    test: //.vue$/,    loader: 'vue-loader',    options: vueLoaderConfig   },   {// 對src和test文件夾下的.js文件使用babel-loader將es6+的代碼轉(zhuǎn)成es5    test: //.js$/,    loader: 'babel-loader',    include: [resolve('src'), resolve('test')]   },   {// 對圖片資源文件使用url-loader    test: //.(png|jpe?g|gif|svg)(/?.*)?$/,    loader: 'url-loader',    options: {     // 小于10K的圖片轉(zhuǎn)成base64編碼的dataURL字符串寫到代碼中     limit: 10000,     // 其他的圖片轉(zhuǎn)移到靜態(tài)資源文件夾     name: utils.assetsPath('img/[name].[hash:7].[ext]')    }   },   {// 對多媒體資源文件使用url-loader    test: //.(mp4|webm|ogg|mp3|wav|flac|aac)(/?.*)?$/,    loader: 'url-loader',    options: {     // 小于10K的資源轉(zhuǎn)成base64編碼的dataURL字符串寫到代碼中     limit: 10000,     // 其他的資源轉(zhuǎn)移到靜態(tài)資源文件夾     name: utils.assetsPath('media/[name].[hash:7].[ext]')    }   },   {// 對字體資源文件使用url-loader    test: //.(woff2?|eot|ttf|otf)(/?.*)?$/,    loader: 'url-loader',    options: {     // 小于10K的資源轉(zhuǎn)成base64編碼的dataURL字符串寫到代碼中     limit: 10000,     // 其他的資源轉(zhuǎn)移到靜態(tài)資源文件夾     name: utils.assetsPath('fonts/[name].[hash:7].[ext]')    }   }  ] }}

webpack.dev.conf.js

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

  • 將webpack的熱重載客戶端代碼添加到每個entry對應(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是一個可以合并數(shù)組和對象的插件var merge = require('webpack-merge')var baseWebpackConfig = require('./webpack.base.conf')// html-webpack-plugin用于將webpack編譯打包后的產(chǎn)品文件注入到html模板中// 即自動在index.html里面加上<link>和<script>標(biāo)簽引用webpack打包后的文件var HtmlWebpackPlugin = require('html-webpack-plugin')// friendly-errors-webpack-plugin用于更友好地輸出webpack的警告、錯誤等信息var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')// add hot-reload related code to entry chunks// 給每個入口頁面(應(yīng)用)加上dev-client,用于跟dev-server的熱重載插件通信,實現(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ī)則,對css/sass/scss等不同內(nèi)容使用相應(yīng)的styleLoaders  // 由utils配置出各種類型的預(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  }),  // 開啟webpack熱更新功能  new webpack.HotModuleReplacementPlugin(),  // webpack編譯過程中出錯的時候跳過報錯階段,不會阻塞編譯,在編譯結(jié)束后報錯  new webpack.NoEmitOnErrorsPlugin(),  // 自動將依賴注入html模板,并輸出最終的html文件到目標(biāo)文件夾  new HtmlWebpackPlugin({   filename: 'index.html',   template: 'index.html',   inject: true  }),  new FriendlyErrorsPlugin() ]})

utils

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

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

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

const ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = {  module: {   rules: [    {     test: //.css$/, //主要用來處理css文件     use: ExtractTextPlugin.extract({      fallback: "style-loader", // fallback表示如果css文件沒有成功導(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({  // 是否打開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àn)webpack的熱更新。

/* eslint-disable */// 實現(xiàn)瀏覽器端的EventSource,用于跟服務(wù)器雙向通信// webpack熱重載客戶端跟dev-server上的熱重載插件之間需要進(jìn)行雙向通信// 服務(wù)端webpack重新編譯后,會向客戶端推送信息,告訴客戶端進(jìn)行更新require('eventsource-polyfill')// webpack熱重載客戶端var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')// 客戶端收到更新動作,執(zhí)行頁面刷新hotClient.subscribe(function (event) { if (event.action === 'reload') {  window.location.reload() }})

build.js

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

  • loading動畫
  • 刪除目標(biāo)文件夾
  • 執(zhí)行webpack構(gòu)建
  • 輸出信息

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

// 檢查NodeJS和npm的版本require('./check-versions')()process.env.NODE_ENV = 'production'// ora,一個可以在終端顯示spinner的插件var ora = require('ora')// rm,用于刪除文件或文件夾的插件var rm = require('rimraf')var path = require('path')// chalk,用于在控制臺輸出帶顏色字體的插件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() // 開啟loading動畫// 首先將整個dist文件夾以及里面的內(nè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)信息或者輸出報錯信息并退出程序 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)建的時候用到的webpack配置來自webpack.prod.conf.js,該配置同樣是在webpack.base.conf基礎(chǔ)上的進(jìn)一步完善。主要完成下面幾件事情:

  • 合并基礎(chǔ)的webpack配置
  • 配置樣式文件的處理規(guī)則,styleLoaders
  • 配置webpack的輸出
  • 配置webpack插件
  • gzip模式下的webpack插件配置
  • webpack-bundle分析

說明: 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)品文件夾distvar 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.envvar webpackConfig = merge(baseWebpackConfig, { module: {  // 樣式文件的處理規(guī)則,對css/sass/scss等不同內(nèi)容使用相應(yīng)的styleLoaders  // 由utils配置出各種類型的預(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代碼,如果只簡單使用extract-text-plugin可能會造成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)簽屬性值的雙引號    removeAttributeQuotes: true    // more options:    // https://github.com/kangax/html-minifier#options-quick-reference   },   // necessary to consistently work with multiple chunks via CommonsChunkPlugin   // 注入依賴的時候按照依賴先后順序進(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,即抽取庫文件  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: ['.*']   }  ]) ]})// 如果開啟了產(chǎn)品gzip壓縮,則利用插件將構(gòu)建后的產(chǎn)品文件進(jìn)行壓縮if (config.build.productionGzip) { // 一個用于壓縮的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  }) )}// 如果啟動了report,則通過插件給出webpack構(gòu)建打包后的產(chǎn)品文件分析報告if (config.build.bundleAnalyzerReport) { var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin())}module.exports = webpackConfig

check-versions.js

// chalk, 用于在控制臺輸出帶顏色字體的插件var chalk = require('chalk')// semver, 語義化版本檢查插件(The semantic version parser used by npm)var semver = require('semver')var packageConfig = require('../package.json')// shelljs, 執(zhí)行Unix命令行的插件var shell = require('shelljs')// 開辟子進(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)   )  } } // 如果有警告則將其輸出到控制臺 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了,在這里面描述了開發(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)品時使用的配置 build: {  // 環(huán)境變量  env: require('./prod.env'),  // html入口文件  index: path.resolve(__dirname, '../dist/index.html'),  // 產(chǎn)品文件的存放路徑  assetsRoot: path.resolve(__dirname, '../dist'),  // 二級目錄,存放靜態(tài)資源文件的目錄,位于dist文件夾下  assetsSubDirectory: 'static',  // 發(fā)布路徑,如果構(gòu)建后的產(chǎn)品文件有用于發(fā)布CDN或者放到其他域名的服務(wù)器,可以在這里進(jìn)行設(shè)置  // 設(shè)置之后構(gòu)建的產(chǎn)品文件在注入到index.html中的時候就會帶上這里的發(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  // 是否開啟gzip壓縮  productionGzip: false,  // gzip模式下需要壓縮的文件的擴(kuò)展名,設(shè)置js、css之后就只會對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)建打包之后的分析報告  bundleAnalyzerReport: process.env.npm_config_report }, // 開發(fā)過程中使用的配置 dev: {  // 環(huán)境變量  env: require('./dev.env'),  // dev-server監(jiān)聽的端口  port: 8080,  // 是否自動打開瀏覽器  autoOpenBrowser: true,  // 靜態(tài)資源文件夾  assetsSubDirectory: 'static',  // 發(fā)布路徑  assetsPublicPath: '/',  // 代理配置表,在這里可以配置特定的請求代理到對應(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.  // 是否開啟 cssSourceMap  cssSourceMap: false }}'use strict'const path = require('path')module.exports = { dev: {  // 開發(fā)環(huán)境下面的配置  assetsSubDirectory: 'static',//子目錄,一般存放css,js,image等文件  assetsPublicPath: '/',//根目錄  proxyTable: {},//可利用該屬性解決跨域的問題  host: 'localhost', // 地址  port: 8080, //端口號設(shè)置,端口號占用出現(xiàn)問題可在此處修改  autoOpenBrowser: false,//是否在編譯(輸入命令行npm run dev)后打開http://localhost:8080/頁面,以前配置為true,近些版本改為false,個人偏向習(xí)慣自動打開頁面  errorOverlay: true,//瀏覽器錯誤提示  notifyOnErrors: true,//跨平臺錯誤提示  poll: false, //使用文件系統(tǒng)(file system)獲取文件改動的通知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)生錯誤時直接定位到未壓縮前的位置,將大大的方便我們調(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后打開文件會報錯,此處修改為./。如果是上線的文件,可根據(jù)文件存放位置進(jìn)行更改路徑  productionSourceMap: true,  devtool: '#source-map',//①  //unit的gzip命令用來壓縮文件,gzip模式下需要壓縮的文件的擴(kuò)展名有js和css  productionGzip: false,  productionGzipExtensions: ['js', 'css'],  bundleAnalyzerReport: process.env.npm_config_report }}

prod.env.js

當(dāng)開發(fā)是調(diào)取dev.env.js的開發(fā)環(huán)境配置,發(fā)布時調(diào)用prod.env.js的生產(chǎn)環(huán)境配置

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

dev.env.js

config內(nèi)的文件其實是服務(wù)于build的,大部分是定義一個變量export出去。

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

src

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

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

③、router文件夾:該文件夾下有一個叫index.js文件,用于實現(xiàn)頁面的路由跳轉(zhuǎn),具體使用請點擊→vue-router傳送門

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

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

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

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

package.json

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

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

注釋:

①、點這里→webpack運(yùn)行時的配置文檔傳送門

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

點這里→更多安裝包文檔搜索頁傳送門

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

點這里→file-loader 和 url-loader詳解

點這里→file-loader文檔傳送門

點這里→url-loader文檔傳送門

其他文件

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

②、.gitignore:忽略git提交的一個文件,配置之后提交時將不會加載忽略的文件

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

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

⑤、README.md:可此填寫項目介紹

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

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 永德县| 香河县| 垦利县| 庆元县| 齐河县| 大兴区| 岳池县| 四平市| 和平县| 当阳市| 丹棱县| 通海县| 德惠市| 湖口县| 佛冈县| 沾化县| 衢州市| 淮北市| 林口县| 柯坪县| 永城市| 新宁县| 新田县| 麦盖提县| 长兴县| 岳阳县| 萨迦县| 汽车| 新密市| 蓝山县| 信丰县| 星子县| 洪湖市| 六安市| 广饶县| 贵定县| 五常市| 石屏县| 吉林市| 仪征市| 壶关县|