Rumah hujung hadapan web tutorial js react-router4中代码拆分的方法

react-router4中代码拆分的方法

Mar 12, 2018 am 09:38 AM
kod kaedah

随着前端项目的不断扩大,一个原本简单的网页应用所引用的js文件可能变得越来越庞大。尤其在近期流行的单页面应用中,越来越依赖一些打包工具(例如webpack),通过这些打包工具将需要处理、相互依赖的模块直接打包成一个单独的bundle文件,在页面第一次载入时,就会将所有的js全部载入。但是,往往有许多的场景,我们并不需要在一次性将单页应用的全部依赖都载下来。例如:我们现在有一个带有权限的"订单后台管理"单页应用,普通管理员只能进入"订单管理"部分,而超级用户则可以进行"系统管理";或者,我们有一个庞大的单页应用,用户在第一次打开页面时,需要等待较长时间加载无关资源。这些时候,我们就可以考虑进行一定的代码拆分(code splitting)。

实现方式

简单的按需加载

代码拆分的核心目的,就是实现资源的按需加载。考虑这么一个场景,在我们的网站中,右下角有一个类似聊天框的组件,当我们点击圆形按钮时,页面展示聊天组件。


btn.addEventListener('click', function(e) {
  // 在这里加载chat组件相关资源 chat.js
});
Salin selepas log masuk

从这个例子中我们可以看出,通过将加载chat.js的操作绑定在btn点击事件上,可以实现点击聊天按钮后聊天组件的按需加载。而要动态加载js资源的方式也非常简单(方式类似熟悉的jsonp)。通过动态在页面中添加标签,并将src属性指向该资源即可。


btn.addEventListener('click', function(e) {
  // 在这里加载chat组件相关资源 chat.js
  var ele = document.createElement('script');
  ele.setAttribute('src','/static/chat.js');
  document.getElementsByTagName('head')[0].appendChild(ele);
});
Salin selepas log masuk

代码拆分就是为了要实现按需加载所做的工作。想象一下,我们使用打包工具,将所有的js全部打包到了bundle.js这个文件,这种情况下是没有办法做到上面所述的按需加载的,因此,我们需要讲按需加载的代码在打包的过程中拆分出来,这就是代码拆分。那么,对于这些资源,我们需要手动拆分么?当然不是,还是要借助打包工具。下面就来介绍webpack中的代码拆分。

代码拆分

这里回到应用场景,介绍如何在webpack中进行代码拆分。在webpack有多种方式来实现构建是的代码拆分。

import()

这里的import不同于模块引入时的import,可以理解为一个动态加载的模块的函数(function-like),传入其中的参数就是相应的模块。例如对于原有的模块引入import react from 'react'可以写为import('react')。但是需要注意的是,import()会返回一个Promise对象。因此,可以通过如下方式使用:


btn.addEventListener('click', e => {
  // 在这里加载chat组件相关资源 chat.js
  import('/components/chart').then(mod => {
    someOperate(mod);
  });
});
Salin selepas log masuk

可以看到,使用方式非常简单,和平时我们使用的Promise并没有区别。当然,也可以再加入一些异常处理:


btn.addEventListener('click', e => {
  import('/components/chart').then(mod => {
    someOperate(mod);
  }).catch(err => {
    console.log('failed');
  });
});
Salin selepas log masuk

当然,由于import()会返回一个Promise对象,因此要注意一些兼容性问题。解决这个问题也不困难,可以使用一些Promise的polyfill来实现兼容。可以看到,动态import()的方式不论在语意上还是语法使用上都是比较清晰简洁的。

require.ensure()

在webpack 2的官网上写了这么一句话:

require.ensure() is specific to webpack and superseded by import().

所以,在webpack 2里面应该是不建议使用require.ensure()这个方法的。但是目前该方法仍然有效,所以可以简单介绍一下。包括在webpack 1中也是可以使用。下面是require.ensure()的语法:

require.ensure(dependencies: String[], callback: function(require), errorCallback: function(error), chunkName: String)
Salin selepas log masuk

require.ensure()接受三个参数:

  1. 第一个参数dependencies是一个数组,代表了当前require进来的模块的一些依赖;

  2. 第二个参数callback就是一个回调函数。其中需要注意的是,这个回调函数有一个参数require,通过这个require就可以在回调函数内动态引入其他模块。值得注意的是,虽然这个require是回调函数的参数,理论上可以换其他名称,但是实际上是不能换的,否则webpack就无法静态分析的时候处理它;

  3. 第三个参数errorCallback比较好理解,就是处理error的回调;

  4. 第四个参数chunkName则是指定打包的chunk名称。

因此,require.ensure()具体的用法如下:


btn.addEventListener('click', e => {
  require.ensure([], require => {
    let chat = require('/components/chart');
    someOperate(chat);
  }, error => {
    console.log('failed');
  }, 'mychat');
});
Salin selepas log masuk

Bundle Loader

除了使用上述两种方法,还可以使用webpack的一些组件。例如使用Bundle Loader:


npm i --save bundle-loader
Salin selepas log masuk

使用require("bundle-loader!./file.js")来进行相应chunk的加载。该方法会返回一个function,这个function接受一个回调函数作为参数。


let chatChunk = require("bundle-loader?lazy!./components/chat");
chatChunk(function(file) {
  someOperate(file);
});
Salin selepas log masuk

和其他loader类似,Bundle Loader也需要在webpack的配置文件中进行相应配置。Bundle-Loader的代码也很简短,如果阅读一下可以发现,其实际上也是使用require.ensure()来实现的,通过给Bundle-Loader返回的函数中传入相应的模块处理回调函数即可在require.ensure()的中处理,代码最后也列出了相应的输出格式:


/*
Output format:
  var cbs = [],
    data;
  module.exports = function(cb) {
    if(cbs) cbs.push(cb);
      else cb(data);
  }
  require.ensure([], function(require) {
    data = require("xxx");
    var callbacks = cbs;
    cbs = null;
    for(var i = 0, l = callbacks.length; i < l; i++) {
      callbacks[i](data);
    }
  });
*/
Salin selepas log masuk

react-router v4 中的代码拆分

最后,回到实际的工作中,基于webpack,在react-router4中实现代码拆分。react-router 4相较于react-router 3有了较大的变动。其中,在代码拆分方面,react-router 4的使用方式也与react-router 3有了较大的差别。

在react-router 3中,可以使用Route组件中getComponent这个API来进行代码拆分。getComponent是异步的,只有在路由匹配时才会调用。但是,在react-router 4中并没有找到这个API,那么如何来进行代码拆分呢?

在react-router 4官网上有一个代码拆分的例子。其中,应用了Bundle Loader来进行按需加载与动态引入


import loadSomething from &#39;bundle-loader?lazy!./Something&#39;
Salin selepas log masuk

然而,在项目中使用类似的方式后,出现了这样的警告:

Unexpected '!' in 'bundle-loader?lazy!./component/chat'. Do not use import syntax to configure webpack loaders import/no-webpack-loader-syntax
Search for the keywords to learn more about each error.

在webpack 2中已经不能使用import这样的方式来引入loader了(no-webpack-loader-syntax)

Webpack allows specifying the loaders to use in the import source string using a special syntax like this:


var moduleWithOneLoader = require("my-loader!./my-awesome-module");
Salin selepas log masuk

This syntax is non-standard, so it couples the code to Webpack. The recommended way to specify Webpack loader configuration is in a Webpack configuration file.

我的应用使用了create-react-app作为脚手架,屏蔽了webpack的一些配置。当然,也可以通过运行npm run eject使其暴露webpack等配置文件。然而,是否可以用其他方法呢?当然。

这里就可以使用之前说到的两种方式来处理:import()或require.ensure()。

和官方实例类似,我们首先需要一个异步加载的包装组件Bundle。Bundle的主要功能就是接收一个组件异步加载的方法,并返回相应的react组件:


export default class Bundle extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mod: null
    };
  }

  componentWillMount() {
    this.load(this.props)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.load !== this.props.load) {
      this.load(nextProps)
    }
  }

  load(props) {
    this.setState({
      mod: null
    });
    props.load((mod) => {
      this.setState({
        mod: mod.default ? mod.default : mod
      });
    });
  }

  render() {
    return this.state.mod ? this.props.children(this.state.mod) : null;
  }
}
Salin selepas log masuk

在原有的例子中,通过Bundle Loader来引入模块:


import loadSomething from &#39;bundle-loader?lazy!./About&#39;

const About = (props) => (
  <Bundle load={loadAbout}>
    {(About) => <About {...props}/>}
  </Bundle>
)
Salin selepas log masuk

由于不再使用Bundle Loader,我们可以使用import()对该段代码进行改写:


const Chat = (props) => (
  <Bundle load={() => import(&#39;./component/chat&#39;)}>
    {(Chat) => <Chat {...props}/>}
  </Bundle>
);
Salin selepas log masuk

需要注意的是,由于import()会返回一个Promise对象,因此Bundle组件中的代码也需要相应进行调整


export default class Bundle extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mod: null
    };
  }

  componentWillMount() {
    this.load(this.props)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.load !== this.props.load) {
      this.load(nextProps)
    }
  }

  load(props) {
    this.setState({
      mod: null
    });
    //注意这里,使用Promise对象; mod.default导出默认
    props.load().then((mod) => {
      this.setState({
        mod: mod.default ? mod.default : mod
      });
    });
  }

  render() {
    return this.state.mod ? this.props.children(this.state.mod) : null;
  }
}
Salin selepas log masuk

路由部分没有变化


<Route path="/chat" component={Chat}/>
Salin selepas log masuk

这时候,执行npm run start,可以看到在载入最初的页面时加载的资源如下


而当点击触发到/chat路径时,可以看到

动态加载了2.chunk.js这个js文件,如果打开这个文件查看,就可以发现这个就是我们刚才动态import()进来的模块。

当然,除了使用import()仍然可以使用require.ensure()来进行模块的异步加载。相关示例代码如下:


const Chat = (props) => (
  <Bundle load={(cb) => {
    require.ensure([], require => {
      cb(require(&#39;./component/chat&#39;));
    });
  }}>
  {(Chat) => <Chat {...props}/>}
 </Bundle>
);
Salin selepas log masuk


export default class Bundle extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mod: null
    };
  }

  load = props => {
    this.setState({
      mod: null
    });
    props.load(mod => {
      this.setState({
        mod: mod ? mod : null
      });
    });
  }

  componentWillMount() {
    this.load(this.props);
  }

  render() {
    return this.state.mod ? this.props.children(this.state.mod) : null
  }
}
Salin selepas log masuk

此外,如果是直接使用webpack config的话,也可以进行如下配置


output: {
  // The build folder.
  path: paths.appBuild,
  // There will be one main bundle, and one file per asynchronous chunk.
  filename: &#39;static/js/[name].[chunkhash:8].js&#39;,
  chunkFilename: &#39;static/js/[name].[chunkhash:8].chunk.js&#39;,
 },
Salin selepas log masuk

结束

代码拆分在单页应用中非常常见,对于提高单页应用的性能与体验具有一定的帮助。我们通过将第一次访问应用时,并不需要的模块拆分出来,通过scipt标签动态加载的原理,可以实现有效的代码拆分。在实际项目中,使用webpack中的import()、require.ensure()或者一些loader(例如Bundle Loader)来做代码拆分与组件按需加载。

Atas ialah kandungan terperinci react-router4中代码拆分的方法. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial Java
1664
14
Tutorial PHP
1266
29
Tutorial C#
1239
24
Bagaimana untuk memulihkan kenalan yang dipadam pada WeChat (tutorial mudah memberitahu anda cara memulihkan kenalan yang dipadam) Bagaimana untuk memulihkan kenalan yang dipadam pada WeChat (tutorial mudah memberitahu anda cara memulihkan kenalan yang dipadam) May 01, 2024 pm 12:01 PM

Malangnya, orang sering memadamkan kenalan tertentu secara tidak sengaja atas sebab tertentu WeChat ialah perisian sosial yang digunakan secara meluas. Untuk membantu pengguna menyelesaikan masalah ini, artikel ini akan memperkenalkan cara mendapatkan semula kenalan yang dipadam dengan cara yang mudah. 1. Fahami mekanisme pemadaman kenalan WeChat Ini memberi kita kemungkinan untuk mendapatkan semula kenalan yang dipadamkan Mekanisme pemadaman kenalan dalam WeChat mengalih keluar mereka daripada buku alamat, tetapi tidak memadamkannya sepenuhnya. 2. Gunakan fungsi "Pemulihan Buku Kenalan" terbina dalam WeChat menyediakan "Pemulihan Buku Kenalan" untuk menjimatkan masa dan tenaga Pengguna boleh mendapatkan semula kenalan yang telah dipadamkan dengan cepat melalui fungsi ini. 3. Masuk ke halaman tetapan WeChat dan klik sudut kanan bawah, buka aplikasi WeChat "Saya" dan klik ikon tetapan di sudut kanan atas untuk memasuki halaman tetapan.

Bagaimana untuk memasukkan bios pada papan induk Berwarna-warni? Ajar anda dua kaedah Bagaimana untuk memasukkan bios pada papan induk Berwarna-warni? Ajar anda dua kaedah Mar 13, 2024 pm 06:01 PM

Papan induk berwarna-warni menikmati populariti tinggi dan bahagian pasaran dalam pasaran domestik China, tetapi sesetengah pengguna papan induk Berwarna-warni masih tidak tahu cara memasukkan bios untuk tetapan? Sebagai tindak balas kepada situasi ini, editor telah membawakan anda secara khas dua kaedah untuk memasukkan bios motherboard yang berwarna-warni. Datang dan cuba! Kaedah 1: Gunakan kekunci pintasan permulaan cakera U untuk terus memasuki sistem pemasangan cakera U Kekunci pintasan untuk papan induk Berwarna untuk memulakan cakera U dengan satu klik ialah ESC atau F11 Pertama, gunakan Black Shark Installation Master untuk mencipta Black Cakera but cakera Shark U, dan kemudian hidupkan komputer Apabila anda melihat skrin permulaan, tekan terus kekunci ESC atau F11 pada papan kekunci untuk memasuki tetingkap untuk pemilihan item permulaan secara berurutan ke tempat "USB " dipaparkan, dan kemudian

Cara menulis novel dalam aplikasi Novel Percuma Tomato Kongsi tutorial cara menulis novel dalam Novel Tomato. Cara menulis novel dalam aplikasi Novel Percuma Tomato Kongsi tutorial cara menulis novel dalam Novel Tomato. Mar 28, 2024 pm 12:50 PM

Novel Tomato adalah perisian membaca novel yang sangat popular Kami sering mempunyai novel dan komik baru untuk dibaca dalam Novel Tomato Setiap novel dan komik sangat menarik ingin menulis ke dalam teks. Jadi bagaimana kita menulis novel di dalamnya? Kongsi tutorial novel Tomato tentang cara menulis novel 1. Mula-mula buka aplikasi novel percuma Tomato pada telefon bimbit anda dan klik pada Pusat Peribadi - Pusat Penulis 2. Lompat ke halaman Pembantu Penulis Tomato - klik pada Buat buku baru di penghujung novel.

Rahsia penetasan telur naga mudah alih terbongkar (langkah demi langkah untuk mengajar anda cara berjaya menetas telur naga mudah alih) Rahsia penetasan telur naga mudah alih terbongkar (langkah demi langkah untuk mengajar anda cara berjaya menetas telur naga mudah alih) May 04, 2024 pm 06:01 PM

Permainan mudah alih telah menjadi sebahagian daripada kehidupan orang ramai dengan perkembangan teknologi. Ia telah menarik perhatian ramai pemain dengan imej telur naga yang comel dan proses penetasan yang menarik, dan salah satu permainan yang telah menarik perhatian ramai ialah versi mudah alih Dragon Egg. Untuk membantu pemain memupuk dan mengembangkan naga mereka sendiri dengan lebih baik dalam permainan, artikel ini akan memperkenalkan kepada anda cara menetas telur naga dalam versi mudah alih. 1. Pilih jenis telur naga yang sesuai Pemain perlu berhati-hati memilih jenis telur naga yang mereka suka dan sesuai dengan diri mereka, berdasarkan pelbagai jenis sifat dan kebolehan telur naga yang disediakan dalam permainan. 2. Tingkatkan tahap mesin pengeraman Pemain perlu meningkatkan tahap mesin pengeraman dengan menyelesaikan tugasan dan mengumpul prop Tahap mesin pengeraman menentukan kelajuan penetasan dan kadar kejayaan penetasan. 3. Kumpul sumber yang diperlukan untuk penetasan Pemain perlu berada dalam permainan

Ringkasan kaedah untuk mendapatkan hak pentadbir dalam Win11 Ringkasan kaedah untuk mendapatkan hak pentadbir dalam Win11 Mar 09, 2024 am 08:45 AM

Ringkasan cara mendapatkan hak pentadbir Win11 Dalam sistem pengendalian Windows 11, hak pentadbir adalah salah satu kebenaran yang sangat penting yang membolehkan pengguna melakukan pelbagai operasi pada sistem. Kadangkala, kami mungkin perlu mendapatkan hak pentadbir untuk menyelesaikan beberapa operasi, seperti memasang perisian, mengubah suai tetapan sistem, dsb. Berikut meringkaskan beberapa kaedah untuk mendapatkan hak pentadbir Win11, saya harap ia dapat membantu anda. 1. Gunakan kekunci pintasan Dalam sistem Windows 11, anda boleh membuka gesaan arahan dengan cepat melalui kekunci pintasan.

Penjelasan terperinci tentang kaedah pertanyaan versi Oracle Penjelasan terperinci tentang kaedah pertanyaan versi Oracle Mar 07, 2024 pm 09:21 PM

Penjelasan terperinci tentang kaedah pertanyaan versi Oracle Oracle ialah salah satu sistem pengurusan pangkalan data hubungan yang paling popular di dunia Ia menyediakan fungsi yang kaya dan prestasi yang berkuasa dan digunakan secara meluas dalam perusahaan. Dalam proses pengurusan dan pembangunan pangkalan data, adalah sangat penting untuk memahami versi pangkalan data Oracle. Artikel ini akan memperkenalkan secara terperinci cara untuk menanyakan maklumat versi pangkalan data Oracle dan memberikan contoh kod khusus. Tanya versi pangkalan data pernyataan SQL dalam pangkalan data Oracle dengan melaksanakan pernyataan SQL yang mudah

Bagaimana untuk menetapkan saiz fon pada telefon mudah alih (mudah melaraskan saiz fon pada telefon bimbit) Bagaimana untuk menetapkan saiz fon pada telefon mudah alih (mudah melaraskan saiz fon pada telefon bimbit) May 07, 2024 pm 03:34 PM

Menetapkan saiz fon telah menjadi keperluan pemperibadian yang penting kerana telefon mudah alih menjadi alat penting dalam kehidupan seharian manusia. Untuk memenuhi keperluan pengguna yang berbeza, artikel ini akan memperkenalkan cara meningkatkan pengalaman penggunaan telefon mudah alih dan melaraskan saiz fon telefon mudah alih melalui operasi mudah. Mengapa anda perlu melaraskan saiz fon telefon mudah alih anda - Melaraskan saiz fon boleh menjadikan teks lebih jelas dan mudah dibaca - Sesuai untuk keperluan membaca pengguna yang berbeza umur - Mudah untuk pengguna yang kurang penglihatan menggunakan saiz fon fungsi tetapan sistem telefon mudah alih - Cara memasukkan antara muka tetapan sistem - Dalam Cari dan masukkan pilihan "Paparan" dalam antara muka tetapan - cari pilihan "Saiz Fon" dan laraskan saiz fon dengan pihak ketiga aplikasi - muat turun dan pasang aplikasi yang menyokong pelarasan saiz fon - buka aplikasi dan masukkan antara muka tetapan yang berkaitan - mengikut individu

Cara menggunakan Copilot untuk menjana kod Cara menggunakan Copilot untuk menjana kod Mar 23, 2024 am 10:41 AM

Sebagai seorang pengaturcara, saya teruja dengan alatan yang memudahkan pengalaman pengekodan. Dengan bantuan alat kecerdasan buatan, kami boleh menjana kod demo dan membuat pengubahsuaian yang diperlukan mengikut keperluan. Alat Copilot yang baru diperkenalkan dalam Visual Studio Code membolehkan kami mencipta kod yang dijana AI dengan interaksi sembang bahasa semula jadi. Dengan menerangkan kefungsian, kami dapat memahami dengan lebih baik maksud kod sedia ada. Bagaimana untuk menggunakan Copilot untuk menjana kod? Untuk bermula, kami terlebih dahulu perlu mendapatkan sambungan PowerPlatformTools yang terkini. Untuk mencapai ini, anda perlu pergi ke halaman sambungan, cari "PowerPlatformTool" dan klik butang Pasang

See all articles