js當中對代碼拆分時require.ensure()和import()的使用介紹及對比


webpack代碼分割

webpack 可以幫助我們將代碼分成不同的邏輯塊,在需要的時候加載這些代碼。
使用 require.ensure() 來拆分代碼
require.ensure() 是一種使用 CommonJS 的形式來異步加載模塊的策略。在代碼中通過 require.ensure([<fileurl>]) 引用模塊
require.ensure(dependencies: String[], callback: function(require), chunkName: String)
第一個參數指定依賴的模塊,
第二個參數是一個函數,
在這個函數里面你可以使用 require 來加載其他的模塊,webpack 會收集 ensure 中的依賴,將其打包在一個單獨的文件中,
在后續用到的時候使用 jsonp 異步地加載進去。

js懶加載

直接上代代碼吧,看着直接。
require.ensure(['./a'],function(require){
    let b = require('./b');
    let a = require('./a');
    console.log(a+b);
})

以上代碼,a 和 b 會被打包在一起,在代碼中執行到這段代碼的時候,會異步地去加載,加載完成后執行函數里面的邏輯。

 那就是說a和b合並成一個文件,代碼走到這里的時候才會去下載這個文件。當然這里是不是要加一個轉圈呢啥的,畢竟是異步加載嘛。
這個稍微麻煩點,可以自己去百度。 

webpack代碼分割

還記得webpack中的chunkFilename嗎?不知道沒關系。

output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },

扣了一小段代碼。這個是vue腳手架里面的。在build/webpack.prod.conf.js文件中,這個是走npm run build才會進來的。

 那怎么配合chunkFilename做代碼分割呢。 
上代碼:
require.ensure(['./c'],function(require){
   let a = require('./a');
   console.log(a);
},'d');
require.ensure(['./c'],function(require){
   let b = require('./b');
   console.log(b);
},'d');

簡單介紹下以上代碼,這兒‘d’就是最終打包成的chunkFilename 中的name。 

chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
name最終a,b,c會被打包到一個叫d.hash.js的文件中去。

require.ensure()與import的區別

     在webpack 2的官網上寫了這么一句話:

         require.ensure()特定於的WebPack並由進口import()取代。

    所以,在webpack 2里面應該是不建議使用require.ensure()這個方法的。但是目前該方法仍然有效,所以可以簡單介紹一下。包括在webpack 1中也是可以使用。

  import()

    這個的進口不同於模塊引入時的導入,可以理解為一個動態加載的模塊的函數(函數等),傳入其中的參數就是相應的模塊。例如對於原有的模塊引入從 '反應' 導入寫為進口('反應')但是需要注意的是,進口()會返回一個無極對象因此,可以通過如下方式使用:

    btn.addEventListener('click',e => {

        //在這里加載聊天組件相關資源chat.js

        import('/ components / chart')。then(mod => {

            someOperate(MOD);

        });

    });

    可以看到,使用方式非常簡單,和平時我們使用的承諾並沒有區別當然,也可以再加入一些異常處理:  

  btn.addEventListener('click',e => {

        import('/ components / chart')。then(mod => {

            someOperate(MOD);

        })。catch(err => {

            的的console.log('失敗');

        });

    });

當然,由於進口()會返回一個承諾對象,因此要注意一些兼容性問題。解決這個問題也不困難,可以使用一些承諾的填充工具來實現兼容。可以看到,動態導入()的方式不論在語意上還是語法使用上都是比較清晰簡潔的。

VUE使用實例

例:require.ensure()實現
const notFound = r => require.ensure([], () => r(require('@views/common/404')), 'index')
const login = r => require.ensure([], () => r(require('@views/common/login')), 'index')
const register = r => require.ensure([], () => r(require('@views/common/register')), 'index')
const main = r => require.ensure([], () => r(require('@views/main')), 'index')
const myWorks = r => require.ensure([], () => r(require('@views/my/index')), 'my')
const myAccountSetting = r => require.ensure([], () => r(require('@views/my/account-setting')), 'my')
const makeIndex = r => require.ensure([], () => r(require('@views/make/index')), 'make')
例:import()實現
const notFound = () => import(/* webpackChunkName: "index" */ '@views/common/404')
const login = () => import(/* webpackChunkName: "index" */ '@views/common/login')
const register = () => import(/* webpackChunkName: "index" */ '@views/common/register')
const main = () => import(/* webpackChunkName: "index" */ '@views/main')
const myWorks = () => import(/* webpackChunkName: "my" */ '@views/my/index')
const myAccountSetting = () => import(/* webpackChunkName: "my" */ '@views/my/account-setting')
const makeIndex = () => import(/* webpackChunkName: "make" */ '@views/make/index')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM