博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
为什么自己写的组件库被引用总是报错——详解webpack的library和libraryTarget
阅读量:6954 次
发布时间:2019-06-27

本文共 2247 字,大约阅读时间需要 7 分钟。

如果我们仅仅是实现一个项目,我们大概率不会关注到webpack output中的这两个属性。但是如果我们是实现一个组件库,那么这两个属性就变得至关重要了。本文从自己之前遇到的一个问题说起,继而引申出library和libraryTarget属性。

1. 故事起源

当我自己开始写第一个组件库的时候,很快我就撸好了框架的代码,然后我兴致冲冲的把我的组件库引入到我的项目中,我记得那时候我是这么写的:

组件库

import Feeds from '@/components/feeds/index';export {  Feeds,};

主项目

import Feeds from '@/tencent/newsH5Ad';// 一些其他代码

然后我就收获了一个报错,Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: null。啊?难道是我的最终输出代码有问题?我检查了一下最终输出的代码,没有问题,Feed组件的代码也在里面。这个问题我查了很久,都没有答案,最后才发现是webpack打包的问题。这就涉及到了本文的主角,library和libraryTarget。

2.

2. library和libraryTarget

我们都知道,webpack可以将不同的模块化方式(commonjs, AMD, CMD, ES6 Module)的代码打包。那我们打出来的代码包其实也可以按不同的模块化方式生成,所以:

libraryTarget就是配置webpack打包内容的模块方式的参数
library就是webpack打包内容的名字

所以library规定了组件库返回值的名字,libraryTarget规定了返回值的编码格式。

libraryTarget的配置选项可以分为四大类:

2.1 按不同的模块方式生成

也就是我们这个问题的解决方法,由于我写的是一个React的UI组件库,所以我们需要commonjs的模块方式。因此只需要在webpack.config.js中配置这一项即可:

module.exports = {  entry: './src/index.js',  output: {    filename: 'index.js',    // library: 'MyLibrary', // 模块名称    libraryTarget: 'commonjs2', // 输出格式  },  // 其他代码}

事实上,你可以选择的选项有:

commonjs/commonjs2: 将你的library暴露为CommonJS模块
amd: 将你的library暴露为amd模块
umd: 将你的library暴露为所有的模块定义下都可运行的方式

其中AMD和UMD需要指定library,如果不声明组件库则不能正常运行。这是为了在浏览器上通过script标签加载时,用AMD模块方式输出的组件库可以有明确的模块名。如:

define("MyLibrary", [], function() {  return _entry_return_; // 此模块返回值,是入口 chunk 返回的值});

注意:commonjs和commonjs2几乎相同,只不过commonjs只包含exports,而commonjs2还包含module.exports,所以直接使用commonjs2即可。

2.2 生成为一个变量

libraryTarget的默认值是var,顾名思义,就是将组件库入口起点的返回值生成一个变量。如:

var MyLibrary = _entry_return_;

也可以选择‘assign',那样的话将默认生成和一个全局的变量。不管是var还是assign,都需要设置library的名称,否则就会报错。

2.3 生成一个为一个对象的属性

和第二种情况差不多,只不过会把这个变量赋值给某个对象,作为它的一个属性存在。可以选择的选项有:

this: 返回值成为this的一个属性
window: 返回值成为window的一个属性
global: 返回值成为global的一个属性

例如:

this["MyLibrary"] = _entry_return_;window["MyLibrary"] = _entry_return_;global["MyLibrary"] = _entry_return_;

可以看到,这种情况下也必须指定library的名字。

2.4 异步生成方式

在这种情况下,libraryTarget的值为‘jsonp’,组件库入口起点的返回值,会被包裹到一个jsonp包装容器中,并配合webpack的externals使用——组件库的依赖由externals指定。如:

MyLibrary(_entry_return_);

3. 总结

本文介绍了webpack中libraray和libraryTarget的相关内容,解释了为什么不设置它们时使用webpack打包出来的组件库会有问题。一般情况下,作为vue或者react组件库,libraryTarget在commonjs2,amd,umd中三者择其一即可。

参考文献

  1. 《》

转载地址:http://zztil.baihongyu.com/

你可能感兴趣的文章
Linux 内核的文件 Cache 管理机制介绍
查看>>
运维高考题
查看>>
PreviewRenderUtility的Example
查看>>
纯JS操作获取桌面路径方法
查看>>
HTTP VISUAL HTTP请求可视化工具、HTTP快照工具(公测)
查看>>
Htmlparser专题
查看>>
银行支持一带一路超4800亿美元 投资不受外汇限制
查看>>
scrapy-splash抓取动态数据例子七
查看>>
Eclipse导入android项目包xml报错未生成R文件
查看>>
未经处理的异常在 System.Data.dll 中发生。其它信息:在应使用条件的上下文(在 '***' 附近)中指定了非布尔类型的表达式。...
查看>>
Alpine Linux配置使用技巧【一个只有5M的操作系统(转)】
查看>>
sqlcmd
查看>>
stl之multiset容器的应用
查看>>
LeetCode 205 Isomorphic Strings(同构的字符串)(string、vector、map)(*)
查看>>
Django REST Framework限速
查看>>
洪涝淹没分析输出淹没范围图、深度图及面积体积等信息【转】
查看>>
树莓派(Debian)系统开启iptables的raw表实现日志输出
查看>>
图像滤镜实现万能方法研究
查看>>
nginx-启动gzip、虚拟主机、请求转发、负载均衡
查看>>
magento 2.3安装测试数据
查看>>