国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

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

2019-11-19 15:24:15
字體:
供稿:網(wǎng)友

在知乎上我們常常會看到有同學發(fā)問:BAT 等大型網(wǎng)站的前端工程是如何組織管理的?這的確是一個可以發(fā)散的很廣的 Q&A,我想如果要我回答這個問題,不如先從 Webpack 配置說起。

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

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

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

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

開發(fā)環(huán)境與生產(chǎn)環(huán)境的區(qū)別

開發(fā)環(huán)境

 ?NODE_ENV 為 development

 ?啟用模塊熱更新(hot module replacement)

 ?額外的 webpack-dev-server 配置項,API Proxy 配置項

 ?輸出 Sourcemap

生產(chǎn)環(huán)境

 ?NODE_ENV 為 production

 ? 將 React、jQuery 等常用庫設置為 external,直接采用 CDN 線上的版本

 ? 樣式源文件(如 css、less、scss 等)需要通過 ExtractTextPlugin 獨立抽取成 css 文件

 ? 啟用 post-css

 ? 啟用 optimize-minimize(如 uglify 等)

 ?中大型的商業(yè)網(wǎng)站生產(chǎn)環(huán)境下,是絕對不能有 console.log() 的,所以要為 babel 配置Remove console transform

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

你需要三份配置文件

1. webpack.base.config.js

在 base 文件里,你需要將開發(fā)環(huán)境和生產(chǎn)環(huán)境中通用的配置集中放在這里:

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 優(yōu)先級高于其他 JS 相關的 loader    test: //.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: [  // 每次打包前,先清空原來目錄中的內(nèi)容  new CleanWebpackPlugin([ASSETS_BUILD_PATH], { verbose: false }),  // 啟用 CommonChunkPlugin  new webpack.optimize.CommonsChunkPlugin({   names: 'vendor',   minChunks: Infinity  }) ]};

2. webpack.dev.config.js

這是用于開發(fā)環(huán)境的 Webpack 配置,繼承自 base:

const webpack = require('webpack');// 讀取同一目錄下的 base configconst config = require('./webpack.base.config');// 添加 webpack-dev-server 相關的配置項config.devServer = { contentBase: './', publicPath: '/assets/'};// 有關 Webpack 的 API 本地代理,另請參考 https://webpack.github.io/docs/webpack-dev-server.html#proxy config.module.rules.push( {  test: //.less$/,  use: [   'style-loader',   'css-loader',   'less-loader'  ],  exclude: /node_modules/ });// 真實場景中,React、jQuery 等優(yōu)先走全站的 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 是一個數(shù)組,則證明它需要被 hot module replace if (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;

3. webpack.config.js

這是用于生產(chǎn)環(huán)境的 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_ENV new webpack.DefinePlugin({  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), // 啟動 minify new webpack.LoaderOptionsPlugin({ minimize: true }), // 抽取 CSS 文件 new ExtractTextPlugin({  filename: '[name].css',  allChunks: true,  ignoreOrder: true }));module.exports = config;

現(xiàn)在在你的工程文件夾里應該已經(jīng)有三個 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 邏輯 }, ...}

和很多項目一樣,在開發(fā)環(huán)境下的時候,你需要使用 npm run dev 來啟動,而在生產(chǎn)環(huán)境中,則用 npm run build 來發(fā)布。
題外話,在真實場景中,我們不會直接使用 webpack-dev-server,而采用 express + webpack/webpack-dev-middleware,配置方法與上面所述的完全相同。

關于專欄

如果你喜歡這篇文章,就請關注我的專欄《前端零棧》在這里我們一起聊一聊前端技術和前端工程。

關于作者

Henry,10 歲開始學習計算機編程,高二暑假獲得江蘇省青少年信息奧林匹克一等獎。2000 年開始自學 JavaScript 及網(wǎng)頁制作,2006 年起正式開始從事前端開發(fā)工作,從此一干就是 10 多年。加入阿里巴巴前,曾在 SAP 中國研究院擔任智慧交通大數(shù)據(jù)產(chǎn)品經(jīng)理。

Github:MagicCube (Henry Li)

 小結(jié)

前端從開發(fā)到部署前都離不開 Webpack 的參與,本文結(jié)合了我們自己在開發(fā)中碰到的種種問題解決方案,同時借鑒了很多開源項目的配置來介紹一種用 3 個 JS 文件來配置 Webpack 的方法。關于本文如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網(wǎng)網(wǎng)站的支持!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 堆龙德庆县| 六枝特区| 马关县| 通渭县| 贵州省| 南汇区| 望城县| 长阳| 本溪| 当涂县| 丹凤县| 大同市| 蒙阴县| 柏乡县| 穆棱市| 澎湖县| 福贡县| 晋州市| 友谊县| 阳曲县| 琼结县| 雷州市| 安阳市| 巴彦县| 台北市| 从化市| 焉耆| 池州市| 固原市| 西平县| 息烽县| 比如县| 黄大仙区| 马关县| 东方市| 龙岩市| 渭南市| 襄汾县| 合山市| 岑巩县| 拜泉县|