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.
Let's assume that you are writing a small library webpack-numbers
allowing to convert numbers 1 to 5 from their numeric to a textual representation and vice-versa. The implementation makes use of ES2015 modules, and might look like this:
src/index.js
import _ from 'lodash'; import numRef from './ref.json'; export function numToWord(num) { return _.reduce(numRef, (accum, ref) => { return ref.num === num ? ref.word : accum; }, ''); }; export function wordToNum(word) { return _.reduce(numRef, (accum, ref) => { return ref.word === word && word.toLowerCase() ? ref.num : accum; }, -1); };
The usage spec for the library will be as follows.
import * as webpackNumbers from 'webpack-numbers'; ... webpackNumbers.wordToNum('Two') // output is 2 ... // CommonJS modules var webpackNumbers = require('webpack-numbers'); ... webpackNumbers.numToWord(3); // output is Three ...
// Or as a script tag <html> ... <script src="https://unpkg.com/webpack-numbers"></script> <script> ... /* webpackNumbers is available as a global variable */ webpackNumbers.wordToNum('Five') //output is 5 ... </script> </html>
For full library configuration and code please refer to webpack-library-example
Now the agenda is to bundle this library
lodash
but requiring it to be loaded by the consumer.webpack-numbers
and the variable is webpackNumbers
.import webpackNumbers from 'webpack-numbers'
or require('webpack-numbers')
.webpackNumbers
when included through script
tag.Add basic webpack configuration.
webpack.config.js
var path = require('path'); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'webpack-numbers.js' } };
This adds basic configuration to bundle the library.
externals
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. 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.
This can be done using the externals
configuration as
webpack.config.js
module.exports = { ... externals: { "lodash": { commonjs: "lodash", commonjs2: "lodash", amd: "lodash", root: "_" } } ... };
This means that your library expects a dependency named lodash
to be available in the consumer's environment.
libraryTarget
For widespread use of the library, we would like it to be compatible in different environments, i. e. CommonJS, AMD, Node.js and as a global variable.
To make your library available for reuse, add library
property in webpack configuration.
webpack.config.js
module.exports = { ... output: { ... library: 'webpackNumbers' } ... };
This makes your library bundle to be available as a global variable when imported. To make the library compatible with other environments, add libraryTarget
property to the config.
webpack.config.js
module.exports = { ... output: { ... library: 'webpackNumbers', libraryTarget: 'umd' // Possible value - amd, commonjs, commonjs2, commonjs-module, this, var } ... };
If library
is set and libraryTarget
is not, libraryTarget
defaults to var
as specified in the config reference.
Tweak your production build using webpack.
Add the path to your generated bundle as the package's main file in package.json
package.json
{ "main": "dist/webpack-numbers.js", "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 }
The key main
refers to the standard from package.json
, and module
to a proposal to allow the JavaScript ecosystem upgrade to use ES2015 modules without breaking backwards compatibility.
module
will point to a module that has ES2015 module syntax but otherwise only syntax features that browser/node supports.
Now you can publish it as an npm package and find it at unpkg.com to distribute it to your users.
© 2012–2016 Tobias Koppers
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/guides/author-libraries/