為什么我們要做三份 Webpack 配置文件

時至今日,Webpack 已經成為前端工程必備的基礎工具之一,不僅被廣泛用于前端工程發布前的打包,還在開發中擔當本地前端資源服務器(assets server)、模塊熱更新(hot module replacement)、API Proxy 等角色,結合 ESLint 等代碼檢查工具,還可以實現在對源代碼的嚴格校驗檢查。

正如上文中提到的,前端從開發到部署前都離不開 Webpack 的參與,而 Webpack 的默認配置文件只有一個,即 webpack.config.js,那么問題來了,開發期和部署前應該使用同一份 Webpack 配置嗎?答案肯定是否定的,既然 webpack.config.js 是一個 JS 文件,我們當然可以在文件里寫 JavaScript 業務邏輯,通過讀取環境變量 NODE_ENV 來判斷當前是在開發(dev)時還是最終的生產環境(production),然而很多同學習慣把這兩者的配置都混寫在根目錄下的 webpack.config.js,通過很多零散的 if…else 來“臨時”決定某一個 plugin 或者某一個 loader 的配置項,隨著 loaders 和 plugins 的不斷增加,久而久之 webpack.config.js 變得原來越隆長,代碼的可讀性和可維護性也大大下降。

我想通過本文來介紹一種用 3 個 JS 文件來配置 Webpack 的方法,這里借鑒了很多開源項目的配置,同時也結合了我們自己在開發中碰到的種種問題解決方案。

本文中提及的配置基于 Webpack 2 或以上,建議使用 3.0 及以上版本

開發環境與生產環境的區別

  • 開發環境

    NODE_ENV 為 development
    啟用模塊熱更新(hot module replacement)
    額外的 webpack-dev-server 配置項,API Proxy 配置項
    輸出 Sourcemap

  • 生產環境

    NODE_ENV 為 production
    將 React、jQuery 等常用庫設置為 external,直接采用 CDN 線上的版本
    樣式源文件(如 css、less、scss 等)需要通過 ExtractTextPlugin 獨立抽取成 css 文件
    啟用 post-css
    啟用 optimize-minimize(如 uglify 等)
    中大型的商業網站生產環境下,是絕對不能有 console.log() 的,所以要為 babel 配置 Remove console transform

    這里需要說明的是因為開發環境下啟用了 hot module replacement,為了讓樣式源文件的修改也同樣能被熱替換,不能使用 ExtractTextPlugin,而轉為隨 JS Bundle 一起輸出。

你需要三份配置文件

  1. webpack.base.config.js
    在 base 文件里,你需要將開發環境和生產環境中通用的配置集中放在這里:const CleanWebpackPlugin = require('clean-webpack-plugin');const path = require('path');const webpack = require('webpack');// 配置常量// 源代碼的根目錄(本地物理文件路徑)const SRC_PATH = path.resolve('./src');// 打包后的資源根目錄(本地物理文件路徑)const ASSETS_BUILD_PATH = path.resolve('./build');// 資源根目錄(可以是 CDN 上的絕對路徑,或相對路徑)const ASSETS_PUBLIC_PATH = '/assets/';module.exports = {context: SRC_PATH, // 設置源代碼的默認根路徑resolve: {extensions: ['.js', '.jsx']  // 同時支持 js 和 jsx},entry: {// 注意 entry 中的路徑都是相對于 SRC_PATH 的路徑vendor: './vendor',a: ['./entry-a'],b: ['./entry-b'],c: ['./entry-c']},output: {path: ASSETS_BUILD_PATH,publicPath: ASSETS_PUBLIC_PATH,filename: './[name].js'},module: {rules: [{enforce: 'pre',  // ESLint 優先級高于其他 JS 相關的 loadertest: /\.jsx?$/,exclude: /node_modules/,loader: 'eslint-loader'},{test: /\.jsx?$/,exclude: /node_modules/,// 建議把 babel 的運行時配置放在 .babelrc 里,從而與 eslint-loader 等共享配置loader: 'babel-loader'},{test: /\.(png|jpg|gif)$/,use:[{loader: 'url-loader',options:{limit: 8192,name: 'images/[name].[ext]'}}]},{test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,use:[{loader: 'url-loader',options:{limit: 8192,mimetype: 'application/font-woff',name: 'fonts/[name].[ext]'}}]},{test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,use:[{loader: 'file-loader',options:{limit: 8192,mimetype: 'application/font-woff',name: 'fonts/[name].[ext]'}}]}]},plugins: [// 每次打包前,先清空原來目錄中的內容new CleanWebpackPlugin([ASSETS_BUILD_PATH], { verbose: false }),// 啟用 CommonChunkPluginnew webpack.optimize.CommonsChunkPlugin({names: 'vendor',minChunks: Infinity})]};
  1. webpack.dev.config.js
這是用于開發環境的 Webpack 配置,繼承自 base:const webpack = require('webpack');// 讀取同一目錄下的 base configconst config = require('./webpack.base.config');// 添加 webpack-dev-server 相關的配置項config.devServer = {contentBase: './',hot: true,publicPath: '/assets/'};// 有關 Webpack 的 API 本地代理,另請參考 https://webpack.github.io/docs/webpack-dev-server.html#proxyconfig.module.rules.push({test: /\.less$/,use: ['style-loader','css-loader','less-loader'],exclude: /node_modules/});// 真實場景中,React、jQuery 等優先走全站的 CDN,所以要放在 externals 中config.externals = {react: 'React','react-dom': 'ReactDOM'};// 添加 Sourcemap 支持config.plugins.push(new webpack.SourceMapDevToolPlugin({filename: '[file].map',exclude: ['vendor.js'] // vendor 通常不需要 sourcemap}));// Hot module replacementObject.keys(config.entry).forEach((key) => {// 這里有一個私有的約定,如果 entry 是一個數組,則證明它需要被 hot module replaceif (Array.isArray(config.entry[key])) {config.entry[key].unshift('webpack-dev-server/client?http://0.0.0.0:8080','webpack/hot/only-dev-server');}});config.plugins.push(new webpack.HotModuleReplacementPlugin());module.exports = config;
  1. webpack.config.js
這是用于生產環境的 webpack 配置,同樣繼承自 base:const webpack = require('webpack');const ExtractTextPlugin = require('extract-text-webpack-plugin');// 讀取同一目錄下的 base configconst config = require('./webpack.base.config');config.module.rules.push({test: /\.less$/,use: ExtractTextPlugin.extract({use: ['css-loader','less-loader'],fallback: 'style-loader'}),exclude: /node_modules/});config.plugins.push(// 官方文檔推薦使用下面的插件確保 NODE_ENVnew webpack.DefinePlugin({'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')}),// 啟動 minifynew webpack.LoaderOptionsPlugin({ minimize: true }),// 抽取 CSS 文件new ExtractTextPlugin({filename: '[name].css',allChunks: true,ignoreOrder: true}));module.exports = config;

現在在你的工程文件夾里應該已經有三個 Webpack 配置文件,它們分別是:

webpack.base.config.js
webpack.dev.config.js
webpack.config.js

最后,你還需要在 package.json 里添加相應的配置:

{..."scripts": {"build": "webpack --optimize-minimize","dev": "webpack-dev-server --config webpack.dev.config.js","start": "npm run dev" // 或添加你自己的 start 邏輯},...}

和很多項目一樣,在開發環境下的時候,你需要使用 npm run dev 來啟動,而在生產環境中,則用 npm run build 來發布。

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

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

相關文章

使用maven插件構建docker鏡像

為什么要用插件 主要還是自動化的考慮,如果額外使用Dockerfile進行鏡像生成,可能會需要自己手動指定jar/war位置,并且打包和生成鏡像間不同步,帶來很多瑣碎的工作。 插件選擇 使用比較多的是spotify的插件:https://github.com/spo…

windows下如何安裝pip以及如何查看pip是否已經安裝成功?

最近剛學習python,發現很多關于安裝以及查看pip是否安裝成的例子都比較老,不太適合于現在(python 3.6 )因此,下一個入門級別的教程。 0:首先如何安裝python我就不做介紹了。 1:如果安裝的是pyth…

檢查用戶顯示器的分辨率

檢查用戶顯示器的分辨率 轉載于:https://www.cnblogs.com/Renyi-Fan/p/8088012.html

android 字體 dpi,詳解Android開發中常用的 DPI / DP / SP

Android的碎片化已經被噴了好多年,隨著國內手機廠商的崛起,碎片化也越來越嚴重,根據OpenSignal的最新調查,2014年市面上有18796種不同的Android設備,作為開發者,一個無法回避的難題就是需要適配各種各樣奇奇…

android studio閃退代碼不報錯_代碼不報錯,不代表真的沒錯

今天是生信星球陪你的第695天大神一句話,菜鳥跑半年。我不是大神,但我可以縮短你走彎路的半年~就像歌兒唱的那樣,如果你不知道該往哪兒走,就留在這學點生信好不好~這里有豆豆和花花的學習歷程,從新手到進階&#xff0c…

Centos7操作系統部署指南

一、硬件環境: Dell R620 二、軟件環境: Centos6.4 X86_64 KVM Windows7vnc 三、安裝說明 操作系統更新之迅速,讓作為新手的系統運維人員有點措手不及,相對于老手就胸有成竹。怎么講?由于老手對技術方向把握的非常好&…

Eclipse插件中的SLF4J登錄

一直都在使用Maven和純Java庫進行開發,我從沒想過在開發Eclipse插件時發出一些日志語句可能會成為問題。 但是,在Eclipse開發人員的想象中,一切似乎總是在Eclipse環境中,而Eclipse宇宙之外則什么都沒有。 如果您使用Google搜索上…

CSS(四)

css元素溢出 當子元素的尺寸超過父元素的尺寸時,需要設置父元素顯示溢出的子元素的方式,設置的方法是通過overflow屬性來設置。 overflow的設置項: 1、visible 默認值。內容不會被修剪,會呈現在元素框之外。2、hidden 內容會被修…

mysql排名

轉載自思心思危http://www.cnblogs.com/zengguowang/p/5541431.html 一、sql1{不管數據相同與否,排名依次排序(1,2,3,4,5,6,7.....)} SELECTobj.user_id,   obj.score,  rownum : rownum 1 AS rownum FROM(SELECT…

python中變量名后的逗號_深入淺析python變量加逗號,的含義

逗號,用于生成一個長度為1的元組>>> (1)1>>> (1,)(1,)>>> 1,(1,)因此需要將長度為1的元組中元素提取出來可以用,簡化賦值操作>>> a(1,)>>> ba>>> b(1,)>>> b,a>>> b1最后print打印變量加,實現連續打印…

廣告的顯示和關閉

app或游戲的主頁顯示廣告頁面,實現方式: public class MainActivity extends Activity implements View.OnClickListener{private Button btnShowAd;private RelativeLayout layoutAd;Overrideprotected void onCreate(Bundle savedInstanceState) {supe…

android簽到功能模塊,基于android的課堂簽到系統.doc

基于android的課堂簽到系統本科畢業論文(設計)題 目 基于Android的課堂簽到系統學生姓名 XXX指導教師 XX學 院 信息科學與工程學院專業班級 計算機科學與技術0908班完成時間 2013年5月 摘 要在大學課堂中,簽到問題一直困擾著老師和同學們。傳統課堂簽到的手段大多是…

Java EE 7社區調查結果!

在JSR 342下可以繼續進行Java EE 7的工作。一切進展順利,Java EE 7現在處于“初稿審查”階段。 在11月初, Oracle發布了一個有關即將推出的Java EE 7功能的小型社區調查 。 昨天結果公布了。 超過1,100名開發人員參加了調查,并且幾乎對每個問…

CSS(三)

CSS盒子模型 盒子模型解釋 元素在頁面中顯示成一個方塊,類似一個盒子,CSS盒子模型就是使用現實中盒子來做比喻,幫助我們設置元素對應的樣式。盒子模型示意圖如下: 把元素叫做盒子,設置對應的樣式分別為:盒…

一道關于運行順序題

function foo(){   getName function(){console.log(1)}   return this } foo.getName function(){console.log(2)} foo.prototype.getName function(){console.log(3)} var getName function(){console.log(4)} function getName(){console.log(5)} foo.getName()//2 …

android+小米文件管理器源碼,小米開源文件管理器MiCodeFileExplorer-源碼研究(2)-2個單實例工具類...

從本篇開始,講解net.micode.fileexplorer.util工具包中的類。這個包下的類,功能也比較單一和獨立。很多代碼的思想和實現,可以用于JavaWeb和Android等多種環境中。一、單實例活動管理器ActivitiesManager一個單實例的活動管理器,從…

移動優先的響應式布局

前面的話 隨著移動互聯網的興起,不同設備的分辨率相差較大,如果在不同的設置上顯示同一個頁面,則用戶體驗差。響應式網頁設計是一種方法,使得一個網站能夠兼容多個終端,而不用為每個終端制作特定的版本。它使得一個網站…

python中英文字符和中文字符存儲長度不同_Django如何正確截取中英混合字符串及表單中限制中文字符中長度...

中文字符和英文字符所占的字節長度是不一樣,一個是2個字節,一個是1個字節,這給我們用英文的web框架開發中文app帶來了麻煩。比如Django自帶過濾器truncatewords并不支持截取中文,另外模型中CharField中的max_length選項用于限制中…

使用RESTful客戶端API進行GET / POST

互聯網上有很多如何使用RESTful Client API的東西。 這些是基礎。 但是,盡管該主題看起來微不足道,但仍然存在一些障礙,尤其是對于初學者而言。 在這篇文章中,我將嘗試總結我的專業知識,以及我如何在實際項目中做到這…

南昌互聯網行業協會籌辦者祝真和華罡團隊-2014年12月江西IDC排行榜

他出自軍營,擁有一身正氣。 他在南昌創業,立意卓越。 從站點開始、到微營銷、到線上教育,全面開花。 他在朋友圈看到不對的內容,就會即時批評。 他對朋友,又是很的和藹可親。 他就是南昌華罡網…