经过前端框架的迅猛发展,大家开始慢慢对模块化习以为常但却不知道通过script引入和require(import)引入的区别。如何引入取决于之前如何导出,在重构一个验证码老项目时,不知如何把项目导出为可通过script引入后使用内部方法?
import {util} from 'util'
import styles from 'css'
export function initA(){
console.log('it is init')
...
}
<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参数可以配置输出模块规范。
在官网说明中叙述libraryTarget 有如下参数可选:(不指定 output.library 将取消这个 “var” 配置)中文说明
window["MyLibrary"] = _entry_return_;
// 使用者将会这样调用你的 library:
window.MyLibrary.doSomething();
exports["MyLibrary"] = _entry_return_;
// 使用者将会这样调用你的 library:
require("MyLibrary").doSomething();
(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();
else
root["MyLibrary"] = factory();
})(this, function() {
//这个模块会返回你的入口 chunk 所返回的
});
由于浏览器环境和node环境的区别,所以产生了window(客服端浏览器)和global(node服务端)的区别。
我理解的var即在script导入时和window一致,是否可以通过import导入,导入之后的使用还待解释。
umd即支持所有情况的自定义。
总的说设置library即在当前环境的全局引入库文件。
那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 可能是以下任何一种形式: