This is the fourth day of my participation in the November Gwen Challenge. Check out the details: The last Gwen Challenge 2021

Some time ago, I found that the company had a project, and the packaged volume was relatively large, so I optimized the project. During optimization, it was found that some packages were repeatedly referenced in different components, resulting in multiple packages being packaged into the output bundle file. Then the investigation found another webpack property, Externals

Externals

Instead of packing imported packages into the bundle, obtain these external dependencies at runtime.

This is the explanation given on webpack’s official website. Here we take a look at the phenomenon in detail:

File test. Js

import $ from 'jquery'
 
$('.main').animate(/ *... * /);
Copy the code

Publish this library using a Webpack package:

// Import file
entry: {
  test: './test.js',}// Output file
output: {
  path: './dist'.filename: 'bundle.js'
}
Copy the code

This bundled bundle.js file will inject jquery code in its entirety, since it’s used in your test.

But this is not always what we expect, because jquery is such a generic module that it is likely to be used by other files in a project. If each release of a file module has jquery bundled into its own bundle and put together, There will be a lot of copies of jquery in the final release, which will not affect its functionality, but will take up a lot of code, which is clearly not what we expected.

So in general, when your library needs to rely on generic JS modules such as jquery and Bootstrap, you can declare external in the Webpack configuration instead of packing it into a bundle:

externals: {
  jquery: {
    root: 'jquery'.commonjs: 'jquery'.commonjs2: 'jquery'.amd: 'jquery',}},Copy the code
  • Root: The Library can be accessed through a global variable (for example, through the script tag).

  • Commonjs: Library can be accessed as a CommonJS module.

  • Commonjs2: same as above, but exports module.exports.default.

  • Amd: Similar to CommonJS, but using amd module system.

    This way, jquery won’t be packaged into our files

    Externals can be passed in a number of different forms, but in summary, it’s really array, object, reg

1, the array

Each element in an array can have multiple forms, including Object, reg, function, string, etc

externals: [
  { // Object
        a: false.// a is not external
        b: true.// b is external `module.exports = b`
        "./c": "c".// "./c" is external `module.exports = c`
        "./d": "var d".// "./d" is external `module.exports = ./d` 
        "./f": "commonjs2 ./a/b".// "./f" is external `module.exports = require("./a/b")`
        "./f": "commonjs ./a/b"./ / same as above
    },
 
   
    /^[a-z\-0-9]+$/.// reg
 
    function(context, request, callback) { // ③ function
        if(/^global-/.test(request))
        return callback(null."var " + request.substr(7));
        callback();
    },
 
    "./e" / / ". / e is "external (the require (". / e")) / / (4) the string form
]
Copy the code

2. The object

Array has the form “object”, which can also be used as externals.

This is probably the configuration in most projects, and it’s the one we see most often. The object form is the most complex, because it must contain the form key: value, so the above form string cannot appear in the object form, of course, function and reg cannot appear in the object form

The following code:

externals: {
  a: false.// a is not external
  b: true.// b is external `module.exports = b`
 
  jquery: 'jQuery'.// This is the way to use it
  lodash : { // This is the same as the above, but in more detail
    commonjs: "lodash".amd: "lodash".root: "_" // indicates global variable
  },
  
    "./c": "c".// "./c" is external `module.exports = c`
    "./d": "var d".// "./d" is external `module.exports = ./d` 
    "./f": "commonjs2 ./a/b".// "./f" is external `module.exports = require("./a/b")`
    "./f": "commonjs ./a/b"./ /... same as commonjs2
    "./f": "this ./a/b".// "./f" is external `(function() { module.exports = this["./a/b"]; `} ())
}
Copy the code

The value of object is Boolean, string, array and object.

Externals can also be excluded from internal modules.

That is, if you use something like require(‘./d’) in your code, you don’t need to include the contents of the d.js file, but their values are strings.

3. Reg form

This is the form of regular matching, which is implemented by passing in the regular expression /reg/ or new RegExp(). This is already used in the array form above, but we can pass the regular reg directly to externals for some kind of match:

externals: /^[a-z\-0-9]+$/
Copy the code

Note:

The result of each bundle can be different. Typically, if your bundle is intended to run in the Node environment, your bundle may use the module.exports interface. Umd compatibility schemes are often required, so a require(‘underscore’) in your source code may have different results inside the bundle file after being packaged for different environments

The libraryTarget parameter is used to determine which module organization your bundle follows. There are several types of libraryTarget:

"var" - Export by setting a variable: var Library = xxx (default)
"this" - Export by setting a property of this: this["Library"] = xxx
"commonjs" - Export by setting a property of exports: exports["Library"] = xxx
"commonjs2" - Export by setting module.exports: module.exports = xxx
"amd" - Export to AMD (optionally named - set the name via the library option)
"umd" - Export to AMD, CommonJS2 or as property in root
'amd-require'
'assign'
'commonjs-module'
'global'
'import' - uses import() to load a native EcmaScript module (async module)
'jsonp'
'module'
'node-commonjs'
'promise'- and'var'Same, but willawaitResults (apply toasyncModule)'self'
'system'
'script'
'umd2'
'window'
Copy the code

Here’s an example: Module. exports = jquery; module. Exports = require(‘jquery’); That’s the difference between using string. Note that when you package a package for Node, you should add the commonJS prefix to the externals string

Summary:

The above is about the use of the external option of Webpack. It is suggested to look at the generated file of Webpack, so that we can know how to do external, and also convenient for us to go to the debugger problem

Reference: Webpack Chinese documentation