资讯专栏INFORMATION COLUMN

为什么自己写的组件库被引用总是报错——详解webpack的library和libraryTarget

lewif / 3292人阅读

摘要:可以选择的选项有返回值成为的一个属性返回值成为的一个属性返回值成为的一个属性例如可以看到,这种情况下也必须指定的名字。异步生成方式在这种情况下,的值为,组件库入口起点的返回值,会被包裹到一个包装容器中,并配合的使用组件库的依赖由指定。

如果我们仅仅是实现一个项目,我们大概率不会关注到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中三者择其一即可。

参考文献

《webpack文档》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101244.html

相关文章

  • Vue组件库开发总结

    摘要:组件库开发总结由于工作需要,最近在学习怎么开发一个组件库。按需打包的使用要使用按需打包,不仅组件库的打包需要做处理,项目中也需要做处理。 Vue组件库开发总结 由于工作需要,最近在学习怎么开发一个Vue组件库。主要需要实现以下点:1.组件使用npm包引入2.实现按需引入及按需打包项目中许多实现是参考的element-ui,特别是webpack打包部分 组织项目 项目生成 项目生成是直接...

    longshengwang 评论0 收藏0
  • 一文教你构建自己librarywebpack优化npm版本控制

    摘要:地址点个,给我们一点动力中文文档地址交流地址点个,谢谢这套费了几个月时间和很多心血,现在已经趋于完善,你完全可以在你的生产环境中试着使用。 介绍 构建自己的UI库,你必须要对一款打包工具熟悉(webpack, gulp或者grunt), 本文以webpack为例。 github 地址: https://github.com/reming0227... (点个 star,给我们一点动力 ...

    刘玉平 评论0 收藏0
  • vue插件开发流程详解-从开发到发布至npm(二)

    摘要:使用插件安装使用测试访问页面注意大大的红字,如果要在本项目下测试,需要修改项目名称,不然报项目名字和包名字是一致的错,无法安装的如下结束语这个笔记继上一篇插件开发流程详解从开发到发布至一,替换了开发和测试的项目架构。   前记:上一篇 https://www.cnblogs.com/adouw...,说到了一个完整的vue插件开发、发布的流程,总结下来就讲了这么一个事,如何注入vue,...

    Flink_China 评论0 收藏0
  • 如何发布你自己React模块至NPM

    摘要:文章介绍如何创建发布一个包,包括项目搭建发布流程注意事项等。语义化版本号分为三位。主版本号当进行了大都改动或者对有很多不兼容修改时应该进行版本号升级。次版本号增加了部分特性或者优化时升级该版本。如如果你想撤回指定版本,执行包名版本号。 文章介绍如何创建发布一个npm包,包括项目搭建、发布流程、注意事项等。 演示代码GitHub地址 1. 初始化项目 首先在创建好的项目文件夹下面执行 ...

    zombieda 评论0 收藏0
  • webpackDllPluginDllReferencePlugin插件简单使用总结

    摘要:今天就来简单讲讲它们的使用。这个插件的作用是创建文件和文件。使用其他的脚手架需要根据具体情况考虑。不要使用,否则在运行时会报错误。的和的要保持一致。 这段时间在对公司的打包构建速度和app.js文件大小进行优化。使用到了webpack的DllPlugin和DllReferencePlugin。今天就来简单讲讲它们的使用。 其实对于这两个插件网上已经有很多各种各样的文章了。不过笔者认为,...

    wushuiyong 评论0 收藏0

发表评论

0条评论

lewif

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<