原文地址連接描述css
通過前端框架的迅猛發展,你們開始慢慢對模塊化習覺得常但殊不知道經過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方法,由於模塊化開發,杜絕一切全局變量,因此在全局找不到該對象,它是局部變量,打包以後代碼簡化以下:html
(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參數能夠配置輸出模塊規範。node
在官網說明中敘述libraryTarget 有以下參數可選:(不指定 output.library 將取消這個 "var" 配置)中文說明jquery
output.library 會將值做爲變量聲明導出(當使用 script 標籤時,其執行後在全局做用域可用)。webpack
當 library 加載完成,入口起點的返回值將分配給 window 對象。web
window["MyLibrary"] = _entry_return_; // 使用者將會這樣調用你的 library: window.MyLibrary.doSomething();
當 library 加載完成,入口起點的返回值將分配給 exports 對象。這個名稱也意味着模塊用於 CommonJS 環境json
exports["MyLibrary"] = _entry_return_; // 使用者將會這樣調用你的 library: require("MyLibrary").doSomething();
這是一種能夠將你的 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(); 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 多是如下任何一種形式: