preface

The following concepts should be fairly clear before reading this article: Go to modularity

  • 1. What is modularity?
  • 2. What are the modular standards?

What is Webpack? Webpack is a module loader and packaging tool.

  • As a module loader, it can use and process all resource files (JS, JSX, CSS, CoffeeScript, Less, Sass, Image, etc.) as modules.
  • As a module packaging tool, the main function is to package resource files into a package, we only need to reference a package file during development, can load the pre-designed module functions, while allowing the output of specified modular specifications.

So as a module loader. While the browser is running, I want to understand the following questions:

  • 1, webpack how to achieve a variety of different JS module specifications compatible processing?
  • 2. How does Webpack implement the modular processing of js type files?

As a module packaging tool, while the browser is running, I want to know:

  • 1. How does WebPack output the specified modularity specification once it has packaged the resource files into a package?

This article is guided by the packaging results, compared with our source code, discusses how to deal with JS files, CSS files, images, fonts, etc. in the output of Webpack when the browser is running, as well as load on demand, to achieve modular management.

Initialize the WebPack project

1.1 Create a folder webpack-demo and install dependencies.

npm init -y
npm install webpack webpack-cli -D
Copy the code

1.2 Configuring Packaged Entry and Output

New webpack. Config. Js

Module. exports = {entry:'./ SRC /index.js', // output: {path: Path.resolve (__dirname, "./dist"), // filename:"bundle.js"}}Copy the code

1.3 Configuring packaging commands

In the package. The json

{
    scripts:{
      "build": "webpack --config webpack.config.js"
    }
}
Copy the code

1.4 Creating an import file

Write anything in SRC /index.js

const foo = function(){
    console.log('this is foo')
}
export default foo
Copy the code

1.5 Running the NPM run build command

Dist /bundle.js can be found in the root directory

【 2 】 Analyze bundle.js

After copying bundle.js and removing some of the comments, it looks like this:

(function(modules) { // webpackBootstrap // 1. Define a module cache object var installedModules = {}; Function __webpack_require__(moduleId) {if(installedModules[moduleId]) {return installedModules[moduleId].exports; Var Module = installedModules[moduleId] = {I: moduleId, l: false, exports: {}}; // exports: {}}; Modules [moduleId]. Call (module.exports, module, module.exports, __webpack_require__); // 2.4 mark module as loaded module.l = true; // exports; // exports. } // expose the modules object (__webpack_modules__) __webpack_require__.m = modules; // expose the module cache __webpack_require__.c = installedModules; // define getter function for harmony exports __webpack_require__.d = function(exports, name, getter) { if(! __webpack_require__.o(exports, name)) { Object.defineProperty(exports, name, { enumerable: true, get: getter }); }}; // define __esModule on exports __webpack_require__.r = function(exports) { if(typeof Symbol ! == 'undefined' && Symbol.toStringTag) { Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); } Object.defineProperty(exports, '__esModule', { value: true }); }; // create a fake namespace object // mode & 1: value is a module id, require it // mode & 2: merge all properties of value into the ns // mode & 4: return value when already ns object // mode & 8|1: behave like require __webpack_require__.t = function(value, mode) { if(mode & 1) value = __webpack_require__(value); if(mode & 8) return value; if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; var ns = Object.create(null); __webpack_require__.r(ns); Object.defineProperty(ns, 'default', { enumerable: true, value: value }); if(mode & 2 && typeof value ! = 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); return ns; }; // getDefaultExport function for compatibility with non-harmony modules __webpack_require__.n = function(module) { var getter = module && module.__esModule ? function getDefault() { return module['default']; } : function getModuleExports() { return module; }; __webpack_require__.d(getter, 'a', getter); return getter; }; // Object.prototype.hasOwnProperty.call __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; // __webpack_public_path__ __webpack_require__.p = ""; Return __webpack_require__(__webpack_require__. S = "./ SRC /index.js"); })({ "./src/index.js": (function(module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__); \nvar foo = function foo() {\n console.log(\"this is foo\"); \n}; \n\n/* harmony default export */ __webpack_exports__[\"default\"] = (foo); \n\n//# sourceURL=webpack:///./src/index.js?" ); })})Copy the code

2.1 Overall Structure

Webpack acts as a module loader, packaging the content in the resulting bundle.js into two parts, the runtime code and our source code. The principle is that through IIFE as the initiator, the self-executing function body is the code that WebPack manages each module code to run on the browser side. The arguments to the self-executing function are our source code.

(function(modules) {// webpackBootstrap statements // require entry module})(// Modules object set {path1:function(){ XXX. / * * / js source code}, path2: function () {/ * XXX. * / js source code}})Copy the code

To put it simply, the WebPack modularity mechanism is started by self-executing functions (IIFE) and then implemented through WebPack’s custom exports and require.

2.2 Implementation of require

The __webpack_require__ function mainly implements the following logic

  • 2.2.1 will check the module cache first and return the export object of the cache module, i.e. Module.exports
  • 2.2.2 If the cache does not exist, create a new module object and put it into the cache
  • 2.2.3 Call the module function, passing in the new module object and __webpack_require__ as arguments
  • 2.2.4 Mark module as loaded
  • 2.2.5 Returning the exports object of the output module

Webpack_require mounts some methods and properties

annotation describe
webpack_require.m // expose the modules object Expose modules objects passed in
webpack_require.c // expose the module cache Expose the cached installedModules(which may not have finished loading)
webpack_require.d // define getter function for harmony exports Bind the action to the getter method of property A
webpack_require.r // define __esModule on exports Use to add an __esModule attribute of true to __webpack_exports__, indicating that this is an ES6 module
webpack_require.t //
webpack_require.n // getDefaultExport function for compatibility with non-harmony modules __webpack_exports__ is an ES module. When __esModule is true, __webpack_exports__ is an ES module. Module [default] returns the export default variable by default. Otherwise return directly to export
webpack_require.o // Object.prototype.hasOwnProperty.call Determine if it has its own attributes
webpack_require.p // __webpack_public_path__ PublicPath in the Webpack configuration is used to load asynchronous code that has been partitioned off
webpack_require.s // Load entry module and return exports The startup module path is saved

2.3 Implementation of Export (Es6 Module)

2.3.1 the source file

// ========== source file ========== start
// src/module-es6.js
export let moduleValue = "moduleValue"
export default function () {
  console.log("this is es6-module")}// src/index.js
import moduleDefault, { moduleValue } from "./module-es6.js";
// ========== source file ========== end
Copy the code

2.3.2 Compiling package results

/ / = = = = = = = = = = compile packaging result = = = = = = = = = = start '. / SRC/index. Js' : (function(module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__); \n/* harmony import */ var _module_es6_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( \"./src/module-es6.js\"); \n\nconsole.log(_module_es6_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"]); \n\n//# sourceURL=webpack:///./src/index.js?" ); }), './src/module-es6.js': /*! exports provided: moduleValue, default */ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__); \n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"moduleValue\", function() { return moduleValue; }); \n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return f; }); \nvar moduleValue = \"moduleValue\"; \n\nfunction f() {\n console.log(\"this is es6-module\"); \n}\n\n//# sourceURL=webpack:///./src/module-es6.js?" ); }) // ========== compile package result ========== endCopy the code

2.3.3 Analyzing packaging results

// 2.3.3.1 Exports from module-es6.js (the return value of the __webpack_require__ function, module.exports) {default: F (), // corresponding to the export default keyword moduleValue: 'moduleValue', // Export keyword __esModule:true // used to identify ES6 modules} // importing ES6 modules through import in index.js // 2.3.3.2 import Var _module_es6_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( \"./ SRC /module-es6.js\") // 2.3.3.3 The use of the corresponding variable is also converted to the attributes of the exported object access _module_es6_js__WEBPACK_IMPORTED_MODULE_0__['default'] _module_es6_js__WEBPACK_IMPORTED_MODULE_0__['moduleValue']Copy the code

2.4 Implementation of Export (commonJs Module)

Against 2.4.1 source file

// module-commonjs.js
exports.moduleValue1 = "moduleValue1";
exports.moduleValue2 = "moduleValue2";

// src.js
import moduleDefault, { moduleValue1, moduleValue2 } from "./module-commonjs.js";
console.log(moduleDefault);
console.log(moduleValue1, moduleValue2);
Copy the code

2.4.2 Compiling the package result

/ / = = = = = = = = = = compile packaging result = = = = = = = = = = start. / SRC/index. "js" : / *! no exports provided */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__); \n/* harmony import */ var _module_commonjs_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./module-commonjs.js */ \"./src/module-commonjs.js\"); \n/* harmony import */ var _module_commonjs_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_module_commonjs_js__WEBPACK_IMPORTED_MODULE_0__); \n\nconsole.log(_module_commonjs_js__WEBPACK_IMPORTED_MODULE_0___default.a); \nconsole.log(_module_commonjs_js__WEBPACK_IMPORTED_MODULE_0__[\"moduleValue1\"], _module_commonjs_js__WEBPACK_IMPORTED_MODULE_0__[\"moduleValue2\"]); \n\n//# sourceURL=webpack:///./src/index.js?" ); }), "./src/module-commonjs.js": (function(module, exports) { eval("// module-commonjs.js\nexports.moduleValue1 = \"moduleValue1\"; \nexports.moduleValue2 = \"moduleValue2\"; \n\n//# sourceURL=webpack:///./src/module-commonjs.js?" ); }) // ========== compile package result ========== endCopy the code

2.4.3 analysis

/ / = = = = = = = = = = = = = = = = = = = = start / / 2.4.3.1, first from the results of the module - commonjs. Js export object (i.e. __webpack_require__ function return values. The module exports) {  moduleValue1: 'moduleValue1', moduleValue2: 'moduleValue2'} // index.js introduces the common JS module with import // 2.4.3.2 The use of corresponding variables is also translated into the property access of the exported object _module_commonjs_js__webpack_imported_module_0___default. a // Get the default module from __webpack_require__.n _module_es6_js__WEBPACK_IMPORTED_MODULE_0__['moduleValue1'] _module_es6_js__WEBPACK_IMPORTED_MODULE_0__['moduleValue2'] // ========== analysis ========== endCopy the code

Of course, modular standards are not only CommoJs and ES Harmony, but also AMD, CMD, etc., which will not be expanded due to space reasons

【 III 】 Implement the principle of loading on demand (introducing asynchronous modules)

3.1 Introduce the asynchronous module module-dynamic

Let’s take a simple example

// module-dynamic.js export default function (msg) { console.log(msg); } // index.js import("./module-dynamic").then((show) => {// execute show function show("Webpack"); });Copy the code

3.2 Running the NPM run build command

The rebuild outputs two files, the execution entry file bundle.js and the asynchronous loading file 0.bundle.js.

3.2.1 0.bundle.jsThe following

(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{
    "./src/module-dynamic.js":
    (function(module, __webpack_exports__, __webpack_require__) {

    "use strict";
    eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (function (msg) {\n  console.log(msg);\n});\n\n//# sourceURL=webpack:///./src/module-dynamic.js?");
    })
}]);
Copy the code

3.2.2 The bundle.js content after the rebuild is as follows

(function(){/*** * webpackJsonp is used to install modules from asynchronously loaded files. * webpackJsonp is mounted globally for easy invocation in other files. * * @param moreModules list of modules to be installed */ / install a JSONP callback for chunk loading function webpackJsonpCallback(data) { var chunkIds = data[0]; var moreModules = data[1]; // add "moreModules" to the Modules object, // then flag all "chunkIds" as loaded and fire callback Mark all "chunkIds" as loaded VAR moduleId, chunkId, I = 0, convergency = []; for(; i < chunkIds.length; i++) { chunkId = chunkIds[i]; if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) { resolves.push(installedChunks[chunkId][0]); } installedChunks[chunkId] = 0; } // Insert the asynchronous module contents into the main file module object modules, For subsequent use for directly (moduleId in moreModules) {if (Object. The prototype. The hasOwnProperty. Call (moreModules, moduleId)) { modules[moduleId] = moreModules[moduleId]; } } if(parentJsonpFunction) parentJsonpFunction(data); while(resolves.length) { resolves.shift()(); }}; // object to store loaded and loading chunks // undefined = chunk not loaded, null = chunk preloaded/prefetched // Promise = chunk loading, 0 = chunk loaded var installedChunks = { "main": 0 }; // script path function function jsonpScriptSrc(chunkId) { return __webpack_require__.p + "" + chunkId + ".bundle." + "F26a295c3de9e9af4369" + ".js"} File of Chunk to be loaded asynchronously * @param chunkId ID of Chunk to be loaded asynchronously * @returns {Promise} */ __webpack_require__.e = function requireEnsure(chunkId) { var promises = []; // JSONP chunk loading for javascript // Check whether the chunk corresponding to chunkId is successfully installed. InstalledChunkData = installedChunkData [chunkId]; if(installedChunkData ! == 0) {// 0 means "already installed". // A Promise means "currently loading". // installedChunkData is not empty and not 0 indicates the Chunk If (installedChunkData) {promises. Push (installedChunkData[2]); } else { // setup Promise in chunk cache var promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; }); promises.push(installedChunkData[2] = promise); // start chunk loading var script = document.createElement('script'); var onScriptComplete; script.charset = 'utf-8'; script.timeout = 120; if (__webpack_require__.nc) { script.setAttribute("nonce", __webpack_require__.nc); } script.src = jsonpScriptSrc(chunkId); // create error before stack unwound to get useful stacktrace later var error = new Error(); OnScriptComplete = function (event) {// avoid mem leaks in IE. clearTimeout(timeout); var chunk = installedChunks[chunkId]; if(chunk ! == 0) { if(chunk) { var errorType = event && (event.type === 'load' ? 'missing' : event.type); var realSrc = event && event.target && event.target.src; error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')'; error.name = 'ChunkLoadError'; error.type = errorType; error.request = realSrc; chunk[1](error); } installedChunks[chunkId] = undefined; }}; Var timeout = setTimeout(function(){onScriptComplete({type: 'timeout', target: script}); }, 120000); script.onerror = script.onload = onScriptComplete; document.head.appendChild(script); } } return Promise.all(promises); }; var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || []; var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); jsonpArray.push = webpackJsonpCallback; jsonpArray = jsonpArray.slice(); for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); var parentJsonpFunction = oldJsonpFunction; "./src/index.js": (function(module, exports, __webpack_require__) { eval("__webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./module-dynamic */ \"./ SRC /module-dynamic.js\")). Then (function (show) {\n // execute show function \n show(\"Webpack "); \n}); \n\n//# sourceURL=webpack:///./src/index.js?" ); })})Copy the code

The old bundle.js is very similar to the bundle.js that introduced asynchrony. The differences are:

  • 1. InstalledChunks are defined as a cache dynamic module.
  • 2. Define an auxiliary function jsonScriptSrc() that produces the URL of the dynamic module according to chunkId
  • 2. Two more core methods, one__webpack_require__.eThe function loads the files corresponding to the chunk that has been partitioned off and needs to be loaded asynchronously, and returns a Promise object and anotherwebpackJsonCallbackFunction to handle the installation of asynchronous modules;
  • 3. Define awebpackJsonp=[]Global variable used to store modules that need to be dynamically imported.
  • 4, overwrite window.webpackJsonp array push method aswebpackJsonCallbackIs passed when webPackJsonP.push is executedwebpackJsonCallbackTo realize the installation of the module after the completion of asynchronous file loading.

3.2.3 Implementation principle of asynchronous module

Analyze the package results from index.js

  1. After index.js is compiled, the import function actually creates the script dynamically by calling __webpack_require__.e and passing in the chunkId that needs to load the module asynchronously (mapped to the actual file loading path via the jsonpScriptSrc function). Registers the script onLoad event and returns a Promise object at the end

  2. After the asynchronous module is loaded, the script is executed, and window[” webpackJsonp “].push actually points to the webpackJsonpCallback function, which does the following three things:

  • Collect module to mark all “chunkIds” as loaded
  • Insert the contents of the just-loaded asynchronous module into the main file module object Modules for subsequent direct use
  • Rosolve updates the state of the Promise object returned in the previous step
  1. Then through__webpack_require__Access modules, the main file object after the update, get the asynchronous module, and continue to execute the subsequent code logic

Of course, you can specify output file names and so on through magic comments

import(
  /* webpackChunkName: "my-chunk-name" */
  /* webpackMode: "lazy" */
  /* webpackExports: ["default", "named"] */
  './module-dynamic.js'
);
Copy the code

At this point, 0. Bundle.xxx. js will be replaced with my-chunk-name.bundle.xxx.js.

How does Webpack handle non-JS files

4.1 deal with CSS

Webpack itself does not have the ability to process files other than JS. CSS files need to be loaded and processed by plug-ins and loaders. There are two options

  • Package CSS directly into JS. Then create the style tag dynamically through JS to insert the page
  • Instead of putting large chunks of CSS in a page, we put them in a separate file and reference them in our page via link.

4.1.1 Insert a Page using style-loader

Installation dependency: style-loader CSS-loader

Bunld. js "./node_modules/css-loader/dist/ css.js! ./src/css/main.css": (function(module, __webpack_exports__, __webpack_require__) { // ... CSS - loader to load the main CSS processing details (include the CSS code may introduce other CSS files)}), ".. / node_modules/CSS - loader/dist/runtime API. Js ": (function(module, exports, __webpack_require__) { // ... Omit the CSS - loader runtime}), ".. / node_modules/style - loader/dist/runtime/injectStylesIntoStyleTag js ": (function(module, exports, __webpack_require__) { // ... Omit style-loader runtime}), "./ SRC/CSS /main.css": (function(module, __webpack_exports__, __webpack_require__) { "use strict"; eval("__webpack_require__.r(__webpack_exports__); var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(\"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\"); var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = __webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);  var _node_modules_css_loader_dist_cjs_js_main_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(\"./node_modules/css-loader/dist/cjs.js! ./src/css/main.css\"); var options = {}; options.insert = \"head\"; options.singleton = false; var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules _css_loader_dist_cjs_js_main_css__WEBPACK_IMPORTED_MODULE_1__[\"default\"], options); __webpack_exports__[\"default\"] = (_node_modules_css_loader_dist_cjs_js_main_css__WEBPACK_IMPORTED_MODULE_1__[\"default\"].locals || {});" ); // 4.1 Load the main. CSS file through the CSS-loader runtime API to obtain objects that conform to the CommonJS specification // 4.1 Use the style-loader runtime API Insert the CSS module object from the previous step into the HTML dynamically with the style tagCopy the code
  • Css-loader is used to convert CSS to CommonJS objects, meaning that the style code will be placed in the JS.
  • Style-loader inserting styles is a dynamic process. Viewing the packaged HTML source code will not see HTML with style styles. Style-loader dynamically creates a style tag at runtime and inserts CSS styles into the style tag

4.1.2 Extract separate CSS files with the help of mini-CSs-extract-plugin

Install dependency: mini-CSS-extract-plugin CSS-loader

// 1, configure webpack.config.js const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { module: { rules: [ { test: /\.css$/, use: [MiniCssExtractPlugin. Loader, "CSS - loader"], / / analytical principles}}] from right to left, the plugins: [new MiniCssExtractPlugin({new MiniCssExtractPlugin({new MiniCssExtractPlugin({new MiniCssExtractPlugin({new MiniCssExtractPlugin({new MiniCssExtractPlugin({new MiniCssExtractPlugin({new MiniCssExtractPlugin({new MiniCssExtractPlugin(}))}) { "css/[name].[hash].css", chunkFilename: "css/[id].[hash].css", CSS import './main. CSS '// 3, execute NPM run build analysis package file // 3.1 package result add CSS /main.xxx. CSS file // 3.2 Index. HTML Header Links the CSS file in this path through the linkCopy the code

4.2 Processing pictures and fonts

Wepack processing picture, font scheme is through urL-loader,file-loader to complete modular conversion. The general principle is as follows:

With urL-loader, images or font files smaller than 10K are automatically converted to Base64 during the build phase by modifying the Webpack configuration. If there are many images, many HTTP requests will be sent, which degrades page performance. Url-loader will encode the imported image and generate the dataURl. It is equivalent to translating the image data into a string of characters. Package the string into a file, and eventually you just need to import the file to access the image. Of course, encoding costs performance if the image is large. Therefore, url-loader provides a limit parameter. Files smaller than limit bytes are converted to DataURl, and files larger than limit are copied using file-loader.

4.2.1 Transfer base64 encoding using URL-loader

/ SRC /images/ no you don't understand. PNG ": (function(module, __webpack_exports__, __webpack_require__) {"use strict"; eval("__webpack_require__.r(__webpack_exports__); \n/* harmony default export */ __webpack_exports__[\"default\"] = (\"data:image/png; base64,...... Omit base64 encoding \"); \n)})Copy the code

4.2.1 Using file-loader to Copy a File

File-loader itself does not convert any of the file contents, but just copies the file contents and generates a unique file name for it according to its configuration. The approximate output is as follows:

"./ SRC /images/ No you don't get it.png ": (function(module, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__); N /* Harmony default export */ __webpack_exports__[\"default\"] = (__webpack_require__.p + \"img/ no you don't understand.adb0f5d9.png \"); \n\n//# sourceURL=webpack:///./src/images/%E4%B8%8D%E4%BD%A0%E6%B2%A1%E6%87%82.png?" ); })Copy the code

Access the actual file path by concatenating it with __webpack_require__.p

[5] Supplement — introduction of non-modules

The webPack package treats everything as a module, but in practical use scenarios, there are still modules that do not support the modularity specification that are used through global variables, but we want it to be exported as module content.

5.1 Take an example

// hello.js
var Hello = window.Hello = function(){
    console.log('hello from global Hello() function');
};

// index.js
var Hello = require('./hello.js');
Hello();
Copy the code

Hello.js does not export the module, so the index. Js file fails to find the hello function

5.2 the use ofexports-loaderExport some global variables as module content

npm install exports-loader@1 --save-dev import Hello from "exports-loader? exports=Hello! ./hello.js";Copy the code

5.3 Viewing the Packing Result

"./node_modules/exports-loader/dist/cjs.js? exports=Hello! ./src/hello.js": (function(module, __webpack_exports__, __webpack_require__) { //.. __webpack_require__.d(__webpack_exports__, \"Hello\", function() {return Hello; }})Copy the code

[vi] Output specified modular specifications

Webpack provides these fields to accommodate the output of different modularity scenarios

  • output.library: Specifies the name of the exported module. Support string or object. How can its value be used depending on the value of output.libraryTarget
  • output.libraryTargetSupport string, which controls how webpack content is exposed, default var
Exposed way value
Expose a variable Var, the assign
Exposure by object properties This, window, global, commonJS
Module definition system Commonjs2, AMD, UMD
  • output.libraryExport: Specifies an attribute of the module as the export object