當前位置:
首頁 > 知識 > Webpack 代碼分離

Webpack 代碼分離


?? 提示:

  1. 版本問題

本文基於 webpack 2.x版本。webpack 2.x相比webpack 1.x有重大改變。所以,如果你的項目中已使用了 webpack 1.x ,本教程的示例將不適用,請慎重。

如果鐵了心要升級 webpack ,請參考 webpack 官方文檔 - 從 v1 遷移到 v2

  1. 閱讀建議

閱讀本文前,建議先閱讀 Webpack 概念。

代碼分離是 webpack 中最引人注目的特性之一。

你可以把你的代碼分離到不同的 bundle 中,然後你就可以去按需載入這些文件。

總的來說, webpack分離可以分為兩類:

  • 資源分離
  • 代碼分離

資源分離(Resource Splitting)

對第三方庫(vendor) 和 CSS 進行代碼分離,這些方式有助於實現緩存和並行載入。

分離 CSS(CSS Splitting)

你可能也想將你的樣式代碼分離到單獨的 bundle 中,以此使其獨立於應用程序邏輯。這加強了樣式的可緩存性,並且使得瀏覽器能夠並行載入應用程序代碼中的樣式文件,避免 FOUC 問題 (無樣式內容造成的閃爍)。

安裝 ExtractTextWebpackPlugin如下

$ npm install --save-dev extract-text-webpack-plugin

webpack.config.js 中需要按下面進行配置:

const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {

// 關於模塊配置
module: {

// 模塊規則(配置 loader、解析器等選項)
rules: [
{
// css 載入
test: /.css$/,
use: ExtractTextPlugin.extract({
use: "css-loader"
})
}
]
},

// 附加插件列表
plugins: [
// 將樣式文件獨立打包
new ExtractTextPlugin("styles.css")
]
};

?? 示例DEMO09:(DEMO/SOURCE)

分離第三方庫(Vendor Code Splitting)

一個典型的應用程序,由於框架/功能性需求,會依賴於許多第三方庫的代碼。不同於應用程序代碼,這些第三方庫代碼不會頻繁修改。

如果我們將這些庫(library)中的代碼,保留在與應用程序代碼相獨立的 bundle 中,我們就可以利用瀏覽器緩存機制,把這些文件長時間地緩存在用戶機器上。

為了完成這個目標,不管應用程序代碼如何變化,vendor 文件名中的 hash部分必須保持不變。學習如何使用CommonsChunkPlugin分離 vendor/library代碼。

webpack.config.js

const webpack = require("webpack");

module.exports = {
// 這裡應用程序開始執行
// webpack 開始打包
// 本例中 entry 為多入口
entry: {
main: "./app/index",
vendor: "react"
},

// webpack 如何輸出結果的相關選項
output: {
// 所有輸出文件的目標路徑
// 必須是絕對路徑(使用 Node.js 的 path 模塊)
path: path.resolve(__dirname, "dist"),

// 「入口分塊(entry chunk)」的文件名模板(出口分塊?)
// filename: "bundle.min.js",
// filename: "[name].js", // 用於多個入口點(entry point)(出口點?)
// filename: "[chunkhash].js", // 用於長效緩存
filename: "[name].[chunkhash:8].js", // 用於長效緩存
},

// 附加插件列表
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor" // 指定公共 bundle 的名字。
})
]
};

在上面的配置中,

  1. entry屬性中,將 react 指定為一個獨立的入口

    vendor

  2. 然後,在 output屬性中,將

    filename

    指定為 [name].[chunkhash:8].js,這表示輸出文件的文件名樣式。
  3. 最後在 plugins列表中引入

    CommonsChunkPlugin

    插件,用來指定 bundle 。

執行 webpack 命令後,webpack 會生成 2 個 bundle 文件,形式如:

main.bef8f974.js
vendor.2f1bd4c8.js

?? 示例DEMO10:(DEMO/SOURCE)

代碼按需分離(On Demand Code Splitting)

雖然前面幾類資源分離,需要用戶預先在配置中指定分離模塊,但也可以在應用程序代碼中創建動態分離模塊。

這可以用於更細粒度的代碼塊,例如,根據我們的應用程序路由,或根據用戶行為預測。這可以使用戶按照實際需要載入非必要資源。

前一節,我們了解了 webpack 可以將資源拆分為bundle。接下來,我們要學習如何非同步載入。例如,這允許首先提供最低限度的引導 bundle,並在稍後再非同步地載入其他功能。

webpack 支持兩種相似的技術實現此目的:使用 import(推薦,ECMAScript 提案) 和require.ensure(遺留,webpack 特定)。本文只介紹官方推薦的import方式。

ES2015 loader 規範定義了import作為一種在運行時(runtime)動態載入 ES2015 模塊的方法。

webpack 把 import作為一個分離點(split-point),並把引入的模塊作為一個單獨的 chunk。import將模塊名字作為參數並返回一個Promoise對象,即import(name) -> Promise

配合 Babel 使用

如果你想要在 Babel中使用import,但是由於 import 還是屬於 Stage 3 的特性,所以你需要安裝/添加syntax-dynamic-import插件來避免 parser 報錯。在草案正式成為規範後,就不再需要這個插件了。

例:

我們來定義一個 Clock 組件,動態引入 moment 庫。

首先,安裝 moment 庫。

$ npm install --save-dev moment

JavaScript 代碼:

class Clock extends React.Component {
constructor(props) {
super(props);
this.state = { date: new Date.toLocaleDateString };
this.click = this.click.bind(this);
}

click {
// 動態引入import
import("moment")
.then(moment => moment.format("MMMM Do YYYY, h:mm:ss a"))
.then(str => this.setState({date:str}))
.catch(err => console.log("Failed to load moment", err));
}

render {
return (

It is {this.state.date}.

Click here to changing the time.

);
}
}

webpack.config.js

// 關於模塊配置
module: {

// 模塊規則(配置 loader、解析器等選項)
rules: [
{
// 語義解釋器,將 js/jsx 文件中的 es2015/react 語法自動轉為瀏覽器可識別的 Javascript 語法
test: /.jsx?$/,
include: path.resolve(__dirname, "app"),

// 應該應用的 loader,它相對上下文解析
// 為了更清晰,`-loader` 後綴在 webpack 2 中不再是可選的
// 查看 webpack 1 升級指南。
loader: "babel-loader",

// loader 的可選項
options: {
presets: ["es2015", "react"],
plugins: ["syntax-dynamic-import"]
},
},
]
},

?? 示例DEMO11:(DEMO/SOURCE)

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 達人科技 的精彩文章:

Java虛擬機14:Java對象大小、對象內存布局及鎖狀態變化
python裝飾器大詳解
用JMX遠程監控Tomcat
google snapy 壓縮文件
Scrapy教程——博客園前3000名文章列表抓取

TAG:達人科技 |

您可能感興趣

dotnet core webapi+vue 搭建前後端完全分離web架構(一)
Tableau小技巧之分離Box plot和Unit Histogram
喬納森:iPhone和Apple Watch將進一步分離
Springboot集成Kaptcha實現前後端分離的驗證碼功能
Mysql8.0主從搭建,shardingsphere+springboot+mybatis讀寫分離
springmvc+jsp轉spring boot結構 前後端分離
SpringBoot 玩轉讀寫分離
實戰:基於django+nuxt前後端分離的web產品架構
蘋果iPhone的重大改革:App Store將從桌面分離
分離,Bruce Haley攝影作品
Windows 10將分離Core OS系統和Shell UI體驗
前後端分離「vue + .netcore 補程」之基於Vuex的許可權驗證探究
把you are telling me翻譯成「你正在告訴我」,錯得十分離譜
Spring Cloud項目前後端分離跨域問題解決
mysql+mycat實現主從複製、讀寫分離
Hybris平台Web架構模式演變:前後端分離
分離的前後 Zoom Air!看看 Air Jordan 33 中底拆解展示
SQLite 分離資料庫
華為手環TalkBand B5真機曝光:依舊可分離設計
Air Jordan XXXII AJ32 前後分離式ZOOM AIR氣墊原裝碳纖CNY Board Room黃蜂總裁