vue-cli分析-webpack.dev.config.js

本系列文章主要講下vue的webpack腳手架的來龍去脈,逐行分析其操做。若是寫的有問題請務必指出!若是以爲寫的還不錯點個贊就是對我最大的鼓勵了,謝謝!javascript

架構說明

當使用vue-cli腳手架生成項目後,項目架構與其做用大概是這樣的:css

  • build負責針對不一樣編譯環境,webpack採用哪些配置,摒棄哪些機制相關
  • config是build編譯文件的另外擴展,把須要用到的配置提取出來,讓配置更模塊化
  • src就是寫代碼的地方了
  • static靜態資源文件夾,注意當打包時這個文件夾下的文件都不會被打包哦
  • package.json項目所採用的類庫與命令都寫在這了,閱讀代碼首先看這個文件了

package.json

首先上面提到,閱讀代碼首先須要看這個文件,由於當你在命令行敲下第一句命令html

npm run dev
複製代碼

webpack就會找到package.json文件中的script屬性並依次分析命令,可見,這句命令相應的會執行前端

webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
複製代碼

這句話的意思是vue

webpack,在開發環境下,請你幫我運行webpack-dev-server插件,而且實時編譯文件,另外,我還需有度條可見。最後,你幫我編譯build文件夾下的webpack.dev.conf.js文件吧java

webpack.dev.conf.js

前文說了那麼多,都是爲了給本文的主角(build/webpack.dev.conf.js)作鋪墊,從這個文件名就不難看出,此文件是webpack在開發環境下的項目的配置文件,下面來看看這個文件到底作了什麼webpack

在文件第71-95行git

module.exports = new Promise((resolve, reject) => {
  portfinder.basePort = process.env.PORT || config.dev.port
  portfinder.getPort((err, port) => {
    if (err) {
      reject(err)
    } else {
      // publish the new Port, necessary for e2e tests
      process.env.PORT = port
      // add port to devServer config
      devWebpackConfig.devServer.port = port

      // Add FriendlyErrorsPlugin
      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.dev.conf.js文件對外暴露出了一個promise對象,從函數裏看出,首先是引入了portfinder這個庫,這是一個關於端口相關的一個庫,其中指定了端口爲項目啓動的端口github

portfinder.basePort = process.env.PORT || config.dev.port
複製代碼

process.env同config.dev後面會講到web

接着看代碼,portfinder又執行了getPort方法,當獲取到當前運行端口後,給process.env設置了port屬性

process.env.PORT = port
複製代碼

這裏這樣設置是由於e2e單元測試須要用到的,在這裏也不敘述了,有興趣能夠去查閱相關資料

接着往下看,promise返回了一個對象devWebpackConfig,這個對象就是webpack.dev.conf.js的核心了,往上翻代碼看他定義了什麼

const devWebpackConfig = merge(baseWebpackConfig, {
  module: {
    rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
  },
  // cheap-module-eval-source-map is faster for development
  devtool: config.dev.devtool,

  // these devServer options should be customized in /config/index.js
  devServer: {
    clientLogLevel: 'warning',
    historyApiFallback: {
      rewrites: [
        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
      ],
    },
    hot: true,
    contentBase: false, // since we use CopyWebpackPlugin.
    compress: true,
    host: HOST || config.dev.host,
    port: PORT || config.dev.port,
    open: config.dev.autoOpenBrowser,
    overlay: config.dev.errorOverlay
      ? { warnings: false, errors: true }
      : false,
    publicPath: config.dev.assetsPublicPath,
    proxy: config.dev.proxyTable,
    quiet: true, // necessary for FriendlyErrorsPlugin
    watchOptions: {
      poll: config.dev.poll,
    }
  }
})
複製代碼

首先說明的是,在開發環境和生產環境,webpack的配置是有很大不一樣的。好比在開發環境,咱們須要快速的開發,因此咱們可能須要一些實時加載和熱更新等功能。可是在開發環境,咱們不須要這些,咱們須要更小的bundle,更輕量的source map,以及更輕量的資源,以改善加載時間。所以,爲給個環境配置不一樣的webpack配置是必作的一步

雖然咱們會爲環境作區分,可是基於不重複原則,vue-cli爲兩個環境公用的配置整合到了(build/webpack.base.conf.js)文件中。而後利用webpack-merge插件將配置整合在一塊兒

webpack.base.conf.js文件在這裏不作敘述了,具體配置你們能夠翻閱文件查看

在文件第17-19行

module: {
  rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
}
複製代碼

這裏默認添加了一些匹配規則(css,postcss,less,sass,scss,stylus,styl),當webpack遇到這些文件時會採用相關的loader進行處理,可是這裏沒有默認配置typescript的loader,想要使用ts的可使用ts-loader進行處理哦

接着看文件第21行

devtool: config.dev.devtool,
複製代碼

當 webpack 打包源代碼時,可能會很難追蹤到錯誤和警告在源代碼中的原始位置。例如,若是將三個源文件(a.js, b.js 和 c.js)打包到一個 bundle(bundle.js)中,而其中一個源文件包含一個錯誤,那麼堆棧跟蹤就會簡單地指向到 bundle.js。這並一般沒有太多幫助,由於你可能須要準確地知道錯誤來自於哪一個源文件。

webpack一共提供了13中構建文件的模式,不一樣的值會明顯影響到構建和從新構建的速度。在開發環境webpack是推薦使用cheap-module-eval-source-map模式的,而在生產環境使用cheap-source-map模式會更適合。webpack 倉庫中包含一個 顯示全部 devtool 變體效果的示例。這些例子或許會有助於你理解這些差別之處,在這裏也不作多敘述了

當你敲下那句熟悉的npm run dev後,瀏覽器就會彈出一個窗口,路徑赫然寫着localhost:8080。這是由於vue-cli在開發模式下,採用了webpack-dev-server插件,這個插件提供了一個簡單的web服務器,而且可以實時加載,大大提升了前端開發速度

看文件第24-46行

devServer: {
    clientLogLevel: 'warning',
    historyApiFallback: {
      rewrites: [
        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
      ],
    },
    hot: true,
    contentBase: false, // since we use CopyWebpackPlugin.
    compress: true,
    host: HOST || config.dev.host,
    port: PORT || config.dev.port,
    open: config.dev.autoOpenBrowser,
    overlay: config.dev.errorOverlay
      ? { warnings: false, errors: true }
      : false,
    publicPath: config.dev.assetsPublicPath,
    proxy: config.dev.proxyTable,
    quiet: true, // necessary for FriendlyErrorsPlugin
    watchOptions: {
      poll: config.dev.poll,
    }
  }
複製代碼

這裏主要講下devServer.proxy這個屬性

devServer採用了一個很是強大的http請求中間件http-proxy-middleware。此中間件能對http請求作中間轉發處理,而且可以很好的解決了開發中跨域的問題

若是你有單獨的後端開發服務器 API,而且但願在同域名下發送 API 請求 ,那麼代理某些 URL 會頗有用

在 localhost:3000 上有後端服務的話,你能夠在config/index.js文件下proxyTable屬性這樣設置:

proxyTable: {
  "/api": "http://localhost:3000"
}
複製代碼

如今請求到 /api 如今會被代理到請求 http://localhost:3000/api

接着看文件第47-69行

plugins: [
  new webpack.DefinePlugin({
    'process.env': require('../config/dev.env')
  }),
  new webpack.HotModuleReplacementPlugin(),
  new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
  new webpack.NoEmitOnErrorsPlugin(),
  // https://github.com/ampedandwired/html-webpack-plugin
  new HtmlWebpackPlugin({
    filename: 'index.html',
    template: 'index.html',
    inject: true
  }),
  // copy custom static assets
  new CopyWebpackPlugin([
    {
      from: path.resolve(__dirname, '../static'),
      to: config.dev.assetsSubDirectory,
      ignore: ['.*']
    }
  ])
]
複製代碼

webpack的插件機制能讓你使用不少自帶的和第三方的插件

這裏使用到了:

  • DefinePlugin:容許在編譯時(compile time)配置的全局常量
  • HotModuleReplacementPlugin:啓用模塊熱替換(Enable Hot Module Replacement - HMR)
  • NamedModulesPlugin:當開啓 HMR 的時候使用該插件會顯示模塊的相對路徑,建議用於開發環境
  • HtmlWebpackPlugin:HtmlWebpackPlugin簡化了HTML文件的建立,以便爲你的webpack包提供服務。這對於在文件名中包含每次會隨着編譯而發生變化哈希的 webpack bundle 尤爲有用。 你可讓插件爲你生成一個HTML文件,使用lodash模板提供你本身的模板,或使用你本身的loader

以上就是webpack.dev.config.js文件所作的事情,欲知後事如何,請聽下回分解。

相關文章
相關標籤/搜索