参考:
https://github.com/kalcifer/webpack-library-example
https://webpack.js.org/guides/author-libraries
说明:
最近结合webpack官方文档和示例代码在windows10下使用webpack创建library时遇见一些问题,在此总结一下
创建library:
-
基础知识准备
1. 库使用方法 ES2015 module import: import * as webpackNumbers from 'webpack-numbers'; // ... webpackNumbers.wordToNum('Two'); CommonJS module require: const webpackNumbers = require('webpack-numbers'); // ... webpackNumbers.wordToNum('Two'); AMD module require: require(['webpackNumbers'], function (webpackNumbers) { // ... webpackNumbers.wordToNum('Two'); }); via a <script>: <!doctype html> <html> ... <script src="https://unpkg.com/webpack-numbers"></script> <script> // ... // Global variable webpackNumbers.wordToNum('Five') // Property in the window object window.webpackNumbers.wordToNum('Five') // ... </script> </html> 2. 暴露 library why:为了让你的 library 能够在各种用户环境(consumption)中可用 how: 在output中添加 library属性 当你在 import 引入模块时,这可以将你的 library bundle 暴露为全局变量 在output中添加 libraryTarget 属性 1) 控制 library 以不同方式暴露,让 library 和其他环境兼容 2) 可以通过以下方式暴露 library: 变量:作为一个全局变量,通过 script 标签来访问(libraryTarget:'var') this:通过 this 对象访问(libraryTarget:'this') window:通过 window 对象访问,在浏览器中(libraryTarget:'window') UMD:在 AMD 或 CommonJS 的 require 之后可访问(libraryTarget:'umd') 3) 如果设置了 library 但没设置 libraryTarget,则 libraryTarget 默认为 var。 output.globalObject string: 'window' 要使umd 在浏览器和node.js 上都可用,globalObject需要设置成this 示例: output: { ... library: 'webpackNumbers', libraryTarget: 'umd', globalObject: 'this' }
步骤:
-
创建目录并安装相关工具
1. $ mkdir webpack-numbers-library //创建webpack-numbers-library 2. $ cd webpack-numbers-library//进入webpack-numbers-library目录 3. $ npm init -y //初始化 npm 4. $ npm install webpack --save-dev //在本地安装 webpack 5. $ npm install webpack-cli --save-dev // 安装 webpack-cli 6. $ npm install lodash --save-dev //安装 lodash
-
添加文件
1. 添加 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); }; ref.json [ { "num": 1, "word": "One" }, { "num": 2, "word": "Two" }, { "num": 3, "word": "Three" }, { "num": 4, "word": "Four" }, { "num": 5, "word": "Five" }, { "num": 0, "word": "Zero" } ] 2. 添加examples/ browser/index.html <html> <head> <title>webpack numbers library</title> <script type='text/javascript' src='https://unpkg.com/lodash@4.16.6'></script> </head> <body> <div id='root'></div> <!--通过<script> 加载库--> <script type='text/javascript' src='./webpack-numbers.js'></script> <script type='text/javascript'> document.getElementById('root').innerHTML = " This is a browser example where and api is called to transalate 'One' to '1' \n Results: wordtonum('One') === " + window.webpackNumbers.wordToNum('Five'); </script> </body> </html> node/example.js require('lodash'); var webpackNumbers = require('./webpack-numbers.js');//CommonJS module require var out = function () { process.stdout.write('This is the result for numToWord(1) === ' + webpackNumbers.numToWord(1)); }; out(); 3. 添加webpack.config.js const path = require('path'); module.exports = { mode: 'production',//启用 uglifyjs 压缩插件进行压缩输出 entry: './src/index.js', output: { path: path.resolve(__dirname, './dist'), filename: 'webpack-numbers.js', library: 'webpackNumbers',//暴露 library为webpackNumbers的全局变量 libraryTarget: 'umd',//让 library 和其他环境兼容:umd:在 AMD 或 CommonJS 的 require 之后可访问 globalObject: 'this',//使umd 在浏览器和node.js 上都可用,globalObject需要设置成this }, externals: {//外部化 lodash:放弃对外部 library 的控制,而是将控制权让给使用 library 的用户 lodash: { commonjs: 'lodash', commonjs2: 'lodash', amd: 'lodash', root: '_' } }, module: { rules: [ { test: /\.(js)$/, exclude: /(node_modules|bower_components)/, use: 'babel-loader' } ] } }; 4. 最终的文件结构如下: │ package-lock.json │ package.json │ webpack.config.js │ ├─examples │ ├─browser │ │ index.html │ │ │ └─node │ example.js ├─node_modules │ └─src index.js ref.json
-
安装babel-loader
$ npm install babel-loader --save-dev 最新的 babel-loader版本是8.x, 直接安装, 后面执行npm build xxx的时候会报以下错误 ERROR in ./src/index.js Module build failed (from ./node_modules/babel-loader/lib/index.js): Error: Cannot find module '@babel/core' babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'. 根据错误信息的提示, 我们安装babel-loader 7.x版本babel-core $ npm install babel-core babel-loader@7 --save-dev babel-loader@7.1.5 babel-core@6.26.3
-
修改package.json
从webpack-library-example 示例中package.json 拷贝以下code 到 { ... "main": "dist/webpack-numbers.js",//添加生成 bundle 的文件路径 "scripts": { "build:browser": "webpack && cp dist/webpack-numbers.js examples/browser", "build:node": "webpack && cp dist/webpack-numbers.js examples/node/ && node examples/node/example.js", "test": "echo \"Error: no test specified\" && exit 1" } ... }
-
测试browser
1. $ npm run build:browser 2. 在浏览器中打开index.html 页面显示: This is a browser example where and api is called to transalate 'One' to '1' Results: wordtonum('One') === 5
-
测试 node
1. $ npm run build:node 2. 打印以下信息: This is the result for numToWord(1) === One
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。