参考:

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          

ocean
4 声望1 粉丝