webpack 配置

webpack.base.conf.js

var path = require('path')
var config = require('../config')
var utils = require('./utils')
var projectRoot = path.resolve(__dirname, '../')

var env = process.env.NODE_ENV
// check env & config/index.js to decide whether to enable CSS source maps for the
// various preprocessor loaders added to vue-loader at the end of this file
var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
var useCssSourceMap = cssSourceMapDev || cssSourceMapProd

// 配置文件的內(nèi)容需要通過module.exports暴露
module.exports = {

  // 配置需要打包的入口文件冈钦,值可以是字符串秧了、數(shù)組担锤、對(duì)象杨凑。
  // 1. 字符串: entry: './entry'
  // 2. 字符串: entry:[ './entry1','entry2'] (多入口)
  // 3. 對(duì)象:   entry: {alert/index': path.resolve(pagesDir, `./alert/index/page`)}
  // 多入口書寫的形式應(yīng)為object骏掀,因?yàn)閛bject,的key在webpack里相當(dāng)于此入口的name,
  entry: {
    app: './src/main.js'
  },
  output: {

    // 輸出文件配置绽昼,output 輸出有自己的一套規(guī)則歇父,常用的參數(shù)基本就是這三個(gè)
    // path: 表示生成文件的根目錄 需要一個(gè)**絕對(duì)路徑** path僅僅告訴Webpack結(jié)果存儲(chǔ)在哪里
    path: config.build.assetsRoot,

    // publicPath 參數(shù)表示的是一個(gè)URL 路徑(指向生成文件的跟目錄)盼忌,用于生成css/js/圖片/字體文件
    // 等資源的路徑以確保網(wǎng)頁能正確地加載到這些資源.
    // “publicPath”項(xiàng)則被許多Webpack的插件用于在生產(chǎn)模式下更新內(nèi)嵌到css、html文件里的url值.
    // 例如绊茧,在localhost(即本地開發(fā)模式)里的css文件中邊你可能用“./test.png”這樣的url來加載圖片铝宵,
    // 但是在生產(chǎn)模式下“test.png”文件可能會(huì)定位到CDN上并且你的Node.js服務(wù)器可能是運(yùn)行在HeroKu上邊的。
    // 這就意味著在生產(chǎn)環(huán)境你必須手動(dòng)更新所有文件里的url為CDN的路徑华畏。
      //開發(fā)環(huán)境:Server和圖片都是在localhost(域名)下
      //.image { 
      // background-image: url('./test.png');
      //}
      // 生產(chǎn)環(huán)境:Server部署下HeroKu但是圖片在CDN上
      //.image { 
      //  background-image: url('https://someCDN/test.png');
      //}
![](http://images2015.cnblogs.com/blog/1108527/201703/1108527-20170304195944626-432609161.png)


    publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
    
    // filename 屬性表示的是如何命名出來的入口文件鹏秋,規(guī)則是一下三種: 
    // [name] 指代入口文件的name,也就是上面提到的entry參數(shù)的key亡笑,因此侣夷,我們可以在name里利用/,即可達(dá)到控制文件目錄結(jié)構(gòu)的效果仑乌。
    // [hash]百拓,指代本次編譯的一個(gè)hash版本琴锭,值得注意的是,只要是在同一次編譯過程中生成的文件衙传,這個(gè)[hash].js 
    //的值就是一樣的决帖;在緩存的層面來說,相當(dāng)于一次全量的替換蓖捶。
    filename: '[name].js'
  },

  // 用來配置依賴文件的匹配古瓤,如依賴文件的別名配置、模塊的查找目錄腺阳、默認(rèn)查找的
  // 文件后綴名
  // resolve.root 該選型用來制定模塊查找的根路徑落君,必須為**絕對(duì)路徑**,值可以
  // 是路徑字符串或者路徑數(shù)組若是數(shù)組亭引,則會(huì)依次查找
  resolve: {
    extensions: ['', '.js', '.vue', '.json'],
    fallback: [path.join(__dirname, '../node_modules')],

    // 用來配置依賴文件的別名绎速,值是一個(gè)對(duì),該對(duì)象的鍵是別名焙蚓,值是實(shí)際路徑
    alias: {
      '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')]
  },

  // 用來進(jìn)行模塊加載相關(guān)的配置
  module: {
    preLoaders: [
      {
        test: /\.vue$/,
        loader: 'eslint',
        include: projectRoot,
        exclude: /node_modules/
      },
      {
        test: /\.js$/,
        loader: 'eslint',
        include: projectRoot,
        exclude: /node_modules/
      }
    ],
    loaders: [
      // webpack擁有一個(gè)類似于插件的機(jī)制纹冤,名為Loader,通過Loader购公,webpack能夠針對(duì)每一種特定的資源做出相應(yīng)的處理
      // 1.test參數(shù)用來指示當(dāng)前配置項(xiàng)針對(duì)哪些資源萌京,該值應(yīng)是一個(gè)條件值(condition)。
      // 2.exclude參數(shù)用來剔除掉需要忽略的資源宏浩,該值應(yīng)是一個(gè)條件值(condition)知残。
      // 3.include參數(shù)用來表示本loader配置僅針對(duì)哪些目錄/文件,該值應(yīng)是一個(gè)條件值(condition)比庄。
      // 而include參數(shù)則用來指示目錄求妹;注意同時(shí)使用這兩者的時(shí)候,實(shí)際上是and的關(guān)系佳窑。
      // 4.loader/loaders參數(shù)制恍,用來指示用哪個(gè)或哪些loader來處理目標(biāo)資源,這倆貨
      // 表達(dá)的其實(shí)是一個(gè)意思神凑,只是寫法不一樣净神,我個(gè)人推薦用loader寫成一行,多個(gè)
      // loader間使用!分割溉委,這種形式類似于管道的概念鹃唯,又或者說是函數(shù)式編程。形
      // 如loader: 'css?!postcss!less'薛躬,可以很明顯地看出俯渤,目標(biāo)資源先經(jīng)less-loader
      // 處理過后將結(jié)果交給postcss-loader作進(jìn)一步處理,然后最后再交給css-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]')
        }
      },
      // expose-loader八匠,這個(gè)loader的作用是,將指定js模塊export的變量聲明為全局變量
      {
        test: require.resolve('jquery'),  // 此loader配置項(xiàng)的目標(biāo)是NPM中的jquery
        loader: 'expose?$!expose?jQuery', // 先把jQuery對(duì)象聲明成為全局變量`jQuery`趴酣,再通過管道進(jìn)一步又聲明成為全局變量`$`
      },
    ]
  },
  eslint: {
    formatter: require('eslint-friendly-formatter')
  },
  vue: {
    loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),

    // 解決.vue中文件style的部分一些特性解析梨树,比如scoped
    postcss: [

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

webpack.dev.conf.js

var config = require('../config')
var webpack = require('webpack')
var merge = require('webpack-merge')
var utils = require('./utils')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')

// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
  baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})

module.exports = merge(baseWebpackConfig, {
  module: {
    loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
  },
  // eval-source-map is faster for development
  devtool: '#eval-source-map',
  plugins: [
    // DefinePlugin 是webpack 的內(nèi)置插件,該插件可以在打包時(shí)候替換制定的變量
    // 
    new webpack.DefinePlugin({
      'process.env': config.dev.env
    }),
    // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin(),
    // https://github.com/ampedandwired/html-webpack-plugin
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    }),
    // 可以自動(dòng)加載當(dāng)前模塊依賴的其他模塊并已制定別名注入到當(dāng)前的模塊中岖寞,引入jq
    // 在網(wǎng)上看到的文章抡四,救了我的命 ProvidePlugin + expose-loader 引入jq 
    // 
    // 如果你把jQuery看做是一個(gè)普通的js模塊來加載(要用到j(luò)Query的模塊統(tǒng)統(tǒng)先require
    // 后再使用),那么仗谆,當(dāng)你加載老式j(luò)Query插件時(shí)指巡,往往會(huì)提示找不到j(luò)Query實(shí)例
    // 有時(shí)候是提示找不到$),這是為啥呢隶垮?
    // 要解釋這個(gè)問題藻雪,就必須先稍微解釋一下jQuery插件的機(jī)制:jQuery插件是通過
    // jQuery提供的jQuery.fn.extend(object)和jQuery.extend(object)這倆方法,來
    // 把插件本身實(shí)現(xiàn)的方法掛載到j(luò)Query(也即$)這個(gè)對(duì)象上的狸吞。傳統(tǒng)引用jQuery及
    // 其插件的方式是先用<script>加載jQuery本身勉耀,然后再用同樣的方法來加載其插件;
    // jQuery會(huì)把jQuery對(duì)象設(shè)置為全局變量(當(dāng)然也包括了$)蹋偏,既然是全局變量便斥,那么
    // 插件們很容易就能找到j(luò)Query對(duì)象并掛載自身的方法了。
    // 
    // 而webpack作為一個(gè)遵從模塊化原則的構(gòu)建工具威始,自然是要把各模塊的上下文環(huán)境給
    // 分隔開以減少相互間的影響枢纠;而jQuery也早已適配了AMD/CMD等加載方式,換句話說黎棠,
    // 我們在require jQuery的時(shí)候京郑,實(shí)際上并不會(huì)把jQuery對(duì)象設(shè)置為全局變量。說到
    // 這里葫掉,問題也很明顯了些举,jQuery插件們找不到j(luò)Query對(duì)象了,因?yàn)樵谒鼈兏髯缘纳舷?    // 文環(huán)境里俭厚,既沒有局部變量jQuery(因?yàn)闆]有適配AMD/CMD户魏,所以就沒有相應(yīng)的requi
    // re語句了),也沒有全局變量jQuery挪挤。
    // 
    // A: ProvidePlugin的機(jī)制是:當(dāng)webpack加載到某個(gè)js模塊里叼丑,出現(xiàn)了未定義且名稱符合
    // (字符串完全匹配)配置中key的變量時(shí),會(huì)自動(dòng)require配置中value所指定的js模塊
    // expose-loader扛门,這個(gè)loader的作用是鸠信,將指定js模塊export的變量聲明為全局變量。
    // 
    // B:externals 調(diào)用jq 
    // externals是webpack配置中的一項(xiàng)论寨,用來將某個(gè)全局變量“偽裝”成某個(gè)js模塊的exports星立,
    // 如下面這個(gè)配置:
    // externals: {'jquery': 'window.jQuery',},
    // 那么爽茴,當(dāng)某個(gè)js模塊顯式地調(diào)用var $ = require('jquery')的時(shí)候,就會(huì)把window,
    // jQuery返回給它,與上述ProvidePlugin + expose-loader的方案相反绰垂,此方案是先用
    // <script>加載的jQuery滿足老式j(luò)Query插件的需要室奏,再通過externals將其轉(zhuǎn)換成符合
    // 模塊化要求的exports。
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery",
      "window.jQuery": "jquery",
      'window.$': 'jquery',
    })
  ]
})

webpack.prod.conf.js

var path = require('path')
var config = require('../config')
var utils = require('./utils')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var env = config.build.env

var webpackConfig = merge(baseWebpackConfig, {
  module: {
    loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
  },
  devtool: config.build.productionSourceMap ? '#source-map' : false,
  output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
  vue: {
    loaders: utils.cssLoaders({
      sourceMap: config.build.productionSourceMap,
      extract: true
    })
  },

  // webpack插件位置劲装,有固定的用法
  // 1. 利用Plugin的初始方法并傳入Plugin預(yù)設(shè)的參數(shù)進(jìn)行初始化胧沫,生成一個(gè)實(shí)例。
  // 2. 將此實(shí)例插入到webpack配置文件中的plugins參數(shù)(數(shù)組類型)里即可占业。
  // 
  // 1. 
  plugins: [
    // http://vuejs.github.io/vue-loader/en/workflow/production.html
    new webpack.DefinePlugin({
      'process.env': env
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new webpack.optimize.OccurrenceOrderPlugin(),
    // extract css into its own file
    new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
    // 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 生成網(wǎng)頁的HTML名字绒怨,可以使用/來控制文件文件的目錄結(jié)構(gòu),最
      // 終生成的路徑是基于webpac配置的output.path的
      filename: config.build.index,
      template: 'index.html',
      inject: true,
      // inject谦疾,指示把加載js文件用的<script>插入到哪里南蹂,默認(rèn)是插到<body>
      // 的末端,如果設(shè)置為'head'餐蔬,則把<script>插入到<head>里碎紊。
      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'
    }),

    // 如果文件是多入口的文件,可能存在樊诺,重復(fù)代碼仗考,把公共代碼提取出來,又不會(huì)重復(fù)下載公共代碼了
    // (多個(gè)頁面間會(huì)共享此文件的緩存)
    // CommonsChunkPlugin的初始化常用參數(shù)有解析词爬?
    // name: 這個(gè)給公共代碼的chunk唯一的標(biāo)識(shí)
    // filename秃嗜,如何命名打包后生產(chǎn)的js文件,也是可以用上[name]顿膨、[hash]锅锨、[chunkhash]
    // minChunks独旷,公共代碼的判斷標(biāo)準(zhǔn):某個(gè)js模塊被多少個(gè)chunk加載了才算是公共代碼
    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
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      chunks: ['vendor']
    })
  ]
})

if (config.build.productionGzip) {
  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
    })
  )
}

module.exports = webpackConfig
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斜筐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子括饶,更是在濱河造成了極大的恐慌囊咏,老刑警劉巖恕洲,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異梅割,居然都是意外死亡霜第,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門户辞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泌类,“玉大人,你說我怎么就攤上這事底燎∪姓ィ” “怎么了弹砚?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長喇澡。 經(jīng)常有香客問我迅栅,道長殊校,這世上最難降的妖魔是什么晴玖? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮为流,結(jié)果婚禮上呕屎,老公的妹妹穿的比我還像新娘。我一直安慰自己敬察,他們只是感情好秀睛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著莲祸,像睡著了一般蹂安。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锐帜,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天田盈,我揣著相機(jī)與錄音,去河邊找鬼缴阎。 笑死允瞧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蛮拔。 我是一名探鬼主播述暂,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼建炫!你這毒婦竟也來了畦韭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤肛跌,失蹤者是張志新(化名)和其女友劉穎艺配,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惋砂,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妒挎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了西饵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酝掩。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖眷柔,靈堂內(nèi)的尸體忽然破棺而出期虾,到底是詐尸還是另有隱情原朝,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布镶苞,位于F島的核電站喳坠,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏茂蚓。R本人自食惡果不足惜壕鹉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望聋涨。 院中可真熱鬧晾浴,春花似錦、人聲如沸牍白。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茂腥。三九已至狸涌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間最岗,已是汗流浹背帕胆。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仑性,地道東北人惶楼。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像诊杆,于是被迫代替她去往敵國和親歼捐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容