Use webpack to package components and base libraries and publish them to npm

In addition to packaging applications, webpack can also be used to package js libraries and some custom component libraries.

Just package js library and component library rollup Packing is also a good choice.

Let's implement a simple Packaging example, which needs to meet the following functions:

  1. Package compression Version (X min.js )And uncompressed versions (x.js).

  2. Support the introduction of AMD/CJS/ESM module.

  3. It supports direct introduction of links through script scripts.

// ESM
import * as Tool from 'tools';

//cjs
const Tool = require('tools');

// AMD
require(['tools'],function(){
  ...
})

// Script script
<script src="https://xxx.com/tools"></script>

How to expose the library?

  • Library: Specifies the global variable of the library

  • libraryTarget: a way to support the introduction of Libraries

module.exports = {
   mode: 'production',
   entry: {
     tools: "./src/index.js",
     tools.min: "./src/index.js"
   },
   output:{
     filename: "[name].js",
     library: "tools",
     libraryExport: "default",
     libraryTarget: "umd",// var this window ...
   }
}

Let's start the show:

1. Create a new project webpack build tools to install webpack and webpack cli

mkdir webpack-build-tools

cd webpack-build-tools

npm init -y

npm i webpack webpack-cli

2. Create a new directory src/index.js , write our tool code

The code here comes from JS tips under my blog, which is only used as an example

/**
 * Convert null undefined in parameter to null
 * @param {String} el 
 */
export function transferDefectParams(el) {
    return ['null', 'undefined'].includes(el) ? '' : el
}

/**
 * Regular representation
 * Idea: get the parameters on the url through regular expression and append them to the object through the array reduce
 * 
 * @param {string} url The url address to be obtained defaults to the current address
 */
export default function getUrlParameters(url = window.location.href) {
    /**
     * match Return array of matching results in string, return null if no match is found
     * [^?=&]+ Match characters other than? = & only once
     * Array.reduce(callBack(prev,cur,index,array), initialValue)
     * Array.slice(start,[end]) Return the start end element
     */
    const params = url.match(/([^?=&]+)=([^&]*)/g)
    if (params) {
        return params.reduce((a, v) => (a[v.slice(0, v.indexOf('='))] = transferDefectParams(v.slice(v.indexOf('=') + 1)), a), {})
    }
    return {}
}

3. Install the terser webpack plugin compression plug-in

npm i terser-webpack-plugin -D

4. NEW webpack.config.js

const TerserPlugin = require('terser-webpack-plugin') // Introducing compression plug-ins

module.exports = {
    mode: 'none', // Because the default is production, which will compress by default
    entry: {
        "tools": "./src/index.js",
        "tools.min": "./src/index.js"
    },
    output: {
        filename: "[name].js",
        library: "tools",
        libraryExport: "default", // If not, you need to tools.default
        libraryTarget: "umd", // var this window ...
    },
    optimization: {
        minimize: true,
        minimizer: [
            new TerserPlugin({ // Using compression plug-ins
                include: /\.min\.js$/
            })
        ]
    }
}

5. Modification package.json Add package command

{
  "name": "webpack-build-tools",
  "version": "1.0.0",
  "description": "js Common tool functions",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "prepublish": "webpack"
  },
  "keywords": [
    "webpack-build-tools"
  ],
  "author": "xjl271314",
  "license": "ISC",
  "dependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11"
  },
  "devDependencies": {
    "terser-webpack-plugin": "^3.0.1"
  }
}

6. Package and check the packaging effect

npm run build

// tools.js
(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else if(typeof exports === 'object')
		exports["tools"] = factory();
	else
		root["tools"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	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] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.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 = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "transferDefectParams", function() { return transferDefectParams; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return getUrlParameters; });
/**
 * Convert null undefined in parameter to null
 * @param {String} el 
 */
function transferDefectParams(el) {
    return ['null', 'undefined'].includes(el) ? '' : el
}

/**
 * Regular representation
 * Idea: get the parameters on the url through regular expression and append them to the object through the array reduce
 * 
 * @param {string} url The url address to be obtained defaults to the current address
 */
function getUrlParameters(url = window.location.href) {
    /**
     * match Return array of matching results in string, return null if no match is found
     * [^?=&]+ Match characters other than? = & only once
     * Array.reduce(callBack(prev,cur,index,array), initialValue)
     * Array.slice(start,[end]) Return the start end element
     */
    const params = url.match(/([^?=&]+)=([^&]*)/g)
    if (params) {
        return params.reduce((a, v) => (a[v.slice(0, v.indexOf('='))] = transferDefectParams(v.slice(v.indexOf('=') + 1)), a), {})
    }
    return {}
}

/***/ })
/******/ ])["default"];
});
// tools.min.js
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.tools=t():e.tools=t()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";function r(e){return["null","undefined"].includes(e)?"":e}function o(e=window.location.href){const t=e.match(/([^?=&]+)=([^&]*)/g);return t?t.reduce((e,t)=>(e[t.slice(0,t.indexOf("="))]=r(t.slice(t.indexOf("=")+1)),e),{}):{}}n.r(t),n.d(t,"transferDefectParams",(function(){return r})),n.d(t,"default",(function(){return o}))}]).default}));

7. Set the entry file to use different entry files in different environments

package.json The main field in is index.js , so create a new one under the project root index.js

// index.js
if (process.env.NODE_ENV === 'production') { // Determine the entry file through the environment variable
    module.exports = require('./dist/tools.min.js')
} else {
    module.exports = require('./dist/tools.js')
}

8. Publish npm package (need to register npm account and log in)

npm publish

9. Synchronize the code to git, and write corresponding instruction documents, etc

// Other project references
npm i tools -s

import getUrlParameters from 'tools';

Full code see github address

Tags: Webpack npm JSON git

Posted on Wed, 20 May 2020 10:56:21 -0400 by Tubby