A recent small project was built using webpack. The function of webpack subpackage asynchronous loading is used. Today I took the time to look at the files after webpack package and roughly understood the routines of webpack subpackaging and asynchronous loading.
Since this small project uses a route written by itself, the route defines the templates and logical codes corresponding to different paths:
webpack configuration file:
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: (__dirname, 'src'), dist: (__dirname, 'dist') } var PKG = require('./'); var TARGET = .npm_lifecycle_event; //Get the currently running script name var isProduction = function() { return .NODE_ENV === 'production'; } ={ entry: { 'index': (__dirname, 'src/'), 'lib': ['./src/lib/js/'], }, //filename is the name of the main entrance file, that is, the corresponding entry //The name of the non-main entry file is the chunk output: { path: , publicPath: '/static/taxi-driver/', //publicPath is the file link generated when packaging. If it is in the production environment, of course, it uses the server address. If it is in the development environment, it uses the address of the local static server. filename: 'js/register/[name].js', chunkFilename: 'js/register/[name].js', //TODO: Add hash value to the build file }, //Generate source-map file devtool: isProduction ? null : 'source-map', devServer: { proxy: { '/api/*': { target: 'http://localhost:3000', secure: false } } }, module: { loaders: [ { test: /\.js$/, exclude: /node_modules|/, loader: 'babel' }, { test: /\.less$/, loader: ('style', 'css!less') }, { test: /\.html$/, loader: 'raw' }, { test: /\.css$/, loader: ('style', 'css') }, { test: /\.json$/, loader: 'json' } ] }, resolve: { alias: { src: (__dirname, 'src'), modules: (__dirname, 'src/modules'), lessLib: (__dirname, 'src/lib/less'), jsLib: (__dirname, 'src/lib/js'), components: (__dirname, 'src/components') }, extensions: ['', '.js', '.less', '.html', '.json'], }, plugins: [ new HtmlWebpackPlugin({ title: 'Certification Information', template: './dist/assets/', inject: 'body', filename: 'pages/register/' //The location of the output html file }), new DashboardPlugin(), new ExtractTextPlugin('css/register/'), // When the imported style file is separately extracted and inserted into the head tag, it will be packaged at the end. new ({ name: 'common', filename: 'js/register/', minChunks: 3 }) ] }
Next is the defined routing file:
const Router = new Route(); Route .addRoute({ path: 'path1', viewBox: '.public-container', template: require('modules/path1/'), pageInit() { //The subcontracted API provided by webpack. ([], () => { let controller = require('modules/path1/controller'); ('path1', new controller('.public-container')); }, 'path1'); } }) .addRoute({ path: 'path2', viewBox: '.public-container', template: require('modules/path2/'), pageInit() { ([], () => { let controller = require('modules/path2/controller'); ('path2', new controller('.public-container')); }, 'path2'); } });
Finally, webpack will package these two modules that need to be loaded asynchronously into the same.
When the page path is:
When http://localhost:8080/pages/register/#/path1, the file will be loaded
When http://localhost:8080/pages/register/#/path2, the file will be loaded.
Let’s take a look at the files packaged by webpack:
Among them, webpack defines a global function webpackJsonp. This global function is defined as soon as the project is started.
The local function __webpack_require__ is used to initialize or call other module methods in a certain module. At the same time, this function also has a static method __webpack_require__.e. This method is used to load js files asynchronously.
Let's look at it step by step:
// (function(modules) { //modules are used to save all subpackages. It is an array. Each element of the array corresponds to a callback. Each subpackage is identified by numbers. //Defined global function webpackJsonp //You can take a look at other packaged files, such as, and files. They are all in the form of webpackJsonp(). It should be easy to understand if you have used JSONP. First, define the function on the front end, and then issue the assembled function js file on the back end. After the front end obtains this file, it can be executed immediately. var parentJsonpFunction = window["webpackJsonp"]; window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { var moduleId, chunkId, i = 0, callbacks = []; for(;i < ; i++) { chunkId = chunkIds[i]; if(installedChunks[chunkId]) (callbacks, installedChunks[chunkId]); installedChunks[chunkId] = 0; } //This global function will cache each subcontract to modules for(moduleId in moreModules) { modules[moduleId] = moreModules[moduleId]; } if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules); while() ().call(null, __webpack_require__); //To start the entire application if(moreModules[0]) { installedModules[0] = 0; return __webpack_require__(0); } }; })([]);
// The require function //The moduleId identified by the number 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, , __webpack_require__); // Flag the module as loaded = true; // Return the exports of the module return ; } // This file contains only the entry chunk. // The chunk loading function for additional chunks //Async loading function __webpack_require__.e = function requireEnsure(chunkId, callback) { // "0" is the signal for "already loaded" if(installedChunks[chunkId] === 0) return (null, __webpack_require__); // an array means "currently loading". if(installedChunks[chunkId] !== undefined) { installedChunks[chunkId].push(callback); } else { //Create script emoticons and request js file // start chunk loading installedChunks[chunkId] = [callback]; var head = ('head')[0]; var script = ('script'); = 'text/javascript'; = 'utf-8'; = true; = __webpack_require__.p + "js/register/" + ({"0":"index","1":"path1","2":"path2"}[chunkId]||chunkId) + ".js"; (script); } }; // expose the modules object (__webpack_modules__) __webpack_require__.m = modules; // expose the module cache __webpack_require__.c = installedModules; // __webpack_public_path__ //The publicPath defined in the configuration file, the path to load the file after building is completed __webpack_require__.p = "/static/taxi-driver/"; })
The first thing that is loaded in the last output file is this file, and then the entry file. Because there are not many common files in this instance code, the commonChunkPlugin plugin provided by webpack itself did not work. It was originally a common file and was packaged into it.
webpackJsonp([0, 3], [ /* 0 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; __webpack_require__(1); __webpack_require__(8); /***/ }, /* 1 */ /* 2 */ /* 3 */ //.... /* 8 */ ])
The file is loaded later and it starts executing after it is loaded. Remember the 3 lines of code in the global function webpackJsonp. It is used to call this:
/* 0 */ function(module, exports, __webpack_require__) { 'use strict'; __webpack_require__(1); __webpack_require__(8); }
For the contents of modules Id 1 and 8, please check the corresponding file. Module 1 is the routing file defined by me. Before executing the code of module 1, the contents of module 2 will be loaded, and the contents of module 2 are the routing library defined by me.
Next, let’s take a look at the specific content of the routing definition in module 1:
/* 1 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; (exports, "__esModule", { value: true }); //Load the routing library var _index = __webpack_require__(2); //Instantiate a route var Router = new _index.Route(); //Defined routing rules ('path1').addRoute({ path: 'path1', viewBox: '.public-container', //Template file, module 4 template: __webpack_require__(4), pageInit: function pageInit() { //This method is a static method in __webpack_require__, which is used to load js asynchronously. //Asynchronously loading js files (i.e. chunks) are used to identify numbers, and the order of chunks starts from 0. //The chunk num here is 1. You can go back to the __webpack_require__.e method. The mapping between chunk num and module files has been done. The module file corresponding to chunk 1 is, and the module file used for chunk 2 is //The second parameter received by __webpack_require__.e() is the callback after loading the module asynchronously. When loaded, it is cached in modules. At this time, the module can be obtained through the module id. Then perform subsequent operations such as initialization __webpack_require__.e/* nsure */(1, function () { var controller = __webpack_require__(6); ('path1', new controller('.public-container')); }); } }).addRoute({ path: 'path2', viewBox: '.public-container', //Template file, module 5 template: __webpack_require__(5), pageInit: function pageInit() { __webpack_require__.e/* nsure */(2, function () { var controller = __webpack_require__(7); ('path2', new controller('.public-container')); }); } }); (); = Router; /***/ },
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.