分離Webpack開發環境與生產環境的配置

来源:http://www.cnblogs.com/developerdaily/archive/2017/05/31/6923893.html
-Advertisement-
Play Games

這是Webpack+React系列配置過程記錄的第五篇。其他內容請參考: 第一篇:使用webpack、babel、react、antdesign配置單頁面應用開發環境 第二篇:使用react-router實現單頁面應用路由 第三篇:優化單頁面開發環境:webpack與react的運行時打包與熱更新 ...


這是Webpack+React系列配置過程記錄的第五篇。其他內容請參考:

這篇文章的主要內容包括:

  1. 增加less-loader、url-loader、file-loader,處理less文件以及圖片字體等資源文件,同時配置autoprefixer實現CSS自動添加首碼;
  2. 增加HtmlWebpackPlugin,動態生成html文件,能夠自動引用css和js。同時修改生成的js文件命名規則,利用hash碼命名js文件。沒有改動時可以讓瀏覽器緩存內容,當有改動重新部署後可以讓瀏覽器緩存失效;
  3. 拆分dev和prod兩種環境。

準備工作

在開始之前又要修改一下項目的目錄結構,主要是為了抽離前端代碼和測試用的伺服器共同使用到的一些配置,以及為拆分dev和prod環境的配置做準備。由於改動內容比較多,也沒有什麼需要特別註意的知識點,故不細述,有問題參考後面給出的源碼即可。

在css-loader的配置上做了一些改動。原來是使用-m尾碼區分要不要對CSS文件進行模塊化處理,這次改動主要拋棄這種做法,配置了當前項目的所有CSS文件啟用模塊化處理,這樣可以在js文件中訪問css文件中定義的類。結合css-loader的文檔和我的使用體驗,發現這樣做基本滿足了目前我所碰到的場景。而針對第三方依賴(如:antd)使用的css/less文件,預設不啟用模塊化。不然可能導致打包後的網頁無法正確顯示第三方庫的樣式。

接下來開始正題。

配置less-loader、url-loader、file-loader、postcss-loader

npm安裝這幾個依賴:

npm i -D less-loader less url-loader file-loader postcss-loader  

在webpack.config.js文件中添加這幾個loader的配置。這裡我對url-loader和file-loader的傳參方式使用的還是舊版本的方式,僅是因為看起來比較順眼。

...
{
    // 當前項目的less文件,啟用CSS modules
    test: /\.less$/,
    include: [config.srcPath],
    exclude: [config.libPath],
    use: ExtractTextPlugin.extract({
        fallback: "style-loader",
        use: [
            {
                loader: 'css-loader',
                options: {
                    modules: true,
                    importLoaders: 3,
                    localIdentName: '[path][name]-[local]-[hash:base64:5]'
                }
            },
            {
                loader: path.resolve(__dirname, '..', 'loader/less-css-modules-assets-fix-loader.js')
            },
            {
                loader: 'postcss-loader',
                options: {
                    plugins: [
                        require('autoprefixer')()
                    ]
                }
            },
            {
                loader: 'less-loader'
            }
        ]
    })
},
...
{
    test: /\.woff(\?.*)?$/,
    use: 'url-loader?prefix=fonts/&name=[name]_[hash:8].[ext]&limit=10000&mimetype=application/font-woff'
},
{
    test: /\.woff2(\?.*)?$/,
    use: 'url-loader?prefix=fonts/&name=[name]_[hash:8].[ext]&limit=10000&mimetype=application/font-woff2'
},
{
    test: /\.otf(\?.*)?$/,
    use: 'file-loader?prefix=fonts/&name=[name]_[hash:8].[ext]&limit=10000&mimetype=font/opentype'
},
{
    test: /\.ttf(\?.*)?$/,
    use: 'url-loader?prefix=fonts/&name=[name]_[hash:8].[ext]&limit=10000&mimetype=application/octet-stream'
},
{
    test: /\.eot(\?.*)?$/,
    use: 'file-loader?prefix=fonts/&name=[name]_[hash:8].[ext]'
},
{
    test: /\.svg(\?.*)?$/,
    use: 'url-loader?prefix=fonts/&name=[name]_[hash:8].[ext]&limit=10000&mimetype=image/svg+xml'
},
{
    test: /\.(png|jpg|jpeg)$/,
    use: 'url-loader?limit=8192'
}
...

這樣就可以在項目中使用less了。你可能會註意到我在配置中增加了這樣一行配置:

loader: path.resolve(__dirname, '..', 'loader/less-css-modules-assets-fix-loader.js')  

這是一個自定義的loader,是為瞭解決less-loader在啟用模塊化時無法正確解析到在less文件中引用的外部地址的問題。請參考less-loader的這個issue

自定義的loader代碼很簡單,執行正則表達式替換:

module.exports = function (content) {  
  return content.replace(/url\(('|")*(\.\/)*(.+?)('|")*\)/g, 'url(./$3)').replace(/\.\/((https?|ftp):\/\/)/, '$1');
};

配置HtmlWebpackPlugin,動態命名導出文件

前面在進行代碼分割的時候留下了一個坑:需要在index.html中手動引入指定名稱的JS文件和CSS文件。一方面這樣做比較煩,另一方面對發佈和更新不利(緩存導致的各種問題)。

這裡使用HtmlWebpackPlugin插件解決這個問題。安裝方法是:

npm i -D html-webpack-plugin  

配置上主要該了這些內容:

...
// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin');  
...
// 配置上下文到項目根目錄,這樣可以使用相對根目錄的路徑訪問其他文件,如下麵的'./template/index.html'
context: config.rootPath,  
// 修改output
output: {  
    filename: '[name].[hash:8].js',
    chunkFilename: 'chunk.[id].[hash:8].js',
    publicPath: config.publicPath
},
...
// 在plugins節點添加
new HtmlWebpackPlugin({  
    template: './template/index.html'
}),
new ExtractTextPlugin({  
    filename: 'styles.[contenthash].css'
}),

可以看到我吧output的filename和chunkFilename的命名方式都改成攻台配置的了,故生成的將會是形如main.1.xxxx.js的js文件。styles.css也加入了hash尾碼。

在項目根目錄下建一個模板‘/template/index.html',內容比以前的index.html更簡單:

<html>  
  <head>
    <title>React Webpack Configuration Demo</title>
  </head>
  <body>
    <p>Hello world</p>
    <div id='main'></div>
  </body>
</html>  

刪除掉原來的index.html文件吧,這是訪問我們的網頁就可以看到這樣的內容:動態生成的html

它會自動搜索到需要的外部依賴,並且以正確的順序載入它們。

這裡我尚有個疑問: index.html這個文件每次都會獲取到最新的內容嗎?瀏覽器對它有緩存嗎?根據看到的結果看應該沒有,不然js文件的更新就不會被正確載入了。那如果沒有被緩存又是為什麼呢?,webpack有通過哪種方式處理嗎?

拆分dev和prod兩種環境

我使用比較簡單的方式拆分開發環境和生成環境的配置,分別使用不同的配置文件就行了。

把原來開發用的的webpack.config.js改成webpack.dev.config.js,並備份一份命名為webpack.prod.config.js。修改package.json和server中對配置文件的引用。

然後針對生成環境的配置文件做一些修改,主要涉及導出目錄、代碼混淆、去除冗餘代碼等相關配置。用到了以下插件:

  • DefinePlugin:定義環境變數
  • webpack.LoaderOptionsPlugin:去除調試代碼,壓縮代碼
  • webpack.optimize.UglifyJsPlugin:針對JS的混淆配置
  • CopyWebpackPlugin:複製手動引入的資源文件到指定目錄

最後改了一下package.json中的scripts:

package.json的scripts內容

這裡就不貼出詳細代碼了,看源碼吧。

源碼下載地址:https://pan.baidu.com/s/1slHIPKp


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.什麼是功能模塊化 將實現不同功能的代碼分別存放到不同的文件、類、方法中,每一個文件、類、方法都是一個實現單一功能的模塊。 2.為什麼使用模塊化 模塊化的文件、類、方法功能單一,可以相對獨立存在,不僅降低了對其他對象的依賴,而且層次清晰,便於維護。 3.模塊化的具體實現方法 通過增加模塊數目減小單 ...
  • <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <style> #div1 { width: 100px; height: 100px; position: absolute; lef ...
  • 一. Set 類似數組,成員值唯一,var s = new Set() s加入值用add,加入時不會發生類型轉換(判斷兩值是否相等用的 ,但Set會認為NaN等於自己) Set.prototype.constructor Set , Set.prototype.size返回Set實例的成員總數 de ...
  • layer是一款近年來備受青睞的web彈層組件,她具備全方位的解決方案,致力於服務各水平段的開發人員,您的頁面會輕鬆地擁有豐富友好的操作體驗。 插件官方地址:http://layer.layui.com/ layer 甚至相容了包括IE6在內的所有主流瀏覽器。 少說多做,代碼演示(拷貝直接運行): ...
  • 1 <!DOCTYPE html> 2 <html ng-app="a2_15"> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title>select控制項</title> 6 <script src="js/angular.js" type="te ...
  • 學習vue時寫的一個小demo 雖然實現很簡單,但還是推介看看,沒什麼難點,而且有些東西你可能會用到!線上演示demo源碼 ...
  • mongoose.connect('mongodb://username:[email protected]:27017/qianxunkefu_db')換成mongoose.connect('mongodb://username:[email protected]:27017/qianxunk ...
  • 《jQuery基礎教程(第4版)》是jQuery經典技術教程的*升級版,涵蓋jQuery 1.10.x和jQuery2.0.x。本書前6章以通俗易懂的方式講解了jQuery的核心組件,包括jQuery的選擇符、事件、動畫、DOM操作、Ajax支持等。第7章和第8章介紹了jQueryUI、jQuery ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...