原文地址链接描述

经过前端框架的迅猛发展,大家开始慢慢对模块化习以为常但却不知道通过script引入和require(import)引入的区别。如何引入取决于之前如何导出,在重构一个验证码老项目时,不知如何把项目导出为可通过script引入后使用内部方法?

情景简化为如下:

  • 插件代码
import {util} from 'util'
import styles from 'css'
export function initA(){console.log('it is init')...
}
  • 通过常见webpack打包为bundle.js,在html中引入
<script src="bundle.js"></script>
<script>
//在这里想要调用内部initA方法,报错initA undefined
initA()
</script>

分析原因

页面报错initA undefined,显然此时调用initA,代表在window对象上面寻找initA方法,因为模块化开发,杜绝一切全局变量,所以在全局找不到该对象,它是局部变量,打包之后代码简化如下:

(function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {value: true
});
exports.initA = initA;
function initA() {console.log('it is initA');
}
})

那如何可以导出变量并挂载在全局对象之下,看下常见的jquery是如何操作的

//jQuery 1.2.6(新版已经支持模块化)
var _jQuery = window.jQuery,_$ = window.$;var jQuery = window.jQuery = window.$ = function( selector, context ) {// The jQuery object is actually just the init constructor 'enhanced'return new jQuery.fn.init( selector, context );};

经过多番寻找在webpack配置中用output.libraryTarget参数可以配置输出模块规范。

webpack libraryTarget 参数说明

在官网说明中叙述libraryTarget 有如下参数可选:(不指定 output.library 将取消这个 "var" 配置)中文说明

  • libraryTarget: "var"(default)

output.library 会将值作为变量声明导出(当使用 script 标签时,其执行后在全局作用域可用)。

  • libraryTarget: "window"

当 library 加载完成,入口起点的返回值将分配给 window 对象。

window["MyLibrary"] = _entry_return_;
// 使用者将会这样调用你的 library:
window.MyLibrary.doSomething();
  • libraryTarget: "assign"
  • libraryTarget: "this"
  • libraryTarget: "global"
  • libraryTarget: "commonjs"

当 library 加载完成,入口起点的返回值将分配给 exports 对象。这个名称也意味着模块用于 CommonJS 环境

exports["MyLibrary"] = _entry_return_;
// 使用者将会这样调用你的 library:
require("MyLibrary").doSomething();
  • libraryTarget: "commonjs2"
  • libraryTarget: "amd"
  • libraryTarget: "umd"

这是一种可以将你的 library 能够在所有的模块定义下都可运行的方式(并且导出的完全不是模块)。它将在 CommonJS, AMD 环境下运行,或将模块导出到 global 下的变量
最终输出:

(function webpackUniversalModuleDefinition(root, factory) {if(typeof exports === 'object' && typeof module === 'object')module.exports = factory();else if(typeof define === 'function' && define.amd)define([], factory);else if(typeof exports === 'object')exports["MyLibrary"] = factory();elseroot["MyLibrary"] = factory();
})(this, function() {//这个模块会返回你的入口 chunk 所返回的
});
  • libraryTarget: "jsonp"

对比var,window,global,umd区别

由于浏览器环境和node环境的区别,所以产生了window(客服端浏览器)和global(node服务端)的区别。
我理解的var即在script导入时和window一致,是否可以通过import导入,导入之后的使用还待解释。
umd即支持所有情况的自定义。
总的说设置library即在当前环境的全局引入库文件。

externals的简单使用

那externals又是如何使用的?和模块导出有什么区别?
先看定义:externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。也就是说webpack打包时不会把库打入bundle中,所以需要开发者在html中通过script标签引入。
例如,从 CDN 引入 jQuery,而不是把它打包:

index.html

<script src="https://code.jquery.com/jquery-3.1.0.js"integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="crossorigin="anonymous"></script>

webpack.config.js

externals: {jquery: 'jQuery'
}

有心的同学可能要想了,我都从script标签引入了那么全局就都可以使用了,为什么还要设置这个配置呐?
为了不改动原来的依赖模块!如下

import $ from 'jquery';$('.my-element').animate(...);

具有外部依赖(external dependency)的 bundle 可以在各种模块上下文(module context)中使用,例如 CommonJS, AMD, 全局变量和 ES2015 模块。这里所说的模式就是上文libraryTarget的模式。
外部 library 可能是以下任何一种形式:

  • root - 外部 library 能够作为全局变量使用。用户可以通过在 script 标签中引入来实现。这是 externals 的默认设置。
  • commonjs - 用户(consumer)应用程序可能使用 CommonJS 模块系统,因此外部 library 应该使用 CommonJS 模块系统,并且应该是一个 CommonJS 模块。
  • commonjs2 - 类似上面几行,但导出的是 module.exports.default。
  • amd - 类似上面几行,但使用 AMD 模块系统。

【深入理解webpack】library,libraryTarget,externals的区别及作用相关推荐

  1. Python的Module,Library,Package的区别

    目录 1.背景 2.module的简介 3.library的简介 4.package的简介 5.Python中的module和library之间的区别 6.Python中的module和package ...

  2. Webpack 究竟是什么?如何理解Webpack

    本篇文章主要是针对 B站Webpack从原理到实战 的知识梳理,之前写过一些 Webpack 更细节的一些知识,详情见 前端工程化(webpack),里面更详细的介绍了前端工程化.loader的使用, ...

  3. JQuery添加扩展方法(理解$.extend(),与$.fn.extend()方法区别)

    为什么80%的码农都做不了架构师?>>>    理解$.extend(),与$.fn.extend()方法区别 1.$.extend()方法 $.extend()方法在JQuery中 ...

  4. 深入理解Webpack核心模块Tapable钩子[异步版]

    接上一篇文章 深入理解Webpack核心模块WTApable钩子(同步版) tapable中三个注册方法 1 tap(同步) 2 tapAsync(cb) 3 tapPromise(注册的是Promi ...

  5. 深入理解 sudo 与 su 之间的区别

    深入理解 sudo 与 su 之间的区别 作者: Himanshu Arora 译者: LCTT zhb127 在早前的一篇文章中,我们深入讨论了 sudo 命令的相关内容.同时,在该文章的末尾有提到 ...

  6. 深入理解equals和hashCode关系和区别

    深入理解equals和hashCode关系和区别 直入主题: 区别: 1.他们判断对象相同的方式不一样: 2.他们判断对象是否相等的准确率不一样: 改写equals时总是要改写hashcode 分享一 ...

  7. 理解 CI 和 CD 之间的区别(翻译)

    博客搬迁至https://blog.wangjiegulu.com RSS订阅:https://blog.wangjiegulu.com/feed.xml 原文链接:https://blog.wang ...

  8. 深入理解 sudo 与 su 之间的区别【转】

    深入理解 sudo 与 su 之间的区别 两个命令的最大区别是: sudo 命令需要输入当前用户的密码,su 命令需要输入 root 用户的密码.另外一个区别是其默认行为.sudo 命令只允许使用提升 ...

  9. 深入理解Webpack核心模块Tapable钩子[同步版]

    记录下自己在前端路上爬坑的经历 加深印象,正文开始- tapable是webpack的核心依赖库 想要读懂webpack源码 就必须首先熟悉tapable ok.下面是webapck中引入的tapab ...

  10. 简单理解钽电容和电解电容的区别

    简单理解钽电容和电解电容的区别 对工作中遇到的一些问题做简要总结. 钽电容 体积,钽电容的体积比较小. 耐压,钽电容一般耐压10V左右,高的一般就是16V,再高的就比较少了. 价格,钽电容价格比较贵. ...

最新文章

  1. 代码实战 | 用LeGO-LOAM实现地面提取
  2. 编写一个爬虫类库——(一)想法
  3. 网络相关的一些基本的命令的使用(ping、ifconfig、route、netstat)---Linux学习笔记
  4. Javascript-Switch
  5. 最全三大框架整合(使用映射)——applicationContext.xml里面的配置
  6. linux6.2 网络yum,配置RHEL6.2的YUM源
  7. 最长单词(信息学奥赛一本通-T1149)
  8. 1天暴涨1300亿!中国移动最不争气的儿子,被王濛救活了?
  9. 你和大厂 Offer 有多近?C 认证免费测试一波,提前备考大厂
  10. 《学习OpenCV3》目录和全书划分
  11. 面试前的准备和注意事项(非常详细)
  12. 什么是对象存储OSS,看完你就懂了
  13. 九月英语--不同以往的感觉
  14. 一起学 WebGL:图元的类型
  15. 快速设置电脑自动关机
  16. 【相约上海,期待广州】甲骨文数据库大会暨38周年庆典
  17. 安卓应用开发小程序!字节跳动+京东+360+网易面试题整理,聪明人已经收藏了!
  18. 航嘉电源的通病维修方法!!
  19. Switch开关控件.
  20. 用Python代码批量处理CP2K动力学计算结果坐标文件(适合数万个分子坐标的批处理)

热门文章

  1. 动态规划-最长不下降子序列
  2. jquery 获取节点各种方法
  3. cocos2dx截整屏、截部分屏
  4. SDWebImage缓存图片的机制(转)
  5. heavy dark--读《《暗时间》》
  6. oracle 查看主外键约束
  7. insert rows into heap/clustered table
  8. 【XSY2731】Div 数论 杜教筛 莫比乌斯反演
  9. ASP.NET MVC 5 笔记
  10. 20145326蔡馨熠《信息安全系统设计》第7周学习总结