在vue中使用import()來代替require.ensure()實現代碼打包分離


最近看到一種router的寫法

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)
const login = r => require.ensure([], () => r(require('@/page/login')), 'login');
const manage = r => require.ensure([], () => r(require('@/page/manage')), 'manage');
const home = r => require.ensure([], () => r(require('@/page/home')), 'home');
const addShop = r => require.ensure([], () => r(require('@/page/addShop')), 'addShop');
const addGoods = r => require.ensure([], () => r(require('@/page/addGoods')), 'addGoods');
const userList = r => require.ensure([], () => r(require('@/page/userList')), 'userList');
const shopList = r => require.ensure([], () => r(require('@/page/shopList')), 'shopList');
const foodList = r => require.ensure([], () => r(require('@/page/foodList')), 'foodList');
const orderList = r => require.ensure([], () => r(require('@/page/orderList')), 'orderList');
const adminList = r => require.ensure([], () => r(require('@/page/adminList')), 'adminList');
const visitor = r => require.ensure([], () => r(require('@/page/visitor')), 'visitor');
const newMember = r => require.ensure([], () => r(require('@/page/newMember')), 'newMember');
const uploadImg = r => require.ensure([], () => r(require('@/page/uploadImg')), 'uploadImg');
const vueEdit = r => require.ensure([], () => r(require('@/page/vueEdit')), 'vueEdit');
const adminSet = r => require.ensure([], () => r(require('@/page/adminSet')), 'adminSet');
const sendMessage = r => require.ensure([], () => r(require('@/page/sendMessage')), 'sendMessage');
const explain = r => require.ensure([], () => r(require('@/page/explain')), 'explain');
// 這種類型的routes
const routes = [
	{
		path: '/',
		component: login
	},
	{
		path: '/manage',
		component: manage,
		name: '',
		children: [{
			path: '',
			component: home,
			meta: [],
		},{
			path: '/addShop',
			component: addShop,
			meta: ['添加數據', '添加商鋪'],
		},{
			path: '/addGoods',
			component: addGoods,
			meta: ['添加數據', '添加商品'],
		},{
			path: '/userList',
			component: userList,
			meta: ['數據管理', '用戶列表'],
		},{
			path: '/shopList',
			component: shopList,
			meta: ['數據管理', '商家列表'],
		},{
			path: '/foodList',
			component: foodList,
			meta: ['數據管理', '食品列表'],
		},{
			path: '/orderList',
			component: orderList,
			meta: ['數據管理', '訂單列表'],
		},{
			path: '/adminList',
			component: adminList,
			meta: ['數據管理', '管理員列表'],
		},{
			path: '/visitor',
			component: visitor,
			meta: ['圖表', '用戶分布'],
		},{
			path: '/newMember',
			component: newMember,
			meta: ['圖表', '用戶數據'],
		},{
			path: '/uploadImg',
			component: uploadImg,
			meta: ['文本編輯', 'MarkDown'],
		},{
			path: '/vueEdit',
			component: vueEdit,
			meta: ['編輯', '文本編輯'],
		},{
			path: '/adminSet',
			component: adminSet,
			meta: ['設置', '管理員設置'],
		},{
			path: '/sendMessage',
			component: sendMessage,
			meta: ['設置', '發送通知'],
		},{
			path: '/explain',
			component: explain,
			meta: ['說明', '說明'],
		}]
	}
]

export default new Router({
	routes,
	strict: process.env.NODE_ENV !== 'production',
})

看到require.ensure這個,我非常好奇,於是便搜索了一下
使用 vue-cli構建的項目,在 默認情況下 ,執行 npm run build  會將所有的js代碼打包為一個整體,

打包位置是 dist/static/js/app.[contenthash].js

類似下面的路由代碼

router/index.js  路由相關信息,該路由文件引入了多個 .vue組件

import Hello from '@/components/Hello'
import Province from '@/components/Province'
import Segment from '@/components/Segment'
import User from '@/components/User'
import Loading from '@/components/Loading'

執行 npm run build 會打包為一個整體 app.[contenthash].js ,這個文件是非常大,可能幾兆或者幾十兆,加載會很慢

所以我們需要分模塊打包,把我們想要組合在一起的組件打包到一個 chunk塊中去

分模塊打包需要下面這樣使用 webpack的 require.ensure,並且在最后加入一個 chunk名,

相同 chunk名字的模塊將會打包到一起

router/index.js 修改為懶加載組件

const Province = r => require.ensure([], () => r(require('@/components/Province.vue')), 'chunkname1')
const Segment = r => require.ensure([], () => r(require('@/components/Segment.vue')), 'chunkname1')
const Loading = r => require.ensure([], () => r(require('@/components/Loading.vue')), 'chunkname3')
const User = r => require.ensure([], () => r(require('@/components/User.vue')), 'chunkname3')

根據 chunkame的不同, 上面的四個組件, 將會被分成3個塊打包,最終打包之后與組件相關的js文件會分為3個 (除了app.js,manifest.js, vendor.js)

分模塊打包之后在 dist目錄下是這樣的, 這樣就把一個大的 js文件分為一個個小的js文件了,按需去下載,其他的使用方法和import的效果一樣

一、require.ensure() 方法來實現代碼打包分離

require.ensure() 是 webpack 特有的,已經被 import() 取代。

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

給定 dependencies 參數,將其對應的文件拆分到一個單獨的 bundle 中,此 bundle 會被異步加載。
當使用 CommonJS 模塊語法時,這是動態加載依賴的唯一方法。
意味着,可以在模塊執行時才運行代碼,只有在滿足某些條件時才加載依賴項。
這個特性依賴於內置的 Promise。如果想在低版本瀏覽器使用 require.ensure,
記得使用像 es6-promise 或者 promise-polyfill 這樣 polyfill 庫, 來預先填充(shim) Promise 環境。

var a = require('normal-dep');
if ( module.hot ) {
  require.ensure(['b'], function(require) {
    var c = require('c');
    // Do something special...
  });
}

按照上面指定的順序,webpack 支持以下參數:

dependencies:字符串構成的數組,聲明 callback 回調函數中所需的所有模塊。
callback:只要加載好全部依賴,webpack 就會執行此函數。require 函數的實現,作為參數傳入此函數。當程序運行需要依賴時,可以使用 require() 來加載依賴。函數體可以使用此參數,來進一步執行 require() 模塊。
errorCallback:當 webpack 加載依賴失敗時,會執行此函數。
chunkName:由 require.ensure() 創建出的 chunk 的名字。通過將同一個 chunkName 傳遞給不同的 require.ensure() 調用,我們可以將它們的代碼合並到一個單獨的 chunk 中,從而只產生一個瀏覽器必須加載的 bundle。
雖然我們將 require 的實現,作為參數傳遞給回調函數,然而如果使用隨意的名字,
例如 require.ensure([], function(request) { request('someModule'); })
則無法被 webpack 靜態解析器處理,所以還是請使用 require,例如 require.ensure([], function(require) { require('someModule'); })。
二、在vue中使用import()來代替require.ensure()實現代碼打包分離

有時候我們想把某個路由下的所有組件都打包在同個異步塊 (chunk) 中。
只需要使用 命名 chunk,一個特殊的注釋語法來提供 chunk name (需要 Webpack > 2.4)。

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

Webpack 會將任何一個異步模塊與相同的塊名稱組合到相同的異步塊中。

例: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')

本文學習自:https://blog.csdn.net/yangbingbinga/article/details/61417689
本文學習自:https://blog.csdn.net/sma2mmm/article/details/83827813
本文學習自:https://www.cnblogs.com/Man-Dream-Necessary/p/9543738.html


免責聲明!

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



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