亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

詳解webpack分包及異步加載套路

2019-11-19 16:13:20
字體:
來源:轉載
供稿:網友

最近一個小項目是用webpack來進行構建的。其中用到了webpack分包異步加載的功能。今天抽時間看了下webpack打包后的文件,大致弄明白了webpack分包及異步加載的套路。

由于這個小項目是用自己寫的一個路由,路由定義好了不同路徑對應下的模板及邏輯代碼:

webpack配置文件:

 var path = require('path'), DashboardPlugin = require('webpack-dashboard/plugin'), HtmlWebpackPlugin = require('html-webpack-plugin'), webpack = require('webpack'), ExtractTextPlugin = require('extract-text-webpack-plugin');var PATHS = { app: path.join(__dirname, 'src'), dist: path.join(__dirname, 'dist')}var PKG = require('./package.json');var TARGET = process.env.npm_lifecycle_event; //獲取當前正在運行的腳本名稱var isProduction = function() { return process.env.NODE_ENV === 'production';}module.exports ={ entry: { 'index': path.join(__dirname, 'src/index.js'), 'lib': ['./src/lib/js/index.js'], }, //filename是主入口文件的名稱,即對應的entry //chunkFilename對應的是非主入口文件的名稱,chunk output: { path: PATHS.dist, publicPath: '/static/taxi-driver/', //publicPath 的話是打包的時候生成的文件鏈接,如果是在生產環境當然是用服務器地址,如果是開發環境就是用本地靜態服務器的地址 filename: 'js/register/[name].js', chunkFilename: 'js/register/[name].js', //TODO: build文件中加入hash值 }, //生成source-map文件 devtool: isProduction ? null : 'source-map', devServer: { proxy: {  '/api/*': {  target: 'http://localhost:3000',  secure: false  } } }, module: { loaders: [  {  test: //.js$/,  exclude: /node_modules|picker.min.js/,  loader: 'babel'  },  {  test: //.less$/,  loader: ExtractTextPlugin.extract('style', 'css!less')  },  {  test: //.html$/,  loader: 'raw'  },  {  test: //.css$/,  loader: ExtractTextPlugin.extract('style', 'css')  },  {  test: //.json$/,  loader: 'json'  } ] }, resolve: { alias: {  src: path.join(__dirname, 'src'),  modules: path.join(__dirname, 'src/modules'),  lessLib: path.join(__dirname, 'src/lib/less'),   jsLib: path.join(__dirname, 'src/lib/js'),  components: path.join(__dirname, 'src/components') }, extensions: ['', '.js', '.less', '.html', '.json'], }, plugins: [ new HtmlWebpackPlugin({  title: '認證資料',  template: './dist/assets/info.html',  inject: 'body',  filename: 'pages/register/index.html' //輸出html文件的位置 }), new DashboardPlugin(), new ExtractTextPlugin('css/register/style.css'), //將引入的樣式文件單獨抽成style.css文件并插入到head標簽當中,帶有路徑時,最后打包 new webpack.optimize.CommonsChunkPlugin({  name: 'common',  filename: 'js/register/common.js',  minChunks: 3 }) ]}

接下來是定義好的路由文件:

 const Router = new Route();  Route .addRoute({  path: 'path1',  viewBox: '.public-container',  template: require('modules/path1/index.html'),  pageInit() {  //webpack提供的分包的API. require.ensure  require.ensure([], () => {   let controller = require('modules/path1/controller');   Router.registerCtrl('path1', new controller('.public-container'));  }, 'path1');  } }) .addRoute({  path: 'path2',  viewBox: '.public-container',  template: require('modules/path2/index.html'),  pageInit() {  require.ensure([], () => {   let controller = require('modules/path2/controller');   Router.registerCtrl('path2', new controller('.public-container'));  }, 'path2');  } });

最后webpack會將這2個需要異步加載的模塊,分別打包成path1.js和path2.js.

當頁面的路徑為:

http://localhost:8080/pages/register/#/path1時,會加載path1.js文件
http://localhost:8080/pages/register/#/path2時,會加載path2.js文件.

再來看看webpack打包后的文件:

其中在common.js中, webpack定義了一個全局函數webpackJsonp.這個全局函數在項目一啟動后就定義好。
局部函數__webpack_require__用以在某一個模塊中初始化或者調用其他的模塊方法。同時這個函數還有一個靜態方法__webpack_require__.e這個方法就是用來異步加載js文件的。

接下來一步一步的看:

 //common.js (function(modules) { //modules用來保存所有的分包,它是一個數組,數組每個元素對應的都是callback,每個分包都是通過數字來進行標識的  //定義好的全局函數webpackJsonp //大家可以看看其他打包好的文件,例如index.js, path1.js和path2.js文件.都是webpackJsonp()這種的形式,大家用過JSONP應該會很好理解。首先在前端定義好函數,然后后端下發組裝好的函數js文件,前端獲取到這個文件后就可以立即進行執行了 var parentJsonpFunction = window["webpackJsonp"]; window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {  var moduleId, chunkId, i = 0, callbacks = []; for(;i < chunkIds.length; i++) {  chunkId = chunkIds[i];  if(installedChunks[chunkId])  callbacks.push.apply(callbacks, installedChunks[chunkId]);  installedChunks[chunkId] = 0; }  //這個全局函數會將各個分包緩存到modules for(moduleId in moreModules) {  modules[moduleId] = moreModules[moduleId]; } if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules); while(callbacks.length)  callbacks.shift().call(null, __webpack_require__);  //用以啟動整個應用 if(moreModules[0]) {  installedModules[0] = 0;  return __webpack_require__(0); } }; })([]);
 // The require function  //通過數字標識的moduleId function __webpack_require__(moduleId) { // Check if module is in cache if(installedModules[moduleId])  return installedModules[moduleId].exports; // Create a new module (and put it into the cache) var module = installedModules[moduleId] = {  exports: {},  id: moduleId,  loaded: false }; // Execute the module function modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // Flag the module as loaded module.loaded = true; // Return the exports of the module return module.exports; } // This file contains only the entry chunk. // The chunk loading function for additional chunks  //異步加載函數 __webpack_require__.e = function requireEnsure(chunkId, callback) { // "0" is the signal for "already loaded" if(installedChunks[chunkId] === 0)  return callback.call(null, __webpack_require__); // an array means "currently loading". if(installedChunks[chunkId] !== undefined) {  installedChunks[chunkId].push(callback); } else {   //創建script表情,請求js文件  // start chunk loading  installedChunks[chunkId] = [callback];  var head = document.getElementsByTagName('head')[0];  var script = document.createElement('script');  script.type = 'text/javascript';  script.charset = 'utf-8';  script.async = true;  script.src = __webpack_require__.p + "js/register/" + ({"0":"index","1":"path1","2":"path2"}[chunkId]||chunkId) + ".js";  head.appendChild(script); } }; // expose the modules object (__webpack_modules__) __webpack_require__.m = modules; // expose the module cache __webpack_require__.c = installedModules; // __webpack_public_path__  //配置文件中定義的publicPath,build完后加載文件的路徑 __webpack_require__.p = "/static/taxi-driver/";})

在最后輸出的index.html文件中首先加載的是這個common.js文件,然后是入口文件index.js。因為這個實例代碼里面沒有很多共用文件,因此webpack自己提供的commonChunkPlugin這個插件并沒有起到作用,本來作為共用文件的xRoute.js因此也被打包進入了index.js.

 webpackJsonp([0, 3], [ /* 0 *//***/ function(module, exports, __webpack_require__) { 'use strict'; __webpack_require__(1); __webpack_require__(8);/***/ },/* 1 *//* 2 *//* 3 *///..../* 8 */ ])

index.js文件在common.js后加載,加載完后即開始執行.大家還記得webpackJsonp這個全局函數里面的倒數3行代碼吧。就是用以調用這里:

 /* 0 */ function(module, exports, __webpack_require__) { 'use strict'; __webpack_require__(1); __webpack_require__(8);}

其中模塊Id為1和8的內容請查看相應文件, 其中模塊1為我定義的路由文件,在執行模塊1的代碼前,會加載模塊2的內容,模塊2的內容為我定義的路由庫。

接下來就看下模塊1中路由定義的具體內容:

 /* 1 *//***/ function(module, exports, __webpack_require__) { 'use strict'; Object.defineProperty(exports, "__esModule", { value: true });  //加載路由庫 var _index = __webpack_require__(2); //實例化一個路由 var Router = new _index.Route(); //定義好的路由規則 Router.home('path1').addRoute({ path: 'path1', viewBox: '.public-container', //模板文件,為模塊4 template: __webpack_require__(4), pageInit: function pageInit() { //這個方法是在common.js中__webpack_require__的靜態方法,用來異步加載js。 //異步加載js的文件(即chunk)用來數字來標識,chunk的順序從0開始. //這里path1.js的chunk num為1,大家可以回過頭到common.js的__webpack_require__.e方法里面看看,里面已經做好了chunk num和模塊文件的映射, chunk 1對應的模塊文件為path1.js,chunk 2對用的模塊文件為path2.js //__webpack_require__.e()接收的第二個參數為異步加載模塊后的回調. 當path1.js被加載完后,在modules里面進行了緩存.這時就可以通過模塊id去獲取這個模塊。然后進行初始化等后續的操作  __webpack_require__.e/* nsure */(1, function () {  var controller = __webpack_require__(6);  Router.registerCtrl('path1', new controller('.public-container'));  }); } }).addRoute({ path: 'path2', viewBox: '.public-container', //模板文件,為模塊5 template: __webpack_require__(5), pageInit: function pageInit() {  __webpack_require__.e/* nsure */(2, function () {  var controller = __webpack_require__(7);  Router.registerCtrl('path2', new controller('.public-container'));  }); } }); Router.bootstrap(); exports.default = Router;/***/ },

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情在线视频二区| 国产成人av网| 中文字幕精品久久久久| 91成人性视频| 亚洲综合日韩在线| 91亚洲午夜在线| 午夜精品福利在线观看| 久久久国产91| 伊人激情综合网| 欧美高清第一页| 国产91在线播放| 日韩精品在线观| 欧美午夜无遮挡| 中文字幕最新精品| 日韩精品中文字幕有码专区| 欧美大片欧美激情性色a∨久久| 91高清在线免费观看| 国产97在线亚洲| 久久久最新网址| 久久久久久国产精品三级玉女聊斋| 亚洲乱亚洲乱妇无码| 欧美日韩在线视频观看| 国产亚洲欧美日韩美女| 午夜精品蜜臀一区二区三区免费| 国产97在线亚洲| 国产精品∨欧美精品v日韩精品| 欧美激情综合色| 欧美中文字幕精品| 日韩中文字幕在线看| 久久久女人电视剧免费播放下载| 日本高清久久天堂| 日韩av在线一区二区| 久久久久久久久久久久av| 国产视频精品一区二区三区| 亚洲第一福利在线观看| 亚洲精品自拍第一页| 久久综合久久美利坚合众国| 国产成人精品一区| 欧美电影《睫毛膏》| 成人免费淫片aa视频免费| 国产精品欧美一区二区三区奶水| 日本欧美精品在线| 92版电视剧仙鹤神针在线观看| 亚洲a一级视频| 尤物九九久久国产精品的特点| 国产美女精彩久久| 亚洲白拍色综合图区| 精品国产91久久久久久老师| 欧美国产日本在线| 国内精品久久久久久久久| 日韩少妇与小伙激情| 精品久久久久久久久久久久久| 97成人超碰免| 国内精品一区二区三区四区| 亚洲淫片在线视频| 亚洲最大的免费| 精品久久久久久中文字幕| 国产亚洲欧美aaaa| 国产欧美日韩中文字幕| 国产综合色香蕉精品| 97在线视频免费播放| 欧美成在线观看| 亚洲精品成人免费| 欧美午夜片在线免费观看| 久久久亚洲欧洲日产国码aⅴ| 国产亚洲精品一区二555| 日韩少妇与小伙激情| 在线视频一区二区| 中文字幕亚洲欧美在线| 91九色综合久久| 亚洲女人初尝黑人巨大| 4k岛国日韩精品**专区| 亚洲free性xxxx护士白浆| 国产精品视频精品| 中文字幕在线看视频国产欧美在线看完整| 欧洲日本亚洲国产区| 91精品国产777在线观看| 亚洲国产精品电影在线观看| 91亚洲一区精品| 欧美黄色片视频| 国产日韩欧美电影在线观看| 亚洲黄色有码视频| 国产第一区电影| 精品人伦一区二区三区蜜桃网站| 亚洲精品电影网站| 亚洲理论片在线观看| 欧美伦理91i| 欧美在线免费观看| 亚洲人成网在线播放| 欧洲永久精品大片ww免费漫画| 日韩精品在线观看网站| 亚洲欧美在线免费观看| 欧美一级在线亚洲天堂| 日韩在线视频免费观看| 亚洲国产精品福利| 亚洲国产成人精品女人久久久| 亚洲精品美女免费| 精品国产欧美一区二区三区成人| 在线视频国产日韩| 国产精品永久免费在线| 欧美一区二区三区免费视| 亚洲国产私拍精品国模在线观看| 欧美国产亚洲精品久久久8v| 国产一区二区三区精品久久久| 日韩电影在线观看中文字幕| 国内精品久久久久伊人av| 91精品综合久久久久久五月天| 91av在线免费观看视频| 日韩av电影在线免费播放| 国产不卡精品视男人的天堂| 亚洲一区制服诱惑| 亚洲老头同性xxxxx| 亚洲一区二区三区xxx视频| 日韩成人高清在线| 欧美高清在线播放| 亚洲欧洲中文天堂| 欧美极品少妇与黑人| 午夜剧场成人观在线视频免费观看| 国产一区二区丝袜| 国产精品综合网站| 亚洲最大av网| 国内外成人免费激情在线视频| 北条麻妃一区二区在线观看| 欧美性xxxx极品高清hd直播| 国产精品九九久久久久久久| 亚洲一区亚洲二区亚洲三区| 国产成人av在线播放| 一区二区三区精品99久久| 亚洲第一网中文字幕| 欧美老妇交乱视频| 中文字幕日本欧美| 亚洲精品一区中文字幕乱码| 精品高清美女精品国产区| 亚洲精品短视频| 91av视频导航| 欧美激情va永久在线播放| 欧美日韩国产91| 国产精品999999| 国内精品国产三级国产在线专| 成人日韩av在线| 久久人人爽人人爽人人片av高清| 亚洲精品影视在线观看| 欧美极品美女电影一区| 成人激情综合网| 亚洲欧美中文字幕在线一区| 欧美肥婆姓交大片| 欧美激情视频三区| 亚洲成人激情小说| 国产一区二区三区直播精品电影| 欧美一区二粉嫩精品国产一线天| 91香蕉嫩草影院入口| 久久久www成人免费精品| 97在线视频免费观看| 成人欧美一区二区三区在线湿哒哒| 欧美俄罗斯乱妇| 91精品视频免费观看| 成人免费观看49www在线观看| 国产精品久久久久91| 日韩电影中文 亚洲精品乱码| 日韩国产在线播放| 亚洲欧美一区二区三区久久| 亚洲影视九九影院在线观看| 中文字幕一精品亚洲无线一区| 欧美影院在线播放|