为何本身写的组件库被援用老是报错——详解webpack的library和libraryTarget

假如我们仅仅是完成一个项目,我们大几率不会关注到webpack output中的这两个属性。然则假如我们是完成一个组件库,那末这两个属性就变得至关重要了。本文从本身之前碰到的一个题目提及,继而引伸出library和libraryTarget属性。

1. 故事劈头

当我本身最先写第一个组件库的时刻,很快我就撸好了框架的代码,然后我兴趣冲冲的把我的组件库引入到我的项目中,我记得那时刻我是这么写的:

组件库

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

主项目

import Feeds from '@/tencent/newsH5Ad';

// 一些其他代码

<Feeds data='xxx'>

然后我就收成了一个报错,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. webpack文档
    原文作者:这是你的玩具车吗
    原文地址: https://segmentfault.com/a/1190000017960583
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞