webpack 打包的输出和引入方式

       最近在迁移项目时,需要将外部依赖的组件库打包后使用。期望是每个组件打包成一个文件入口,放在工程目录下的lib 文件夹下。配置了webpack 的 entry 为数组,output 的filename,path,publicPath 和 chuckFilename属性。 作为迁移项目的依赖,将组件库项目以git  tag 的方式引入项目,代码中使用ES6 import 的方式使用lib下的组件。组件库项目打包生成lib过程顺利,文件都按期望生成。 迁移项目也打包顺利,dev server 也顺利启动,终端没有报任何错误。 但是在运行时,页面却没有按预期渲染出来,打开console,出现了如下错误:

        浏览器端debug 发现,在执行import 语句时,的确有进入 smart组件的lib 文件,且return 也是符合预期。当代码运行到使用smart组件的地方时,smart就为undefined了。这说明,组件库代码本身没有问题,应该是打包后引入方式的问题。当前打包的lib 不支持 ES6 import 方式, 那就是试试commonJs的方式,发现require 也不起作用。分析打包后的lib 文件,发现那是一个立即执行表达式。然后想到手动将立即执行表达式的值赋给module.exports。 运行时,发现有进展了,smart 有值了,但是个object,期望的值在这个object的default属性下。大喜呀,说明问题根源是 组件库打包的输出方式不对。 然后开始谷歌webpack bundle 如何以模块方式引入,果然查到了一个libraryTarget关键字。然后去通吃了一变webpack output 的两个配置:library 和 libraryTarget。 这两个配置决定了bundle对外暴露的方式,同时也决定了bundle的使用方法。总结如下:

libraryTarget:默认值var,可选项 var, assign, this, window, global, commonjs, commonjs2, amd, umd, jsonp.  这些可选项配合library属性的值,可以将bundle 对外暴露的方式和使用方法分为三种:

1.  暴露为一个变量,变量名由library指定, 在项目中以<script>标签方式引入,使用时访问该变量。 这种方式下,library 必须指定,且值为字符串。libraryTarget的相关可选项有var, assign。

2.  暴露为一个特定对象的属性上, 属性名由library指定,若library 未指定,则直接暴露在对象上(会有覆盖原有属性的风险)。在项目中以<script>标签方式引入,使用时访问特定对象的属性。libraryTarget的相关可选项有this, window, global, commonjs。各选项对应的特定对象分别为:

  • “this” :全局变量this
  • “window”:客服端浏览器环境的全局变量window,
  • “global” :服务端NodeJs环境的全局变量global,
  • “commonjs” :commonJS 模块的全局变量 exports ,需要以package依赖方式引入项目,用commonJS格式使用。

3. 模块方式暴露,模块类型由libraryTarget指定,在项目中以package依赖方式加载,以特定模块语法格式使用。libraryTarget的相关可选项有commonjs2, amd, umd。 不同的选项,library的意义不一样。

  • commonjs2:commonJs 模块,commonJs语法引入,library无意义。
  • amd: AMD模块,AMD 语法引入,library指定模块名。
  • umd:同时适用commonJs 模块,AMD模块,也可以导出到 global 下的变量,library指定模块名或变量名。

总结:webpack打包时,libraryTarget 属性决定了输出结果,同时也决定了输出的bundle如何在项目中使用。对于组件库,我们大多是npm package 依赖方式引入项目,为增强通用性,一般将libraryTarget设置为umd模式。 当我们希望以CDN方式引入资源时,要在html中以<script> 标签引入bundle,这时候就需要用方法1或2来设置libraryTarget 和library。

 

 

 

 

 

 

参考:

https://blog.csdn.net/frank_yll/article/details/78992778

https://www.webpackjs.com/configuration/output/#output-library

展开阅读全文

没有更多推荐了,返回首页