Webpack 代碼分離

來源:互聯網
上載者:User

標籤:web

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.jsvendor.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 (      <div>        <h2>It is {this.state.date}.</h2>        <p onClick={this.click}>Click here to changing the time.</p>      </div>    );  }}

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‘]      },    },  ]},


Webpack 代碼分離

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.