vue-cli#2.0 webpack 配置分析

目錄結構:

├── README.md

├── build

│ ├── build.js

│ ├── check-versions.js

│ ├── dev-client.js

│ ├── dev-server.js

│ ├── utils.js

│ ├── webpack.base.conf.js

│ ├── webpack.dev.conf.js

│ └── webpack.prod.conf.js

├── config

│ ├── dev.env.js

│ ├── index.js

│ └── prod.env.js

├── index.html

├── package.json

├── src

│ ├── App.vue

│ ├── assets

│ │ └── logo.png

│ ├── components

│ │ └── Hello.vue

│ └── main.js

└── static

入口文件:package.json

"scripts": {

"dev": "node build/dev-server.js",

"build": "node build/build.js",

?"lint": "eslint --ext .js,.vue src"?

}

當我們執行 npm run dev / npm run build 時運行的的是 node build/dev-sev-server.js 或 node build/build.js

dev-server.js

  // 檢查 Node 和 npm 版本

require('./check-versions')()

  // 獲取 config/index.js 的默認配置

var?config = require('../config')

  // 如果Node 的環境無法判斷當前是dev/product 環境

  // 使用 config.dev.env.NODE_ENV 作為當前的環境

if(!process.env.NODE_ENV)process.env.NODE_ENV=JSON.parse(confi g.dev.env.NODE_ENV)

  // 使用nodeJS 自帶的路徑工具

var?path = require('path')

  // 使用 express

var?express = require('express')

  // ?使用webpack

var?webpack = require('webpack')

  // 一個可以強制打卡瀏覽器并挑戰到指定url 的插件

var?opn = require('opn')

  // 使用proxyTable

var?proxyMiddleware = require('http-proxy-middleware')

  // 使用 dev 環境的webpack 配置

var?webpackConfig = require('./webpack.dev.conf')

  // 如果沒有指定運行端口,使用config.dev.port 作為運行端口

var?port = process.env.PORT || config.dev.port?

  // 使用config.dev.proxyTable 的配置作為proxyTable 的代理配置

var?proxyTable = config.dev.proxyTable

  // 使用 express 啟動一個服務

var?app = express()

  // 啟動webpack 進行編譯

var?compiler = webpack(webpackConfig)

  // 啟動 webpack-dev-middleware, 將 編譯后的文件暫存到內存中

var?devMiddleware =require('webpack-dev-middleware')(compiler, { publicPath: webpackConfig.output.publicPath, stats: { colors: true, chunks: false?} })

  // 啟動 webpack-hot-middleware, 也就是我們常說的Hot-reload

var?hotMiddleware = require('webpack-hot-middleware')(compiler) compiler.plugin('compilation', function?(compilation) { compilation.plugin('html-webpack-plugin-after-emit', function? (data, cb) { hotMiddleware.publish({ action: 'reload'?}) cb() }) })

  // 將proxyTable 中的請求配置掛在啟動的express 服務上

Object.keys(proxyTable).forEach(function?(context) { var?options = proxyTable[context] if?(typeof?options === 'string') { options = { target: options } } app.use(proxyMiddleware(context, options)) })

  // 使用 connect-hisory-api-fallback 匹配資源,如果不匹配就可以重 定向到指定地址

app.use(require('connect-history-api-fallback')())

  // 將暫存到內存中的 wepack 編譯后的文件掛載帶express 服務上

app.use(devMiddleware)

  // 將Hot-reload 掛載到 express 服務上

app.use(hotMiddleware)

  //拼接到 static 文件夾的靜態資源路徑

var?staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)

  // 為靜態資源提供相應服務

app.use(staticPath, express.static('./static'))

  // 讓我們這個express 服務監聽port 的請求,并且將此服務作為 dev-server.js的接口暴露

module.exports = app.listen(port, function?(err) { if?(err) { console.log(err) return?} var?uri = 'http://localhost:'?+ port console.log('Listening at '?+ uri + '\n')

  // 如果不是測試環境,自動打開瀏覽器并跳到我們的開發地址

if?(process.env.NODE_ENV !== 'testing') { opn(uri) }

Webpack.dev.conf.js

    // 同樣的使用了config/index.js

var?config = require('../config')

    // 使用webpack

var?webpack = require('webpack')

    //使用webpack 配置合并插件

var?merge = require('webpack-merge')

    // 使用一些小工具

var?utils = require('./utils')

    // 加載webpack.base.conf

var?baseWebpackConfig = require('./webpack.base.conf')

    // 使用 html-webpack-plugin 插件,這個插件可以幫助我們自動生成html,并注入 .html 文件中

var?HtmlWebpackPlugin = require('html-webpack-plugin')

    // 將 Hol-reload 相對路徑添加到webpack.base.conf 的 對應 entry 前

Object.keys(baseWebpackConfig.entry).forEach(function(name) {baseWebpackConfig.entry[name]=['./build/dev-client'].concat(baseWebpackConfi g.entry[name]) })

    //將我們 webpack.dev.conf.js 的配置和webpack.base.conf.js 的配置合并

module.exports = merge(baseWebpackConfig, { module: {

    // 使用 styleLoaders?

loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) },

    // 使用 #eval-source-mao 模式作為開發工具,

module.exports = merge(baseWebpackConfig, {

?module: {

      ?// 使用 styleLoaders?

  loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) },

      // eval-source-map is faster for development?// 使用 #eval-source-map 模式作為開發工具,此配置可參考 DDFE 往期文章詳細了解?

  devtool: '#eval-source-map', plugins: [

      // definePlugin 接收字符串插入到代碼當中, 所以你需要的話可以寫上 JS 的字符串?new?webpack.DefinePlugin({ 'process.env': config.dev.env })

  new?webpack.optimize.OccurenceOrderPlugin(),

?    // HotModule 插件在頁面進行變更的時候只會重回對應的頁面模塊,不會重繪整個 html 文件?

  new?webpack.HotModuleReplacementPlugin(),

    // 使用了 NoErrorsPlugin 后頁面中的報錯不會阻塞,但是會在編譯結束后報錯?

  new?webpack.NoErrorsPlugin(),

    // 將 index.html 作為入口,注入 html 代碼后生成 index.html文件?

  new?HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true?}) ] })

Webpack.base.conf.js

?

    // 使用 nodejs 自帶的文件路徑

var?path = require('path')

    // 引入 config/index.js

var?config = require('../config')

    // 引入一些小工具

var?utils = require('./utils')

    // 拼接我們的工作區路徑為一個絕對路徑

var?projectRoot = path.resolve(__dirname, '../')

    // 將nodeJs 作為我們的編譯環境

var?env = process.env.NODE_ENV

    // 將在dev 環境下開啟cssSourceMap 在config/index.js 中可配置

var?cssSourceMapDev = (env === 'development'?&& config.dev.cssSourceMap)

    // 是否在production 環境下開啟 ssSourceMap 在config/index.js 中可配置

var?cssSourceMapProd = (env === 'production'?&& config.build.productionSourceMap)

    // 最終是否使用cssSourceMap

var?useCssSourceMap = cssSourceMapDev || cssSourceMapProd

module.exports = {

  entry: {

      // 編譯文件入口

    app: './src/main.js'?

??????},

  output: {

      // 編譯輸出的根路徑

?????  path: config.build.assetsRoot,

      // 正式發布環境下編譯輸出的發布路徑

? ?  publicPath:process.env.NODE_ENV==='production'? config.build.assetsPublicPath : config.dev.assetsPublicPath,

      // 編譯輸出的文件名

?  ?filename: '[name].js'?

 },

 resolve: {

      // 自動補全的擴展名

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

      // 不進行自動補全貨處理的文件或者文件夾

  fallback: [path.join(__dirname, '../node_modules')],

    alias: {

        // 默認路徑帶了 例如 import vue for ‘vue’或自動到’vue/dist/vue.common.js’

?     'vue': 'vue/dist/vue.common.js',

    ?'src': path.resolve(__dirname, '../src'),

    ?'assets':path.resolve(__dirname,'../src/assets'),

    ?'components': path.resolve(__dirname, '../src/components')

    }

?   },

    resolveLoader: { fallback: [path.join(__dirname, '../node_modules')]

  ?},

  module: {

      preLoaders: [

          // 預處理的文件及使用的 loader?

        { test: /\.vue$/, loader: 'eslint', include: projectRoot, exclude: /node_modules/?}, { test: /\.js$/, loader: 'eslint', include: projectRoot, exclude: /node_modules/?} ], loaders: [

          // ?需要處理的文件及使用的loader

        { test: /\.vue$/, loader: 'vue'?},

        { test: /\.js$/, loader: 'babel', include: projectRoot, exclude: /node_modules/?}, { test: /\.json$/, loader: 'json'?},

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

        loader:'url',

          query: {

            ?limit: 10000,

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

          }

      },

    ?{

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

      loader:'url',

      query:{limit:10000,

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

    }

  ?}

  ]

},

eslint: {

      // eslint 代碼檢查配置工具?

    formatter: require('eslint-friendly-formatter')

  },

vue: {

      // ?.vue 文件配置 loader 及工具

    loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),

    postcss: [ require('autoprefixer')({ browsers: ['last 2 versions'})]

  }

}

config/index.js

?

    // 使用 nodejs 自帶的文件路徑

?

var?path = require('path')

?

module.exports = {

?

  build: {

?

      // 使用 confi/prod.env.js 中定義的編譯環境

?

    env: require('./prod.env'),

?

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

?

      // 編譯出的靜態資源根路徑

?

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

?

      // 編譯輸出的二級目錄

?

    assetsSubDirectory: 'static',

?

      // 編譯發布上線路徑的根目錄,可配置為資源服務器域名CDN 域名

?

    assetsPublicPath: '/',

?

      // 是否開啟 cssSourceMap

?

    productionSourceMap: true,

?

      // 是否開啟 gzip

?

    productionGzip: false,

?

      // 需要使用gzip 壓縮的文件擴展名

?

    productionGzipExtensions: ['js', 'css']

?

  },

?

    // dev 環境

?

dev: {

?

    // ?使用 config/dev.env.js 中定義的編譯環境

?

? env: require('./dev.env'),

?

    // 運行測試網頁的端口

?

 port: 8080,

?

    // 編譯輸出的二級目錄

?

 assetsSubDirectory: 'static',

?

    // ?編譯發布上線的根目錄,可以配置為資源服務器域名或CDN 域名

?

? assetsPublicPath: '/',

?

    // 需要 proxyTable 代理的接口

?

? proxyTable: {},

?

    // 是否需要開啟 cssSourceMap

?

  cssSourceMap: false?

?

}}

Build.js

    // 檢查node 和npm 版本

require('./check-versions')()

    // 使用了shelljs 插件,可以讓我們在node 環境的js 中使用 shell

require('shelljs/global')

env.NODE_ENV = 'production'

    // 使用 nodejs 自帶的文件路徑

var?path = require('path')

    // 加載config.js

var?config = require('../config')

    // 一個很好看的loading 插件

var?ora = require('ora') ?

    // 加載 webpack

var?webpack = require('webpack')

    // 加載 webpack.prod.conf

var?webpackConfig = require('./webpack.prod.conf')

    // 輸出提示信息~提示用戶請在http 服務下查看頁面,否則為空白頁

console.log(

  ' Tip:\n'?+

  ' Built files are meant to be served over an HTTP server.\n'?+

  ' Opening index.html over file:// won\'t work.\n'?

)

    // 使用 ora 打印出loading + log

var?spinner = ora('building for production...')

    // 開始loading 動畫

spinner.start()

    // 拼接編譯輸出文件路徑

var?assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory)

    // ?刪除這個文件(遞歸刪除)

rm('-rf', assetsPath)

    // ?創建此文件夾

mkdir('-p', assetsPath)

    // 復制 static 文件夾到我們的編譯輸出目錄

cp('-R', 'static/*', assetsPath)

    // 開始 webpack 的編譯

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

})

Webpack.prod.conf.js

?

      // 使用 nodejs 自帶的文件路徑

?

    var?path = require('path')

?

      // 加載 confi.index.js

?

    var?config = require('../config')

?

      // 使用一些工具

?

    var?utils = require('./utils')

?

      // 加載 webpack

?

    var?webpack = require('webpack')

?

      // 加載webpack 配置合并工具

?

    var?merge = require('webpack-merge')

?

      // 加載 webpack.base.conf.js

?

    var?baseWebpackConfig = require('./webpack.base.conf')

?

      // 一個webpack 擴展,可以提取一些代碼并且將他們和文件分離開

?

      // 如果我們想將webpack 打包成一個文件 css js 分離開,那我們需要這個插件

?

    var?ExtractTextPlugin = require('extract-text-webpack-plugin')

?

      //一個可以插入 html 并且創建新的 .html 文件的插件

?

    var?HtmlWebpackPlugin = require('html-webpack-plugin')

?

    var?env = config.build.env

?

     // 合并 webpack.base.conf.js

?

    var?webpackConfig = merge(baseWebpackConfig, {

?

      module: {

?

          // 使用 loader

?

        loaders: utils.styleLoaders({

?

          sourceMap: config.build.productionSourceMap, extract: true?})

?

      ?},

?

        // 是否使用 #source-map 開發工具

?

      devtool: config.build.productionSourceMap ? '#source-map'?: false, output: {

?

        // 編譯輸出項目

?

      path: config.build.assetsRoot,

?

        // 編譯輸出文件名

?

        // 我們可以在hash 后加 :6 決定使用幾位 hash 值

?

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

?

        // 沒有指定輸出名的文件輸出的文件名

?

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

?

        vue: {

?

          // ?編譯 .vue 文件的使用的loader

?

        loaders: utils.cssLoaders({

?

          sourceMap: config.build.productionSourceMap, extract: true?}) }, plugins: [

?

            // 使用的插件 ?definePlugin 接收字符串插入到代碼當中,所以你需要的話寫上

?

          new?webpack.DefinePlugin({ 'process.env': env }),

?

            // 壓縮js (同樣可以壓縮css)

?

          new?webpack.optimize.UglifyJsPlugin({ compress: { warnings: false?} }),

?

          new?webpack.optimize.OccurrenceOrderPlugin(),

?

            // 將css 文件分離出來

?

          new?ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),

?

            // 輸入 輸出的 .html 文件

?

          new?HtmlWebpackPlugin({ filename: config.build.index,template: 'index.html',

?

            // 是否注入 html

?

          inject: true,

?

    // 壓縮的方式

?

      minify: {

?

          removeComments: true,

?

          collapseWhitespace: true,

?

          removeAttributeQuotes: true?

?

          chunksSortMode: 'dependency'?}),

?

              // 沒有指定輸出文件名的文件輸出的靜態文件名

?

       new?webpack.optimize.CommonsChunkPlugin({

?

          name: 'vendor',

?

          minChunks: function?(module, count) {

?

      return(

?

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

?

        module.resource.indexOf(

?

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

?

?        ) === 0?) }

?

      }),

?

      // 沒有指定輸出文件名稱的文件輸出的靜態文靜名

?

    new?webpack.optimize.CommonsChunkPlugin({

?

        name: 'manifest',

?

        chunks: ['vendor'] })

?

?      ]

?

?    })

?

      // 開啟 gzip 的情況下使用下方的配置

?

   ?if?(config.build.productionGzip) {

?

      // 加載 compression-webpack-plugin 插件?

?

  var?CompressionWebpackPlugin = require('compression-webpack-plugin')

?

      // 向webpackconfig.plugins中加入下方的插件?

?

  var reProductionGzipExtensions='\\.('+ config.build.productionGzipExtensions.join('|') + '$)'?

?

    webpackConfig.plugins.push(

?

        // 使用 compression-webpack-plugin 插件進行壓縮?

?

    new?CompressionWebpackPlugin({

?

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

?

?        algorithm: 'gzip',

?

?        test: new?RegExp(reProductionGzipExtensions),

?

        // 注:此處因有代碼格式化的bug,與源碼有差異

?

      ?  threshold: 10240, minRatio: 0.8?})

?

    ) }

?

    module.exports = webpackConfig

?本文參考https://gold.xitu.io/post/584e48b2ac502e006c74a120 ?僅學習交流

轉載于:https://www.cnblogs.com/nmxs/p/6206306.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/259896.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259896.shtml
英文地址,請注明出處:http://en.pswp.cn/news/259896.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

initWithNibName與viewDidLoad的執行關系以及順序

一個ViewController,一般通過init或initWithNibName來加載。二者沒有什么不同,init最終還是要調用initWithNibName方法(除非這個ViewController沒有nib文件)。 我們經常在initWithNibName方法中初始化視圖,變量或者其他…

120xa正反轉參數_你知道變頻器的“正反轉死區時間”嗎?它的“停機方式”有幾種?...

若你我之間有緣,關注作者又何妨?兩情若是久長時,又豈在朝朝暮暮。大家好!我是江郎,一個踏踏實實的維修工。本期我們仍然探討兩個問題,如標題所述,#變頻器#“死區時間”和“停機方式”&#xff0…

【轉】游戲編程中的人工智能技術--神經網絡

原文:http://blog.csdn.net/ecitnet/article/details/1799444 游戲編程中的人工智能技術.>. (連載之一)用平常語言介紹神經網絡(Neural Networks in Plain English)因為我們沒有很好了解大腦,我們經常試圖用最新的技術作為一種模型來解釋它。在我童年…

w8計算機配置要求,win8系統最低配置要求有哪些|win8系統是否有最低配置要求-系統城...

2013-10-17 17:08:08  瀏覽量:5753小編這里要為大家帶來的是win8系統最低配置要求和部分安裝截圖,很多用戶想要將自己的電腦裝上win8,但也不是每一臺電腦都可以安裝win8系統的,為了避免一些低配置的用戶安裝了win8之后卻無法運行…

Session 丟失問題

項目從.NET Framework3.5 升級 .NET Framework4.0后,如果用Response.Redirect();進行頁面的跳轉,服務端會把這個跳轉動作當作是一個“新”的用戶去訪問網頁。 而這個時候,會給這個“新”的用戶一個SessionID,那造成的結果是&#…

財務管理專業應該報計算機二級哪個科目,我是應該報計算機二級還是三級呢

2008-12-01怎樣學好財務管理?“五步”學好財務管理:學習這門課程前,首先就不要認為它“很難”,只要相信“難而不會,會而不難”,充滿信心一定就能學好。我在學習過程中總結了幾條經驗,以供各位學友參考&…

libsvm java 調用說明

libsvm是著名的SVM開源組件,目前有JAVA.C/C,.NET 等多個版本,本人使用的是2.9libsvm命名空間下主要使用類:svm_model 為模型類,通過訓練或加載訓練好的模型文件獲得svm_parameter 為參數類,主要為支持向量機設定參數&a…

java字符串排序_對字符串排序持一種寬容的心態

在Java中一涉及中文處理就會冒出很多問題來,其中排序也是一個讓人頭疼的課題,我們來看下面的代碼:上面的代碼定義一個數組,然后進行升序排序,我們期望的結果是按照拼音升序排列,即為李四、王五、張三&#…

rails開發隨手記-0

helper默認是只在view中可用的,如果在controller中也要使用,要在ApplicationController中 include 如果model中如果有叫做type的列的話,會觸發rails的Single Table Inheritance ,放棄它吧,不好用,還是安心使…

nagios 監控配置介紹(二)

#配置服務端監控客戶端[rootnagios etc]# cd objects/[rootnagios objects]# vi hosts.cfg# Define a host for the local machinedefine host{use linux-serverhost_name 1.3-sambaalias 1.3-sambaaddress …

spoj SUBLEX (Lexicographical Substring Search) RE的歡迎來看看

SPOJ.com - Problem SUBLEX 這么裸的一個SAM,放在了死破OJ上面就是個坑。 注意用SAM做的時候輸出要用一個數組存下來,然后再puts,不然一個一個字符輸出會更慢。 還有一個就是不要多數據輸入,估計最后多了幾個沒用的數字&#xff0…

mt4雙線macd_3年內從虧損90多萬到獲利近760萬,我只堅持我的:60分鐘MACD雙回拉戰法!附選股公式...

MACD指標被普遍認為是最經典實用的技術指標之一。其實并不是因為MACD有多么精妙的算法,而是MACD遵循了最基本的“均線指導原則”,形象的將經典雙均線系統換了一種更加直觀的表達方式。在MT4中,默認應用的是單線MACD指標,而在證券市…

計算機專業書籍速讀方法,格式你玩的轉?速讀5分鐘就懂

小編又接到了新問題,有小伙伴說自己64GB的U盤在電腦里格式化只能選ExFAT或者NTFS,不能選擇FAT32,求小編解答,小編正好借著這個機會,說說現在電腦格式問題。如果你懶得讀,↓↓↓最后一段有答案,如…

java項目打jar包

http://www.cnblogs.com/tianguook/archive/2012/03/14/2396335.html java項目打jar包分為2種情況: 一、java項目沒有導入第三方jar包 這時候打包就比較簡單: 1. 首先在Eclipse中打開項目, 右鍵點擊項目,選擇“Export”&#xff1…

第一天 :學習node.js

第一天 :學習node.js ① node.js環境配置 我學過的語言最簡單的一門 直接百度就可以配置 ② 每個入門 的程序都是從helloworld開始 代碼如下 : var httprequire(http); http.createServer(function(req,res){ res.writeHead(200,{content-type:text/htm…

c語言從入門到精通第四版電子書_C語言從入門到精通(吐血分享)4.pdf

C語言從入門到精通(吐血分享)4成功!結構體、鏈表、文件數組、字符串函數、指針三種結構化程序設計三種數據類型、六大表達式一、簡單的程序#include 數學函數 命令行main() /*主函數*/{ /*左花括號,函數體的開始 */int a,b,c; /*定義語句*/a 3; /*執行語…

從硬盤上把數據傳回到計算機稱為什么,計算機基礎知識 第一章 習題三

計算機基礎知識第一章習題三一、填空題1. 高級語言不能直接被計算機識別并執行,必須翻譯成機器語言,翻譯的方式有兩種:一種是編譯方式,另一種是方式。2. 計算機中存儲數據的最小單位是;存儲容量的基本單位是。3. CAI的…

Mentor PADS 9.5下載安裝及破解指南

Pads,是一款用于設計、模擬電子線路及設計電路板的電腦軟件,原由Innoveda公司開發,其后改名為PowerPCB,在2002年4月Innoveda被Mentor Graphics收購,近年再次改用原名Pads。目前該軟件是國內從事電路設計的工程師和技術…

Thymeleaf 學習筆記 (4)~~~~

2019獨角獸企業重金招聘Python工程師標準>>> 模板布局 模板布局主要用到的標記有這么幾個: th:fragment ,用來定義片段的,用法:th:fragment"fragmentName",起一個名字方便被其他地方引用&#xf…