before the article analyzes the basic principle of Webpack package JS module, the case is one of the most common situation, namely a JS module and an entrance module, packaged into a bundle file, can be directly by the browser or other JavaScript engines, equivalent to direct the compiler generates a complete executable file. But there is a common case that we need to build a library that releases JavaScript. For example, when you publish your library in NPM community, Webpack needs corresponding configuration, and the code generated by compilation is also slightly different.

and before an article, this article mainly analyzes the generated Webpack code, and combines it to illustrate the compiler library Webpack about library configuration options for the specific role of the corresponding official document in here.

prepared JS library

we started from a simple case, we can write a simple library util.js:

 import $from'jquery'function (sayHello) {console.log ("Hello");} function (hideImages) {$('img').Hide (export);} default {sayHello:, sayHello, hideImages: hideImages} 

provides two functions, of course, there is no relationship between them, also do not actually have any eggs, is purely for teaching reference...

then write Webpack configuration:

 / entry: util:'./util.js'entrance file {}, / / output file output: {path:'./dist'} 

'[name].dist.js'filename:, but that is not enough, so that the output file is an immediate execution function, finally returns util.js exports, according to the analysis on an article in bundle, the code structure of last generation is roughly like this:

 (function (modules) {var installedModules = {}; function webpack_require (moduleId) {} / /... Return webpack_require ('./util.js');}) ({'./util.js': generated_util,'/path/to/jquery.js': generated_jquery 

}); if it is executed, then the end, export util.js returns it, and we need is this The return value is given to the module.export of the compiled file, so that the compiled file becomes a library that can be used by other people's import. So we hope to get the compiled file should be like this:

 = module.exports (function (modules) {var installedModules = {}; function webpack_require (moduleId) {} / /... Return webpack_require ('./util.js');}) ('./ {util.js': generated_util,'/path/to/jquery.js': generated_jquery 

;}) to get such a result. Webpack, output joined library configuration information:

 output: path:'./dist' {/ / entrance file, filename:'[name].dist.js', library:'util', libraryTarget: commonjs2 

} here is the most important libraryTarget, we now use the commonjs2 format, will be compiled the results above, it is said that Webpack library will put the final output to export CommonJS in the form of such The release of a library has been implemented.

other release format in addition to commonjs2, libraryTarget and other options:

 var (the default, published as a global variable) commonjs commonjs2 amd UMD 

using different options, the compiled file can be executed in different environments using JavaScript. Here we look directly output UMD format of the Tiger Balm is about:

 (function webpackUniversalModuleDefinition (root, factory) {if (typeof = exports'object'& & typeof; module ='object') / / commonjs2 (module.exports = factory); else if (typeof define'function'& define.amd = & (define) "util, [], factory); / / AMD else if (typeof exports ='object') exports[= Factory (" util "); / / commonjs else root[" util "] = Factory (); / / var}) (window, function) {return ((function (modules) {var installedModules = {}; function webpack_require (moduleId) {} / /... Return webpack_require ('./util.js'));} ({'./util.js': generated_util,'/path/to/jquery.js': generated_jquery});} < 

P> is much more complex than the previous commonjs2, because it needs to deal with various case, but in fact, the following parts are the same. The most important thing is the first few lines, which is the standard writing method of UMD module. It runs the incoming factory function, in fact the function of the load module, and then the returned result is given to the corresponding object according to the different running environment. For example, VAR will set the result as a global variable, which is used for browser directly importing the JS file through < script> tag; if it is CommonJS, it will be sent to exports object; if it is AMD environment, it is also written by standard AMD. This release of the JS library can be used by other people in any environment.


control output if packaged with UMD format, there may be a need to pay attention to the pit, if your library source code is output by ES6 format export default util.js, as the example above, you directly to the compiled JS library files into the browser, can be < script>, or RequireJS, may not be able to get the results you want. This is because your JS file back to your object is this:

: sayHello: {'default'{sayHello}}, hideImages: hideImages 

rather than you expect:

 sayHello {sayHello:, hideImages:} hideImages 

is not only in the browser module system does not support ES6 also will be this problem is because they do not know default. So you actually compiled JS file should only output default, it will need to use targetExport to control the Webpack configuration:

libraryTarget: UMD, factory

loading function module

above will be followed by a return value of ['default'], it only returns exports default part.

of the pit under UMD format, but it is still very easy to step on, for example, you release a Vue component, JavaScript.Vue file is in the Component object is to derive the format of export default,

 export default like this: 

{name:'xxx'data: {return}, {props: / /... {methods:} / /... / /...}}

if you have compiled JS files directly in the browser, and with the way CDN by < script> loading Vue, you will find that Vue does not recognize the Component, because the object you get a layer of unnecessary default.

you may ask if I change the output to default, will it affect the use of this module in the ES6 environment? Generally speaking, it is not. Before an article has been talked about, the formation of Webpack code in the introduction of a module, through a __esModule value to set and determine whether it is not the format of ES6 export, now only if the derived default part, then the object is regarded as a non ES6, because it does not contain __esModule. So when other modules are introduced into the module through import, the whole object will be introduced, which in fact is equivalent to introducing the export default part of the original module in a disguised way.

, of course, is on the premise that all your needs for export are all in export default. If you have both a default and a normal export, the compiled file that exports only the default part is obviously not.

is the whole content of this article, I hope to help you, and hope that you can support a lot of scripting home.

you might be interested in this article:

This concludes the body part

This paper fixed link: | Script Home | +Copy Link

Article reprint please specify:The principle and implementation of webpack organization module packaging Library | Script Home

You may also be interested in these articles!