{"id":22443117,"url":"https://github.com/riversun/making-library-with-webpack","last_synced_at":"2025-08-01T18:33:59.779Z","repository":{"id":38997684,"uuid":"243698524","full_name":"riversun/making-library-with-webpack","owner":"riversun","description":"How to build a library that supports both browser and Node.js using webpack4 and ES6","archived":false,"fork":false,"pushed_at":"2023-01-07T04:50:29.000Z","size":2831,"stargazers_count":41,"open_issues_count":74,"forks_count":11,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-24T12:42:46.344Z","etag":null,"topics":["build","javascript","javascript-library","library","make","webpack"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/riversun.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-28T06:56:32.000Z","updated_at":"2024-01-26T11:11:03.000Z","dependencies_parsed_at":"2023-02-06T12:16:02.970Z","dependency_job_id":null,"html_url":"https://github.com/riversun/making-library-with-webpack","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riversun%2Fmaking-library-with-webpack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riversun%2Fmaking-library-with-webpack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riversun%2Fmaking-library-with-webpack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/riversun%2Fmaking-library-with-webpack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/riversun","download_url":"https://codeload.github.com/riversun/making-library-with-webpack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228398828,"owners_count":17913680,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["build","javascript","javascript-library","library","make","webpack"],"created_at":"2024-12-06T02:22:41.137Z","updated_at":"2024-12-06T02:22:41.862Z","avatar_url":"https://github.com/riversun.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Recipes on how to create a library using webpack\n\n## About\nIntroduces how to build a library that **supports both browser and Node.js** using webpack4 and ES6, and how to use the created library.\n\nThere are two ways to create a library that supports both browser and node.js.\n\n![image](https://user-images.githubusercontent.com/11747460/75525983-3ae41400-5a54-11ea-9d31-279ee9dd0065.png)\n\n- **One bundle**:  \nThe first is a method that covers **both browser and Node.js** with one bundle.\nIn this article, we'll take a closer look at how to create one bundle for both browser and Node.js.\n\n- **Two bundles**:  \nThe second is to build libraries for browser and node.js separately.\n\n## How to run examples\n\nStep 1.Clone this repository.\n\nStep2.Go to example directory like \"part_1_1\"\n\n```\ncd part_1_1\n```\n \nStep3.Run 'npm start' after `npm install` to start examples.\n\n```\nnpm install\nnpm start\n```\n \n\n## 1.One class in the library\n### 1-1.Publish an \"export default\" class.\n\n#### Build configuration\n\nBuild configuration is as follows\n\n**family.js** is the source code of the library to be published\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: '',\n    libraryExport: '',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_1/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n\n\n#### Source code of the **library**\n\n**family.js** has a class named **Tom** with a single method **sayHello**.\nWe will see how to turn this into a library.\n\n\n**family.js**\n\n```javascript\nexport default class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\n```\n\n#### Source code for using this library\n\n●Using from **Browser**\n\n```html\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const Tom = window.default;\n    const tom = new Tom();\n    console.log(tom.sayHello());\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_1/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\n\n●Using from **Node.js**\n\n```javascript\nconst Lib = require('./mylib.min.js');\nconst Tom = Lib.default;\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\nAlso works with the following code,\n\n```javascript\nconst Tom = require('./mylib.min.js').default;\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\n●Example of using **ES6's import** statement\n\n```javascript\nimport * as Lib from './mylib.min.js';\nconst Tom = Lib.default;\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\nAlso works with the following code,\n\n```javascript\nimport {default as Tom} from './mylib.min.js';\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\nor\n\n```javascript\nimport Tom from './mylib.min.js';//Pick default\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\n●**Tips** for this recipe\n\n\u003cfont color=blue\u003e**Point 1:**\u003c/font\u003eWhat does **globalObject: 'this'** mean?\n\nThe webpacked bundle **mylib.min.js** is as follows.\n\n```javascript\n(function webpackUniversalModuleDefinition(root, factory) {\n    if(typeof exports === 'object' \u0026\u0026 typeof module === 'object')\n        module.exports = factory();\n    else if(typeof define === 'function' \u0026\u0026 define.amd)\n        define([], factory);\n    else {\n        var a = factory();\n        for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n    }\n})(this, function() {...});\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_1/mylib.develop.js\" target=\"_blank\"\u003eSee full source code of bundle(develop build)\u003c/a\u003e\n\nThis is an immediate function with `(this, function ())` as its argument.\nThis `this` is caused by setting **globalObject: 'this'**.\nIf you do not specify **globalObject:**,\nthe argument of this immediate function will be `(window, function ())`.\nIt works on browsers that have a `window` object,\nbut cannot be run on **node.js** that does not have a **window** object.\nAs you might expect, if you try the above, you will get `ReferenceError: window is not defined`.\nSo if you want to support **both browser and node.js**, \ndon't forget to include **globalObject: 'this'**.\n\n\u003cfont color=blue\u003e**Point 2:**\u003c/font\u003eClasses you want to publish are stored with the key \"**default**\"\n\nIf you want to access the classes published in the library,\nUse `require('./mylib.min.js').default` on node.js and use `window.default`(=window[\"default\"]) on the browser. \n\nRemember that in this configuration, the class is identified by the key **default**.\n\n### 1-2.Publish an \"export default\" class **with library name** (like namespace).\n\nThe library name (namespace) can be set by specifying **output.library: 'MyLibrary'** in webpack.config.js.\n\n#### Build Configuration\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: 'MyLibrary',\n    libraryExport: '',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_2/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n\n#### Source code of the **library**\n\n**family.js**\n\n```javascript\nexport default class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\n```\n\n#### Source code for using this library\n\n●Using from **Browser**\n\nSee below.\n**Tom class** can be used as **MyLibrary.default**.\n\n```javascript\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const Tom = MyLibrary.default;\n    const tom = new Tom();\n    console.log(tom.sayHello());\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_2/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\n\n●Using from **Node.js**\n\nNote that in case of node.js (CommonJS2), \u003cfont color=red\u003elibrary name is ignored \u003c/font\u003e.\nSo **output.library: 'MyLibrary'** does not work for node.js.\n\n```javascript\nconst Lib = require('./mylib.min.js');\nconst Tom = Lib.default;\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\n●Example of using **ES6's import** statement\n\n```javascript\nimport * as Lib from './mylib.min.js';\nconst Tom = Lib.default;\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\n### 1-3.Publish an \"export default\" class **with** library name **without** using the **default property**.\n\nYou want to access a class without using \"default\" which looks redundant like below.\n\n```javascript\nconst Tom = MyLibrary.default;　\n```\n\n\n#### Build Configuration\n\nTry to set `output.libraryExport: 'default'`\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: 'MyLibrary',\n    libraryExport: 'default',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_3/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n#### Source code of the **library**\n\n**family.js**\n\n```javascript\nexport default class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\n```\n\n#### Source code for using this library\n\n\n●Using from **Browser**\n\nLet's build the library with this configuration.\nThen, instead of `MyLibrary.default`,\n`MyLibrary` itself equals to a reference of `Tom` class.\n\n```javascript\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const Tom = MyLibrary;\n    const tom = new Tom();\n    console.log(tom.sayHello());\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_3/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\n\n●Using from **Node.js**\n\nAs mentioned above, in case of node.js (CommonJS2), \u003cfont color=red\u003elibrary name is ignored \u003c/font\u003e.\n\n```javascript\nconst Tom = require('./mylib.min.js');\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\n●Example of using **ES6's import** statement\n\n```javascript\nimport Tom  from './mylib.min.js';\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\n### 1-4.Publish an \"export default\" class with the setting **\"library name = class name\"**.\n\n\n#### Build Configuration\n\n- Set `output.libraryExport: 'default'`\n- Make library name the same as class name like `output.library: 'Tom'`\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: 'Tom',\n    libraryExport: 'default',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_4/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n\n#### Source code of the **library**\n\n**family.js**\n\n```javascript\nexport default class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\n```\n\n#### Source code for using this library\n\n\n●Using from **Browser**\n\n```javascript\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const tom = new Tom();\n    console.log(tom.sayHello());\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_4/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\n●Using from **Node.js**\n\n```javascript\nconst Tom = require('./mylib.min.js');\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\n●Example of using **ES6's import** statement\n\n```javascript\nimport Tom from './mylib.min.js';\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\n●**Tips** for this recipe\n\nIt can be accessed from the browser and node.js with the symbol **Tom**.\nThis configuration is one of my favorites.\n\n### 1-5.Publish an \"export default\" class in a way called \"reexport\".\n\nPublish the library using re-export.\nRe-export means exporting one module from another.\n\n#### Build Configuration\n\nChange \u003cfont color=blue\u003e**entry**\u003c/font\u003e to \u003cfont color=blue\u003e**index.js**\u003c/font\u003e to re-export from index.js.\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/index.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: '',\n    libraryExport: '',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_5/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n#### Source code of the **library**\n\nNow, let's create **index.js** and re-export the **Tom class** in **family.js** from there.\n\n```javascript\nexport {default as Tom} from './family.js';\n```\n\n\u003cfont color = gray\u003e**Tom** is \"**export**\"ed by **{default as Tom}** \nwhen reexporting by index.js. So, strictly speaking, this method is no longer \"**default export**\".\u003c/font\u003e\n\n\n**family.js**\n\n```javascript\nexport default class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\n```\n\n#### Source code for using this library\n\n\n●Using from **Browser**\n\n```javascript\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const tom = new Tom();\n    console.log(tom.sayHello());\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_1_5/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\n\n●Using from **Node.js**\n\nWe use [destructuring assignment](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) to get the **Tom** class.\n\n```javascript\nconst {Tom} = require('./mylib.min.js');\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n\n```\n\n●Example of using **ES6's import** statement\n\n```javascript\nimport {Tom} from './mylib.min.js';\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\n## 2.Multiple classes in the library\n\n### 2-1.Publish **multiple classes**\n\nLet's look at some examples of publishing multiple classes.\n(You can publish not just classes but functions or variables in the same way.)\n\n#### Source code of the **library**\n\nAs you can see, the following **family.js** contains two classes **Tom** and **Jack**.\n\n**family.js**\n\n```javascript\nexport class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\nexport class Jack {\n    sayHello() {\n        return 'Hi, I am Jack.'\n    }\n}\n```\n\n#### Build Configuration\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: '',\n    libraryExport: '',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_2_1/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n\n#### Source code for using this library\n\n●Using from **Browser**\n\n```javascript\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const tom = new Tom();//means window[\"Tom\"]\n    const jack = new Jack();//means window[\"Jack\"]\n\n    console.log(tom.sayHello());//-\u003e Hi, I am Tom.\n    console.log(jack.sayHello());//-\u003e Hi, I am Jack.\n\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_2_1/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\n\n●Using from **Node.js**\n\n```javascript\nconst {Tom, Jack} = require('./mylib.min.js');\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n\nAlso works with the following code,\n\n```javascript\nconst Lib = require('./mylib.min.js');\n\nconst Tom = Lib.Tom;\nconst Jack = Lib.Jack;\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n\n●Example of using **ES6's import** statement\n\n```javascript\nimport * as Lib from './mylib.min.js';\n\nconst Tom = Lib.Tom;\nconst Jack = Lib.Jack;\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n\nOR\n\n```javascript\nimport {Tom, Jack} from './mylib.min.js';\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n\n### 2-2.Publish multiple classes **with library name**\n\n\nBy specifying `library:'GreatFamily'`, \nyou can add a library name (like namespace) like as follows. \n\n#### Build Configuration\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: 'GreatFamily',\n    libraryExport: '',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_2_2/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n\n#### Source code of the **library**\n\n**family.js**\n\n```javascript\nexport class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\nexport class Jack {\n    sayHello() {\n        return 'Hi, I am Jack.'\n    }\n}\n```\n\n#### Source code for using this library\n\n●Using from **Browser**\n\nWhen running on a browser, each class(Tom and Jack) is stored in window [\"GreatFamily\"].\n\n```javascript\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const tom = new GreatFamily.Tom();\n    const jack = new GreatFamily.Jack();\n\n    console.log(tom.sayHello());\n    console.log(jack.sayHello());\n\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_2_2/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\n\n●Using from **Node.js**\n\nNote that in case of node.js (CommonJS2), \u003cfont color=red\u003elibrary name is ignored \u003c/font\u003e.\nSo **output.library: 'GreatFamily'** does not work for node.js.\n\n```javascript\nconst Lib = require('./mylib.min.js');\n\nconst Tom = Lib.Tom;\nconst Jack = Lib.Jack;\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n　\n\n●Example of using **ES6's import** statement\n\n```javascript\nimport * as Lib from './mylib.min.js';\n\nconst Tom = Lib.Tom;\nconst Jack = Lib.Jack;\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n\n　\n\n##2-3.Publish multiple classes including **\"export default\"** class\n\n#### Source code of the **library**\n\n**family.js**\n\n```javascript\nexport default class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\nexport class Jack {\n    sayHello() {\n        return 'Hi, I am Jack.'\n    }\n}\n\n```\n\n#### Build Configuration\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: '',\n    libraryExport: '',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_2_3/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n#### Source code for using this library\n\n\n●Using from **Browser**\n\n```javascript\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n\n    const Tom = window.default;//means window[\"default\"]\n\n    const tom = new Tom();\n    const jack = new Jack();//means window[\"Jack\"]\n\n    console.log(tom.sayHello());\n    console.log(jack.sayHello());\n\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_2_3/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\n\n●Using from **Node.js**\n\n```javascript\nconst Lib = require('./mylib.min.js');\n\nconst Tom = Lib.default;\nconst Jack = Lib.Jack;\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n\nAlso works with the following code,\n\n```javascript\nconst Tom = require('./mylib.min.js').default;\nconst {Jack} = require('./mylib.min.js');\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n\n●Example of using **ES6's import** statement\n\n```javascript\nimport * as Lib from './mylib.min.js';\n\nconst Tom=Lib.default;\nconst Jack=Lib.Jack;\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n\nor\n\n```javascript\nimport {default as Tom, Jack} from './mylib.min.js';\n\nconst tom = new Tom();\nconst jack = new Jack();\n\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack.sayHello());//-\u003e Hi, I am Jack.\n```\n\nor\n\n```javascript\n\nimport Tom2 from './mylib.min.js';\nimport {Jack as Jack2} from './mylib.min.js';\n\nconst tom2 = new Tom2();\nconst jack2 = new Jack2();\n\nconsole.log(tom2.sayHello());//-\u003e Hi, I am Tom.\nconsole.log(jack2.sayHello());//-\u003e Hi, I am Jack.\n```\n\n##2-4.Publish only \"export default\" class from multiple classes.\n\nHere's a rare pattern, but let's take a look to get a better understanding of what happens when building.\n\n#### Build Configuration\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: 'Tom',\n    libraryExport: 'default',\n    libraryTarget: 'umd',\n    globalObject: 'this'\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_2_4/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n#### Source code of the **library**\n\n**family.js**\n\n```javascript\nexport default class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\nexport class Jack {\n    sayHello() {\n        return 'Hi, I am Jack.'\n    }\n}\n```\n\n\n#### Source code for using this library\n\n\n●Using from **Browser**\n\n\u003cfont color=red\u003eJack class becomes inaccessible from outside code.\u003c/font\u003e\n\n```javascript\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const tom = new Tom();\n    console.log(tom.sayHello());\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_2_4/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\n\n●Using from **Node.js**\n\n```javascript\nconst Tom = require('./mylib.min.js');\nconst tom=new Tom();\nconsole.log(tom.sayHello());//-\u003eHi, I am Tom.\n```\n\n●Example of using **ES6's import** statement\n\n```javascript\nimport Tom  from './mylib.min.js';\nconst tom=new Tom();\nconsole.log(tom.sayHello());//-\u003eHi, I am Tom.\n```\n\n●**Tips** for this recipe\n\nThe Jack class is included as code in the bundle even though it is not accessible from outside.\nThis is purely wasteful, so if your Jack class isn't used by anyone, don't put it in your source code.\n\n## 3. Other options\n\n### 3-1.Set a separate namespace for each module type.\n\nWhen `libraryTarget: 'umd'` is specified\nRoot, AMD, and CommonJS can have different library names (namespaces).\nHowever, you cannot specify a library name for CommonJS2 (for node.js) as before, it will be ignored.\n\n#### Build Configuration\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: {\n         root: 'GreatFamily',\n         amd: 'great-family',\n         commonjs: 'common-great-family',\n    },\n     libraryExport: '',\n     libraryTarget: 'umd',\n     globalObject: 'this',\n     umdNamedDefine: true,\n}\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_3_1/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n\n```javascript\n    library: {\n         root: 'GreatFamily',\n         amd: 'great-family',\n         commonjs: 'common-great-family',\n    },\n```\n\nIn the above part,\nthe library name is given for each module type.\n\nBe careful if you want to use the AMD module type.\nSpecify `umdNamedDefine: trueP` if you want to add library name to AMD.\n\nLet's see the result of building with this setting.\nThe bundle is shown below.\nAs you can see, each module type has a specified library name.\n\n**family.min.js**\n\n```javascript\n(function webpackUniversalModuleDefinition(root, factory) {\n\t//for CommonJS2 environment\n\tif(typeof exports === 'object' \u0026\u0026 typeof module === 'object')\n\t\tmodule.exports = factory();\n\t//for AMD environment\n\telse if(typeof define === 'function' \u0026\u0026 define.amd)\n\t\tdefine(\"great-family\", [], factory);\n\t//for CommonJS environment\n\telse if(typeof exports === 'object')\n\t\texports[\"common-great-family\"] = factory();\n\t//for Root\n\telse\n\t\troot[\"GreatFamily\"] = factory();\n})(this, function() {...}\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_3_1/mylib.develop.js\" target=\"_blank\"\u003eSee full source code of bundle(develop build)\u003c/a\u003e\n\n### 3-2.Set a separate comment for each module type.\n\nBy writing **auxiliaryComment**, you can add comments to the source code of each module type definition of the generated code of bundle.\n\n#### Build Configuration\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: {\n         root: 'GreatFamily',\n         amd: 'great-family',\n         commonjs: 'common-great-family',\n    },\n    libraryExport: '',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n    umdNamedDefine: true,\n    auxiliaryComment: {\n        root: 'Comment for Root',\n        commonjs: 'Comment for CommonJS',\n        commonjs2: 'Comment for CommonJS2',\n        amd: 'Comment for AMD'\n    }\n}\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_3_2/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n\nAs you can see below,\nyou can see the comments in the bundle.\n\n**family.min.js**\n\n```javascript\n(function webpackUniversalModuleDefinition(root, factory) {\n\t//Comment for CommonJS2\n\tif(typeof exports === 'object' \u0026\u0026 typeof module === 'object')\n\t\tmodule.exports = factory();\n\t//Comment for AMD\n\telse if(typeof define === 'function' \u0026\u0026 define.amd)\n\t\tdefine(\"great-family\", [], factory);\n\t//Comment for CommonJS\n\telse if(typeof exports === 'object')\n\t\texports[\"common-great-family\"] = factory();\n\t//Comment for Root\n\telse\n\t\troot[\"GreatFamily\"] = factory();\n})(this, function() {...}\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_3_2/mylib.develop.js\" target=\"_blank\"\u003eSee full source code of bundle(develop build)\u003c/a\u003e\n\n## 3-3.Make library name looks like **namespace** separated by periods like \"org.riversun.GereatFamily\".\n\nIf you want to name the library \"org.riversun.GreatFamily\",\nfor example, specify an array like `library: ['org', 'riversun', 'GreatFamily']`\n\n\n#### Build Configuration\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: ['org', 'riversun', 'GreatFamily'],\n    libraryExport: '',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n    umdNamedDefine: true,\n},\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_3_3/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n\n#### Source code of the **library**\n\n**family.js**\n\n```javascript\nexport class Tom {\n    sayHello() {\n        return 'Hi, I am Tom.'\n    }\n}\nexport class Jack {\n    sayHello() {\n        return 'Hi, I am Jack.'\n    }\n}\n```\n\n\n#### Source code for using this library\n\n\n●Using from **Browser**\n\n```javascript\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const tom = new org.riversun.GreatFamily.Tom();\n    const jack = new org.riversun.GreatFamily.Jack();\n    console.log(tom.sayHello());\n    console.log(jack.sayHello());\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_3_3/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\nAs mentioned above, in case of node.js (CommonJS2), \u003cfont color=red\u003elibrary name is ignored \u003c/font\u003e.\n\n          \n### 3-4.Separate external libraries(dependencies) **using \"externals\"**\n\nIf your library uses an external library (if it has dependencies), there are two types of build methods.\n\n- One method is to **bundle** an external library into your own library.\n- The other method is to **externalize** an external library.\n\n**This section describes \"externalization\" .**\n\n![image.png](https://user-images.githubusercontent.com/11747460/75517817-f3a15780-5a42-11ea-915b-2812292786ba.png)\n\n\n\nHere is an example of code where the **Tom** class depends on external library [**@riversun/simple-date-format**](https://www.npmjs.com/package/@riversun/simple-date-format).\n\n**Install an external library\n\nInstall an external library to be used as development dependencies.\n\n```shell\nnpm install --save-dev @riversun/simple-date-format\n```          \n\n#### Build Configuration\n\nAdd **externals** into **webpack.config.js** as below.\n\n**webpack.config.js**\n\n```javascript\nentry: {\n    'mylib': [`./src/family.js`],\n},\noutput: {\n    filename: `[name].min.js`,\n    library: 'Tom',\n    libraryExport: 'default',\n    libraryTarget: 'umd',\n    globalObject: 'this',\n\n},\nexternals: {\n    SDF: {\n        commonjs: '@riversun/simple-date-format',\n        commonjs2: '@riversun/simple-date-format',\n        amd: '@riversun/simple-date-format',\n        root: 'SimpleDateFormat'\n    }\n}\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_3_4/webpack.config.build-lib.js\" target=\"_blank\"\u003eSee full source code of webpack.config.js\u003c/a\u003e\n\n\nIn the following part, the part specified as \"**SDF**\" means the property name for referring to the external library from the source code.\n\n```javascript\n\nexternals: {\n    SDF: {\n        commonjs: '@riversun/simple-date-format',\n        commonjs2: '@riversun/simple-date-format',\n        amd: '@riversun/simple-date-format',\n        root: 'SimpleDateFormat'\n    }\n}\n```\n\nWrite \"**Library type name**:**Library name**\" (same as `npm install`) as shown below in the child element of **SDF**.\n\n```javascript\ncommonjs: '@riversun/simple-date-format',\ncommonjs2: '@riversun/simple-date-format',\namd: '@riversun/simple-date-format',\n```\nLibrary name can be set for each module type like **commonjs, commonjs2, amd**.\n**SDF** in the example above acts as an alias. What the **SDF** actually points to is an external library specified for each module type.\n\nLook at this at the bottom,\n\n```javascript\nroot: 'SimpleDateFormat'\n```\n\nWhen using your own library on the browser, \n**SDF** is built to reference **SimpleDateFormat**(=window.[\"**SimpleDateFormat**\"]).\n\n● Generated bundle\n\nWhen building, the following bundle is generated,\n\n```javascript\n\n(function webpackUniversalModuleDefinition(root, factory) {\n\t//for CommonJS2\n\tif(typeof exports === 'object' \u0026\u0026 typeof module === 'object')\n\t\tmodule.exports = factory(require(\"@riversun/simple-date-format\"));\n\t//for AMD\n\telse if(typeof define === 'function' \u0026\u0026 define.amd)\n\t\tdefine(\"Tom\", [\"@riversun/simple-date-format\"], factory);\n\t//for CommonJS\n\telse if(typeof exports === 'object')\n\t\texports[\"Tom\"] = factory(require(\"@riversun/simple-date-format\"));\n\t//for Root\n\telse\n\t\troot[\"Tom\"] = factory(root[\"SimpleDateFormat\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_SDF__) {...})\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_3_4/mylib.develop.js\" target=\"_blank\"\u003eSee full source code of bundle(develop build)\u003c/a\u003e\n\nYou can see that the code that loads the external library is generated for each module type.\n\nThis way you can avoid bundling external libraries.\n\nLet's look at the source code of \"my\" library.\n\n#### Source code of the **library**\n\n**family.js**\n\n```javascript\nimport SimpleDateFormat from \"SDF\";\n\nexport default class Tom {\n    sayHello() {\n        const date = new Date();\n        const sdf = new SimpleDateFormat();\n        return `Hi, I am Tom. Today is ${sdf.formatWith(\"EEE, MMM d, ''yy\", date)}`;\n    }\n}\n```\n\nYou can see that **SDF** in `import SimpleDateFormat from\" SDF \";` is an alias of the original `import SimpleDateFormat from\"@riversun/simple-date-format\";`.\n\nNext, let's look at using my library created by separating the external library.\n\n#### Source code for using this library\n\n\n●Using from **Browser**\n\n- When using from a browser, read the external library from the CDN as follows\n- Note that dependent libraries (external libraries) are loaded **\"before\"** my library.\n\n```javascript\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/@riversun/simple-date-format@1.1.0/dist/simple-date-format.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"./mylib.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    const tom = new Tom();\n    document.write(tom.sayHello());\n\u003c/script\u003e\n```\n\n\u003ca href=\"https://riversun.github.io/make-lib-with-webpack/part_3_4/client/example_for_browser.html\" target=\"_blank\"\u003eOpen demo\u003c/a\u003e\n\nBy the way, \nthe external library used this time was also built by the method of 1-4 in this article.\n\n●Using from **Node.js**\n\n```javascript\nconst Tom = require('./mylib.min.js');\nconst tom = new Tom();\nconsole.log(tom.sayHello());//-\u003e Hi, I am Tom.\n```\n\nWritten by Tom Misawa (riversun.org@gmail.com) on 2020-02-28","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friversun%2Fmaking-library-with-webpack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Friversun%2Fmaking-library-with-webpack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Friversun%2Fmaking-library-with-webpack/lists"}