Webpack can be used to package applications as well as JS libraries.

Let’s use an example to show how to package a JS library with Webpack.

Our goal is to achieve a large integer plus library package.

  • You need to package the compressed and uncompressed versions
  • Support AMD/Commonjs/ES6 Module introduction.
  • Support direct import using script tags

1. Create a project directory

// Enter in terminal
mkdir npm-large-number
cd npm-large-number
npm init -y
Copy the code

2. Install Webpack & WebPack-CLI

npm i webpack webpack-cli -D

3. Open the project and create files/folders to form the following directory structure

4. Write code

  1. SRC folder index.js writes a method to add large integers:
// src/index.js
export default function add (a, b) {
    let i = a.length - 1;
    let j = b.length - 1;
    let res = ' '; / / the result
    let carray = 0; / / carry value
    while (i >= 0 || j >= 0) {
        let x = 0;
        let y = 0;
        let sum;
        if (i >=  0) {
            x = a[i] - '0'; // Convert to a number
            i --;
        }
        if (j >=  0) {
            y = b[j] - '0'; // Convert to a number
            j --;
        }
        sum = x + y + carray;
        if (sum >= 10) {
            carray = 1;
            sum -= 10;
        } else {
            carray = 0;
        }
        res = sum + res;
    }
    if (carray > 0) {
        res = carray + res;
    }
    return res;
}
// add('1', '999');
// add('999', '1');
// add('123', '456');
Copy the code
  1. Run NPM install terser-webpack-plugin -d to install terser-webpack-plugin

  2. The configuration of webpack.config.js is as follows:

// webpack.config.js
Uglifyjs (version 3.0 support)
const TerserWebpackPlugin = require('terser-webpack-plugin');

module.exports = {
    mode: "none".entry: {
        'large-number': './src/index.js'.'large-number.min': './src/index.js'
    },
    output: {
        filename: '[name].js'.library: 'largeNumber'.// Specify the name of the library and its global variables
        libraryTarget: 'umd'.// Support the way libraries are introduced
        libraryExport: 'default'
    },
    optimization: {
        minimize: true.minimizer: [
            new TerserWebpackPlugin({
                include: /\.min\.js$/}}})];Copy the code

About Library and libraryTarget

How library values are used varies depending on the libraryTarget. The libraryTarget configuration controls how webPack packaged content is exposed. In our example, the library value is largeNumber. We use _entry_return_ to represent the value returned by the entry point.

The value of libraryTarget has the following values:

  • Var: The default. With this configuration, the value returned by the package is bound to a variable specified by the library, regardless of how the package is referenced
var largeNumber = _entry_return_;

// The usage mode
largeNumber();
Copy the code
  • Assign: With this setting, the library return value is assigned to a variable not declared using var. If the variable is not previously declared in the import scope, it will be mounted in the global scope. (Note that this behavior may overwrite existing variables in the global scope.)
largeNumber = _entry_return_;
Copy the code
  • This: Assigns the library return value to the Library-specified property of this object. The meaning of this is determined by the user.
this["largeNumber"] = _entry_return_;

// The usage mode
this.largeNumber();
Copy the code
  • Window: The Library-specified property that assigns the library return value to the window object.
window["largeNumber"] = _entry_return_;

// The usage mode
window.largeNumber.doSomething();
Copy the code
  • Global: The library-specified property that assigns the library’s return value to the Global object.
global["largeNumber"] = _entry_return_;

// The usage mode
global.largeNumber.doSomething();
Copy the code
  • Commonjs: Assigns the return value of the library to a Library-specified property of an Exports object. As the name suggests, this option can be used in the CommonJS environment.
exports["largeNumber"] = _entry_return_;

// The usage mode
require("largeNumber").doSomething();
Copy the code
  • Commonjs2: Assigns the return value of the library to module.exports. Note that output.library is not required in this case because the output.library option will be ignored.
module.exports = _entry_return_;

// The usage mode
const largeNumber = require("largeNumber");
largeNumber();
Copy the code
  • Amd: This option exports the library as an AMD module.
define("largeNumber"[],function() {
	return _entry_return_;
});

// The usage mode
require(['largeNumber'].function(largeNumber) {
	// Do something with the library...
	largeNumber();
});
Copy the code
  • Umd: This option attempts to expose the library to the current module-definition system in use, which makes it compatible with CommonJS and AMD, or exposes it as a global variable.
(function webpackUniversalModuleDefinition(root, factory) {
  if(typeof exports= = ='object' && typeof module= = ='object')
    module.exports = factory();
  else if(typeof define === 'function' && define.amd)
    define([], factory);
  else {
    var a = factory();
    for(var i in a) (typeof exports= = ='object' ? exports : root)[i] = a[i];
  }
})(this.function() {
	return _entry_return_;
});
Copy the code
  • Jsonp: This method wraps the results in jSONP style

Starting with WebPack 3.10.0, we can control the output of different target environments by defining library as an object.

	largeNumber(_entry_return_);
Copy the code
  1. The index.js file in the root directory is used to import the appropriate JS file based on the environment
// index.js
if (process.env.NODE_ENV === "production") {
    module.exports =  require('./dist/large-number.min.js');
} else {
    module.exports =  require('./dist/large-number.js');
}
Copy the code

Package. json adds the packaging command

{
  "name": "npm-large-number"."version": "1.0.0"."description": "Large integer addition NPM package"."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."build": "rimraf ./dist && webpack"."prepublish": "npm run build"
  },
  "keywords": []."author": ""."license": "ISC"."devDependencies": {
    "terser-webpack-plugin": "^ 4.1.0." "."webpack": "^ 4.44.1"."webpack-cli": "^" 3.3.12}}Copy the code
  1. You can then execute the NPM run build and see that there are two files in the Dist file, one compressed and one uncompressed.

5. Publish the NPM package

  1. Run NPM adduser and enter the user name, password, and email address
  2. Perform NPM publish

6. Reference tests

  1. NPM install NPM – large-number-s
  2. Introduced in the project
import largeNumber from 'npm-large-number';

var res = largeNumber('999'.'1');
console.log(res);
Copy the code

Another article on writing an NPM package:

How do I publish my own NPM package?