Skip to content

Commit 317a18c

Browse files
authored
Merge pull request #299 from kalcifer/feat/author-library
Adds how to author libraries
2 parents 19ef422 + e0029c4 commit 317a18c

File tree

1 file changed

+190
-3
lines changed

1 file changed

+190
-3
lines changed

content/how-to/author-libraries.md

Lines changed: 190 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,194 @@
11
---
22
title: How to Author Libraries?
3+
contributors:
4+
- pksjce
35
---
4-
> library option
5-
> externals option
66

7-
> see also [[Output]]
7+
webpack is a tool which can be used to bundle application code and also to bundle library code. If you are the author of a JavaScript library and are looking to streamline your bundle strategy then this document will help you.
8+
9+
## Author a Library
10+
11+
We have here a small wrapper library to convert number 1 to 5 from number to word and vice-versa. It looks something like this.
12+
13+
__src/index.js__
14+
```javascript
15+
import _ from 'lodash';
16+
import numRef from './ref.json';
17+
18+
export function numToWord(num) {
19+
return _.reduce(numRef, (accum, ref) => {
20+
return ref.num === num ? ref.word : accum;
21+
}, '');
22+
};
23+
24+
export function wordToNum(word) {
25+
return _.reduce(numRef, (accum, ref) => {
26+
return ref.word === word && word.toLowerCase() ? ref.num : accum;
27+
}, -1);
28+
};
29+
30+
```
31+
32+
The usage spec for the library will be as follows.
33+
34+
```javascript
35+
// ES2015 modules
36+
37+
import * as webpackNumbers from 'webpack-numbers';
38+
39+
...
40+
webpackNumbers.wordToNum('Two') /// output is 2
41+
...
42+
43+
// CommonJs modules
44+
45+
var webpackNumbers = require('webpack-numbers');
46+
...
47+
webpackNumbers.numToWord(3); // output is Three
48+
...
49+
50+
// As a script tag
51+
52+
<html>
53+
...
54+
<script src='https://unpkg.com/webpack-numbers' type='text/javascript'/>
55+
<script type='text/javascript'>
56+
...
57+
/* webpackNumbers is available as a global variable */
58+
webpackNumbers.wordToNum('Five') //output is 5
59+
...
60+
</script>
61+
</html>
62+
```
63+
64+
For full library configuration and code please refer to [webpack-library-example](https://github.com/kalcifer/webpack-library-example)
65+
66+
## Configure webpack
67+
68+
Now the agenda is to bundle this library
69+
- Without bundling lodash but requiring it to be loaded by the consumer.
70+
- Name of the library is `webpack-numbers` and the variable is `webpackNumbers`.
71+
- Library can be imported as `import webpackNumbers from 'webpack-numbers'` or `require('webpack-numbers')`.
72+
- Library can be accessed through global variable `webpackNumbers` when included through `script` tag.
73+
- Library can be accessed inside Node.js.
74+
75+
### Add webpack
76+
77+
Add basic webpack configuration.
78+
79+
__webpack.config.js__
80+
81+
```javascript
82+
83+
module.exports = {
84+
entry: './src/index.js',
85+
output: {
86+
path: './dist',
87+
filename: 'webpack-numbers.js'
88+
}
89+
};
90+
91+
```
92+
93+
This adds basic configuration to bundle the library.
94+
95+
### Add Loaders
96+
97+
But it will not work without adding relevant loaders for transpiling the code.
98+
Here, we need a [`json-loader`](https://github.com/webpack/json-loader) is required to precompile our json fixture file.
99+
100+
__webpack.config.js__
101+
102+
```javascript
103+
module.exports = {
104+
// ...
105+
module: {
106+
rules: [{
107+
test: /.json$/,
108+
use: 'json-loader'
109+
}]
110+
}
111+
};
112+
```
113+
### Add `externals`
114+
115+
Now, if you run `webpack`, you will find that a largish bundle file is created. If you inspect the file, you will find that lodash has been bundled along with your code.
116+
It would be unnecessary for your library to bundle a library like `lodash`. Hence you would want to give up control of this external library to the consumer of your library.
117+
118+
This can be done using the `externals` configuration as
119+
120+
__webpack.config.js__
121+
122+
```javascript
123+
module.exports = {
124+
...
125+
externals: {
126+
"lodash": {
127+
commonjs: "lodash",
128+
commonjs2: "lodash",
129+
amd: "lodash",
130+
root: "_"
131+
}
132+
}
133+
...
134+
};
135+
```
136+
137+
This means that your library expects a dependency named `lodash` to be available in the consumers environment.
138+
139+
### Add `libraryTarget`
140+
141+
For widespread use of the library, we would like it to be compatible in different environments, ie CommonJs, AMD, nodejs and as a global variable.
142+
143+
To make your library available for reuse, add `library` property in webpack configuration.
144+
145+
__webpack.config.js__
146+
147+
```javascript
148+
module.exports = {
149+
...
150+
output: {
151+
...
152+
library: 'webpackNumbers'
153+
}
154+
...
155+
};
156+
```
157+
158+
This makes your library bundle to be available as a global variable when imported.
159+
To make the library compatible with other environments, add `libraryTarget` property to the config.
160+
161+
__webpack.config.js__
162+
163+
```javascript
164+
module.exports = {
165+
...
166+
output: {
167+
...
168+
library: 'webpackNumbers',
169+
libraryTarget:'umd' // Possible value - amd, commonjs, commonjs2, commonjs-module, this, var
170+
}
171+
...
172+
};
173+
```
174+
175+
If `library` property is set and `libraryTarget` is set to be `var` by default, as given in the [config reference](/configuration/output).
176+
177+
### Final Steps
178+
179+
[Tweak your production build using webpack](/how-to/generate-production-build).
180+
181+
Add the path to your generated bundle as the package's main file in `package.json`
182+
183+
__package.json__
184+
185+
```javascript
186+
{
187+
...
188+
"main": "dist/webpack-numbers.js",
189+
"module": "src/index.js", // To add as standard module as per https://github.com/dherman/defense-of-dot-js/blob/master/proposal.md#typical-usage
190+
...
191+
}
192+
```
193+
194+
Now you can [publish it as an npm package](https://docs.npmjs.com/getting-started/publishing-npm-packages) and find it at [unpkg.com](https://unpkg.com/#/) to distribute it to your users.

0 commit comments

Comments
 (0)