1. 程式人生 > >webpack開發和生產兩個環境的配置詳解

webpack開發和生產兩個環境的配置詳解

目錄

啟動指令

"scripts": {
    "dev": "node build/dev-server.js", // 
    "build": "node build/build.js",// 打包
    "lint": "eslint --ext .js,.vue src"
  },

webpack.base.conf.js

webpack基本配置

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 // 配置檔案的內容需要通過module.exports暴露 module.exports = { // 配置需要打包的入口檔案,值可以是字串、陣列、物件。 // 1. 字串: entry: './entry' // 2. 字串: entry:[ './entry1','entry2'] (多入口) // 3. 物件: entry: {alert/index': path.resolve(pagesDir, `./alert/index/page`)}
// 多入口書寫的形式應為object,因為object,的key在webpack裡相當於此入口的name, entry: { app: './src/main.js' }, output: { // 輸出檔案配置,output 輸出有自己的一套規則,常用的引數基本就是這三個 // path: 表示生成檔案的根目錄 需要一個**絕對路徑** path僅僅告訴Webpack結果儲存在哪裡 path: config.build.assetsRoot, // publicPath 引數表示的是一個URL 路徑(指向生成檔案的跟目錄),用於生成css/js/圖片/字型檔案 // 等資源的路徑以確保網頁能正確地載入到這些資源. // “publicPath”項則被許多Webpack的外掛用於在生產模式下更新內嵌到css、html檔案裡的url值. // 例如,在localhost(即本地開發模式)裡的css檔案中邊你可能用“./test.png”這樣的url來載入圖片, // 但是在生產模式下“test.png”檔案可能會定位到CDN上並且你的Node.js伺服器可能是執行在HeroKu上邊的。 // 這就意味著在生產環境你必須手動更新所有檔案裡的url為CDN的路徑。 //開發環境:Server和圖片都是在localhost(域名)下 //.image { // background-image: url('./test.png'); //} // 生產環境: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 屬性表示的是如何命名出來的入口檔案,規則是一下三種: // [name] 指代入口檔案的name,也就是上面提到的entry引數的key,因此,我們可以在name裡利用/,即可達到控制檔案目錄結構的效果。 // [hash],指代本次編譯的一個hash版本,值得注意的是,只要是在同一次編譯過程中生成的檔案,這個[hash].js //的值就是一樣的;在快取的層面來說,相當於一次全量的替換。 filename: '[name].js' }, // 用來配置依賴檔案的匹配,如依賴檔案的別名配置、模組的查詢目錄、預設查詢的 // 檔案字尾名 // resolve.root 該選型用來制定模組查詢的根路徑,必須為**絕對路徑**,值可以 // 是路徑字串或者路徑陣列若是陣列,則會依次查詢 resolve: { extensions: ['', '.js', '.vue', '.json'], fallback: [path.join(__dirname, '../node_modules')], // 用來配置依賴檔案的別名,值是一個對,該物件的鍵是別名,值是實際路徑 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')] }, // 用來進行模組載入相關的配置 module: { preLoaders: [ { test: /\.vue$/, loader: 'eslint', include: projectRoot, exclude: /node_modules/ }, { test: /\.js$/, loader: 'eslint', include: projectRoot, exclude: /node_modules/ } ], loaders: [ // webpack擁有一個類似於外掛的機制,名為Loader,通過Loader,webpack能夠針對每一種特定的資源做出相應的處理 // 1.test引數用來指示當前配置項針對哪些資源,該值應是一個條件值(condition)。 // 2.exclude引數用來剔除掉需要忽略的資源,該值應是一個條件值(condition)。 // 3.include引數用來表示本loader配置僅針對哪些目錄/檔案,該值應是一個條件值(condition)。 // 而include引數則用來指示目錄;注意同時使用這兩者的時候,實際上是and的關係。 // 4.loader/loaders引數,用來指示用哪個或哪些loader來處理目標資源,這倆貨 // 表達的其實是一個意思,只是寫法不一樣,我個人推薦用loader寫成一行,多個 // loader間使用!分割,這種形式類似於管道的概念,又或者說是函數語言程式設計。形 // 如loader: 'css?!postcss!less',可以很明顯地看出,目標資源先經less-loader // 處理過後將結果交給postcss-loader作進一步處理,然後最後再交給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,這個loader的作用是,將指定js模組export的變數宣告為全域性變數 { test: require.resolve('jquery'), // 此loader配置項的目標是NPM中的jquery loader: 'expose?$!expose?jQuery', // 先把jQuery物件宣告成為全域性變數`jQuery`,再通過管道進一步又宣告成為全域性變數`$` }, ] }, 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 的內建外掛,該外掛可以在打包時候替換制定的變數
    // 
    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
    }),
    // 可以自動載入當前模組依賴的其他模組並已制定別名注入到當前的模組中,引入jq
    // 在網上看到的文章,救了我的命 ProvidePlugin + expose-loader 引入jq 
    // 
    // 如果你把jQuery看做是一個普通的js模組來載入(要用到jQuery的模組統統先require
    // 後再使用),那麼,當你載入老式jQuery外掛時,往往會提示找不到jQuery例項
    // 有時候是提示找不到$),這是為啥呢?
    // 要解釋這個問題,就必須先稍微解釋一下jQuery外掛的機制:jQuery外掛是通過
    // jQuery提供的jQuery.fn.extend(object)和jQuery.extend(object)這倆方法,來
    // 把外掛本身實現的方法掛載到jQuery(也即$)這個物件上的。傳統引用jQuery及
    // 其外掛的方式是先用<script>載入jQuery本身,然後再用同樣的方法來載入其外掛;
    // jQuery會把jQuery物件設定為全域性變數(當然也包括了$),既然是全域性變數,那麼
    // 外掛們很容易就能找到jQuery物件並掛載自身的方法了。
    // 
    // 而webpack作為一個遵從模組化原則的構建工具,自然是要把各模組的上下文環境給
    // 分隔開以減少相互間的影響;而jQuery也早已適配了AMD/CMD等載入方式,換句話說,
    // 我們在require jQuery的時候,實際上並不會把jQuery物件設定為全域性變數。說到
    // 這裡,問題也很明顯了,jQuery外掛們找不到jQuery物件了,因為在它們各自的上下
    // 文環境裡,既沒有區域性變數jQuery(因為沒有適配AMD/CMD,所以就沒有相應的requi
    // re語句了),也沒有全域性變數jQuery。
    // 
    // A: ProvidePlugin的機制是:當webpack載入到某個js模組裡,出現了未定義且名稱符合
    // (字串完全匹配)配置中key的變數時,會自動require配置中value所指定的js模組
    // expose-loader,這個loader的作用是,將指定js模組export的變數宣告為全域性變數。
    // 
    // B:externals 呼叫jq 
    // externals是webpack配置中的一項,用來將某個全域性變數“偽裝”成某個js模組的exports,
    // 如下面這個配置:
    // externals: {'jquery': 'window.jQuery',},
    // 那麼,當某個js模組顯式地呼叫var $ = require('jquery')的時候,就會把window,
    // jQuery返回給它,與上述ProvidePlugin + expose-loader的方案相反,此方案是先用
    // <script>載入的jQuery滿足老式jQuery外掛的需要,再通過externals將其轉換成符合
    // 模組化要求的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預設的引數進行初始化,生成一個例項。
  // 2. 將此例項插入到webpack配置檔案中的plugins引數(陣列型別)裡即可。
  // 
  // 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 生成網頁的HTML名字,可以使用/來控制檔案檔案的目錄結構,最
      // 終生成的路徑是基於webpac配置的output.path的
      filename: config.build.index,
      template: 'index.html',
      inject: true,
      // inject,指示把載入js檔案用的<script>插入到哪裡,預設是插到<body>
      // 的末端,如果設定為'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'
    }),

    // 如果檔案是多入口的檔案,可能存在,重複程式碼,把公共程式碼提取出來,又不會重複下載公共程式碼了
    // (多個頁面間會共享此檔案的快取)
    // CommonsChunkPlugin的初始化常用引數有解析?
    // name: 這個給公共程式碼的chunk唯一的標識
    // filename,如何命名打包後生產的js檔案,也是可以用上[name]、[hash]、[chunkhash]
    // minChunks,公共程式碼的判斷標準:某個js模組被多少個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

相關推薦

webpack開發生產環境配置

目錄 啟動指令 "scripts": { "dev": "node build/dev-server.js", // "build": "node build/build.js",// 打包 "lint": "eslint --ext .js,.vue src" }, w

flutter環境配置開發第一專案

flutter環境配置的具體步驟如下: 1). 下載flutter 2).下載後的檔案解壓,放在你想指定的目錄下(我以放在桌面為例) 3).配置環境變數 vim ~/.bash_profile 輸入後,出現上圖介面,則表明已經存在,我們直接點選大寫字母Q退出就OK!

windows 環境下在anaconda 3中安裝python2python3環境(python2python3共存)

博主本人是在學習機器學習的過程當中,看到的相關書籍使用的python 版本不一,但又想將每個版本都懂能使用一番,接下來,博主給大家介紹一個比較簡單方便的方式: 首先:安裝python 環境,極力推薦使用anaconda,Anaconda 是 Python 的

jeeweb敏捷開發平臺的環境配置

這裡講解eclipse非Maven版本的搭建 前期準備: jdk7.0以上,這裡我用jdk8eclipseTomcat 8.0Mysql 5.5或者5.6(建議使用Navicat資料庫管理軟體)軟體

Mac下 node安裝環境配置(最新)

1、進入node官網下載頁http://nodejs.cn/download/       如下圖: 選擇macOS安裝程式下載,此為  10.12.0版本、 2、雙擊安裝程式安裝 如下: 顯示程式將會安裝的位置 一直點選繼續到最後為 3

使用MyEclipse開發JSP環境配置

JDK環境怎麼配置可以到網上查詢 Tomcat 在網上也可以下載到,不再贅述 開啟MyEclipse 出現以下介面 選擇自己的工作空間,我選擇的是 C:\Users\Administrato

JAVA環境配置

指向 微軟 ssp cep 解釋 引入 bin testcase loader 步驟:一下載安裝JDK(註意版本)二配置環境變量 JAVA_HOME:JDK的安裝路徑 CLASSPATH:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\too

Redis 設計與實現之RDB AOF 種持久化模式

在執行情況下, Redis 以資料結構的形式將資料維持在記憶體中, 為了讓這些資料在 Redis 重啟之後仍然可用, Redis 分別提供了 RDB 和 AOF 兩種持久化模式。 在 Redis 執行時, RDB 程式將當前記憶體中的資料庫快照儲存到磁碟檔案中, 在 Red

Tomcat安裝與環境配置

由於eclipse的很多開發版本不支援最新版的9.0,所以接下來下載的是8.0(鋼鐵直女的滑鼠字醜的一批,極易引起不適,給各位猿兄打個預防針先) 官網地址:https://tomcat.apache.org/download-80.cgi 根據自己電腦的配置選擇相應版本

MyBatis中#$的區別與PageHelper配置

一.PageHelper配置詳解 二.MyBatis中#和$的區別 #將傳入的資料都當成一個字串,會對自動傳入

Node.js安裝以及環境配置

一.安裝 1.下載Node.js 2.下載完成後,雙擊“node-v6.9.2-x64.msi”,開始安裝Node.js 3.傻瓜式安裝,一路next 注意幾點: 4.安裝後目錄 5.開啟cmd,檢查是否安裝成功 輸入node -v,npm -v

Mybatis關聯查詢之一對多多對一XML配置

平時在開發過程中dao、bean和XML檔案都是自動生成的,很少寫XML的配置關係,今天記錄一下mybatis的關聯查詢中的多對一和一對多的情況。 首先是有兩張表(學生表Student和老師Teacher表),為了更易懂,這裡只設置了最簡單的幾個必要欄位。表結構如下圖

Nginx+Tomcat的伺服器端環境配置

Nginx+tomcat是目前主流的java web架構,如何讓nginx+tomcat同時工作呢,也可以說如何使用nginx來反向代理tomcat後端均衡呢?直接安裝配置如下: 1、JAVA JDK安裝: #下載相應的jdk軟體包,然後解壓安裝,我這裡包名稱為:jdk-7u25-linu

linux 中切換使用者:susu -的使用環境變數

大部分Linux發行版的預設賬戶是普通賬戶,而更改系統檔案或者執行某些命令,需要root身份才能進行,這就需要從當前使用者切換到root使用者,Linux中切換使用者的命令是su或su - 前者只是切換root身份,但shell環境仍然是普通使用者的shell; 而後者連使

spring 項目分開發生產環境

XML 生產 修改 default cti csharp light pos sha 1、pom 文件修改 <profile> <!-- 本地開發環境 --> <id>dev</id> <proper

Google SRE主管:使用開源軟體打造類似Google的開發生產環境

作者簡介: Minghua Ye(Google  SRE 主管) 2007加入 Google 公司,2009年開始,主要負責 Google 的雲端計算平臺,特別是 Google App Engine。 前言 如果大家對 App Engine 還不熟悉的話,簡單來說 App Engine 就是 G

當部署Robot Framework環境存在的Python2python3版本注意事項

具體部署的步驟我在這裡就不在重複,請自行百度。部署完成(當前是Windows7 64位)並寫完一個簡單的測試用例,執行測試用例的時候發現會報錯,報錯資訊如下:command: pybot.bat --argumentfile c:\users\zhouzh~1\appdata

配置環境變量:

nls_lang oracl tns ren sql china bsp -a rap 配置兩個環境變量: 名:TNS_ADMIN 值:tnsnames.ora所在目錄 名:NLS_LANG 值:SIMPLIFIED CHINESE_CHINA.ZHS16GBK

Hadoop 2.6.5 FileSystemConfiguration對象的探究

family 上傳數據 大數 塊大小 緩存 完成 color span 小夥伴 Hadoop 2.6.5 FileSystem和Configuration兩個對象的探究 版權聲明:本文為yunshuxueyuan原創文章,如需轉載,請標明出處。【http://www.

PP1指向了OO1變量(對象)的地址, 而不是OO1的內容(對象的實際地址)——充分證明@是取變量(對象)的地址,而不是變量裏面的內容,夠清楚!

com 告訴 cnblogs src logs es2017 strong bsp html 如圖,為什麽這樣取出來的p,p1的值不一樣呢? 165232328群友庾偉洪告訴我: P和P1指向了O和O1兩個變量(對象)的地址, 而不是O和O1的內容(對象