In addition to packaging applications, webpack can also be used to package JavaScript libraries. The following applies to library authors who want to simplify the packaging strategy.
Create a library
Suppose we are writing a small library called my math, which contains addition and subtraction.
The basic project structure may be as follows:
|- webpack.config.js |- package.json |- /test // Test library |- index.html |- /src |- index.js
Initialize the project with npm, and then install webpack, webpack CLI and lodash:
npm init -y npm install --save-dev webpack webpack-cli
src/index.js
export const add = (x, y) => x + y; export const subtract = (x, y) => x - y;
webpack.config.js
const path = require('path'); module.exports = { mode: 'development', entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'myMath.js', }, };
In the above example, we will notify webpack to Src / index JS package to dist / mymath JS.
Export library
So far, everything should be the same as a packaged application. Here are the different parts - we need to pass output.library The configuration item exposes the content exported from the portal.
webpack.config.js
const path = require('path'); module.exports = { mode: 'production', entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'myMath.js', + library: "myMath", }, };
We exported myMath so that users can use it through script tags:
test/index.html
<script src="../dist/myMath.js"></script> <script> myMath.add(1, 2); </script>
Output ES module
This feature is still experimental and not fully supported, so make sure to enable it in advance experiments.outputModule . In addition, you can here Track development progress.
const path = require('path'); module.exports = { mode: 'production', entry: './src/index.js', experiments: { outputModule: true, }, output: { path: path.resolve(__dirname, 'dist'), // filename: 'myMath.js', / / do not execute filename here library: 'myMath', }, };
Execute npx webpack
test/index.html
<script type="module"> import { add } from '../dist/myMath.js' console.log(add(1, 2)); </script>
You can see the normal output
Output umd
However, it can only work by being referenced by script tags. It can't run in CommonJS, AMD and node JS, ES module, etc.
For a library author, we hope that it can be used in different environments and ways. Users should be able to use the packaged library through the following:
-
CommonJS module require:
const myMath = require('myMath'); // ... myMath.add(1, 2);
-
AMD module require:
require(['myMath'], function (myMath) { // ... myMath.add(1, 2); });
-
script tag:
<!DOCTYPE html> <html> ... <script src="https://example.org/myMath.js"></script> <script> // ... // global variable myMath.add(1, 2); // Properties mounted on window window.myMath.subtract(2, 2); // ... </script> </html>
We update output Library configuration item, set its type to 'umd':
const path = require('path'); module.exports = { mode: 'development', entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'myMath.js', library: { name: 'myMath', type: 'umd', }, globalObject: 'this', }, };
output.globalObject
string = 'window'
When the output is library, especially when the libraryTarget is' UMD ', this option will determine which global object to use to mount the library. In order to build UMD in browser and node JS, output. JS should be The globalobject option is set to 'this'. For web like targets, the default is self.
Now webpack will package a library that can be used with CommonJS, AMD, and script tags.
Externalities depend on externalization
When we create a library, we may use some third-party libraries, such as loadsh
npm i loadsh -S
src/index.js
import _ from 'lodash'; export const add = (x, y) => _.add(x, y); export const subtract = (x, y) => x - y;
Execute npx webpack and you will find that a large file is created. If you look at this file, you will see that lodash is also packaged into the code. In this scenario, we prefer to regard lodash as peer dependency. That is, the consumer should have installed lodash. Therefore, you can give up control of the external library and give control to the consumer using the library.
This can be done using the externals configuration:
webpack.config.js
const path = require('path'); module.exports = { mode: 'development', entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'myMath.js', library: { name: "myMath", type: "umd" }, globalObject: 'this', }, + externals: { + lodash: { + commonjs: 'lodash', + commonjs2: 'lodash', + amd: 'lodash', + root: '_', + }, + }, };
This means that your library needs a dependency called lodash, which must exist and be available in the host environment.
package.json
{ ... "main": "dist/myMath.js", ... }
Publish npm publish
npm (III): release, update and discard of npm package
Tip
To expose the style sheets associated with the library, you should use MiniCssExtractPlugin . You can then use and load these style sheets as you would any other style sheet.
To be continued: [webpack create library] practical chapter