今天就跟大家聊聊有關(guān)如何使用webpack構(gòu)建一個(gè)js庫(kù),可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
公司主營(yíng)業(yè)務(wù):成都網(wǎng)站制作、網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出息烽免費(fèi)做網(wǎng)站回饋大家。
在前文中,我說過本系列文章的受眾是在現(xiàn)代前端體系下能夠熟練編寫業(yè)務(wù)代碼的同學(xué),因此本文在介紹 webpack 配置時(shí),僅提及構(gòu)建一個(gè)庫(kù)所特有的配置,其余配置請(qǐng)參考 webpack 官方文檔。
構(gòu)建一個(gè)庫(kù)與構(gòu)建一個(gè)一般應(yīng)用最大的不同點(diǎn)在于構(gòu)建完成后輸出的產(chǎn)物。
一般應(yīng)用構(gòu)建完成后會(huì)輸出:
雖然輸出的資源非常多,但實(shí)際上所有的依賴、加載關(guān)系都已經(jīng)從 html 文件開始一層一層定下來了,換句話說,這個(gè) html 文件實(shí)際上就是整個(gè)應(yīng)用的入口。
一個(gè)庫(kù)構(gòu)建完成后會(huì)輸出:
庫(kù)的入口分別是上面羅列的 js 文件;你可能會(huì)奇怪,一個(gè)庫(kù)怎么會(huì)有3個(gè)入口文件呢?莫急,且聽我一一道來。
CommonJS是 Node.js 推行的一種模塊化規(guī)范,主要語法包括module.exports
、require()
等;而我們?cè)谑褂?webpack 引入 npm 包時(shí),實(shí)際上是處于 Node.js 環(huán)境,由此可知,這個(gè) CommonJS 格式的入口 js 文件(<庫(kù)名稱>.common.js
)是供其它應(yīng)用在 Node.js 環(huán)境下引入 npm 包使用的。由于在引用 npm 包時(shí)一般不會(huì)過多考慮 npm 包的體積(在構(gòu)建自己的應(yīng)用時(shí)如有需要可自行壓縮),且為了方便調(diào)試,因此該 js 入口文件是沒有經(jīng)過壓縮的。
UMD是一個(gè)模塊化規(guī)范大雜燴,除了兼容 CommonJS 外,它還兼容 AMD模塊化規(guī)范,以及最傳統(tǒng)的全局變量模式。
這邊稍微介紹一下 AMD 規(guī)范, AMD 全稱 Asyncchronous Module Definition ,一般應(yīng)用在瀏覽器端(這是與 CommonJS規(guī)范最大的不同點(diǎn)),最著名的 AMD 加載器是 RequireJS。目前由于 webpack 的流行, AMD 這一模塊化方案已逐漸退出市場(chǎng)。
全局變量模式就很好理解了,就是把庫(kù)的入口掛載在一個(gè)全局變量(如window.xxx
)上,頁面上的任何位置都能隨時(shí)取用,屬于最傳統(tǒng)的 js 插件加載方案。
由上可知, UMD 格式的入口 js 文件,既可以用于引用 npm 包的場(chǎng)景(未壓縮的版本,即<庫(kù)名稱>.umd.js
),也可以直接用于瀏覽器端(已壓縮的版本,即<庫(kù)名稱>.umd.min.js
)。
目前, webpack 不支持同時(shí)生成多份入口 js 文件,因此需要分多次來進(jìn)行構(gòu)建。
關(guān)鍵的 webpack 配置是:
output.libraryTarget: "commonjs2"
output.libraryTarget: "umd"
對(duì)于 UMD ,我們還需要設(shè)置全局變量名稱,即output.library: "LibraryName"
。
為了壓縮構(gòu)建出來的文件,最簡(jiǎn)單的方法是在 CLI 中調(diào)用 webpack 命令時(shí)帶上 mode參數(shù),如webpack --mode=production
;這是因?yàn)楫?dāng) mode 的值為production
時(shí), webpack 會(huì)自動(dòng)啟用 UglifyJsPlugin對(duì)源碼進(jìn)行壓縮。
我在某公司工作時(shí),該公司對(duì)第三方依賴抓得很緊,所有在項(xiàng)目里使用的第三方依賴都必須申請(qǐng)且審核通過后才可使用;且申請(qǐng)時(shí)是精確到具體版本的,未申請(qǐng)的軟件版本也一概不允許使用。某些第三方依賴無論在文件內(nèi)容上,還是在文件名稱上,都沒有體現(xiàn)出版本號(hào),這就對(duì)我們識(shí)別這類第三方依賴產(chǎn)生障礙,這是我們開發(fā)自己的庫(kù)時(shí)需要引以為戒的。
在構(gòu)建庫(kù)時(shí),我們完全可以利用 webpack 把庫(kù)的信息直接輸出到文件內(nèi)容里,有了這“身份信息”,用戶使用起來也會(huì)格外安心。
輸出庫(kù)版本信息的方法是使用 webpack.BannerPlugin ,最簡(jiǎn)單的使用方法如下:
const pgk = require('./package.json'); const banner = ` ${pkg.name} ${pkg.description}\n @version v${pkg.version} @homepage ${pkg.homepage} @repository ${pkg.repository.url}\n (c) 2019 Array-Huang Released under the MIT License. hash: [hash] `; /* webpack 配置 */ { // ...其它配置 plugins: [ // ...其它 plugin 配置 new webpack.BannerPlugin(banner); ] }
最終生成出來的效果是:
/*! * * vue-directive-window * Vue.js directive that enhance your Modal Window, support drag, resize and maximize. * * @version v0.7.5 * @homepage https://github.com/Array-Huang/vue-directive-window * @repository git+https://github.com/Array-Huang/vue-directive-window.git * * (c) 2019 Array-Huang * Released under the MIT License. * hash: dc6c11a1e50821f4444a * */
如果庫(kù)的用戶是直接通過在瀏覽器里加載你的庫(kù)來使用的話,那么提供一份 source map文件是非常有必要的;這是因?yàn)槟愕膸?kù)在經(jīng)過 webpack 構(gòu)建,甚至壓縮后,與源代碼已經(jīng)大相徑庭了,用戶將難以在瀏覽器中進(jìn)行調(diào)試;但如果你能為自己的庫(kù)附上一份 source map ,瀏覽器開發(fā)者工具會(huì)調(diào)用 source map 來幫助解析,用戶的調(diào)試體驗(yàn)會(huì)更接近于調(diào)試庫(kù)的源碼。
相應(yīng)的 webpack 配置為:
// webpack 配置 { // ...其它配置 devtool: 'cheap-module-source-map' }
webpack 支持多種類型的 source map ,不同類型的 source map 在生成速度、支持功能(如 babel )、調(diào)試位置偏移等問題上均有不同表現(xiàn),我這邊只做推薦:
關(guān)于其它類型的 source map ,請(qǐng)查看 webpack 官方文檔的 devtool 章節(jié)。
與一般應(yīng)用不一樣,在開發(fā)庫(kù)的時(shí)候,我們應(yīng)盡量避免引入第三方庫(kù)(構(gòu)建過程中使用的工具鏈除外),因?yàn)檫@些第三方庫(kù)會(huì)讓我們寫的庫(kù)的大小猛增;很可能會(huì)出現(xiàn)這樣的情況:我們自己寫的小功能只有幾百行代碼的邏輯,構(gòu)建出來的庫(kù)卻有幾百k,那這樣的庫(kù)意義就不大了。
但我們的確也很難避免使用第三方庫(kù),那該咋辦呢?
// webpack 配置 { // ...其它配置 externals: { lodash: { commonjs: 'lodash', commonjs2: 'lodash', amd: 'lodash', root: '_' } } }
使用上述配置后,我們構(gòu)建出來的庫(kù)中就不會(huì)包含配置中指定的第三方庫(kù)(例子中為lodash
)了,下面來一一詳解:
commonjs
和commonjs2
項(xiàng)都是指明用戶在 node.js 環(huán)境下使用當(dāng)前庫(kù)時(shí),以 CommonJS的方式來加載名為lodash
的 npm 包。amd
項(xiàng)表示在瀏覽器中加載運(yùn)行本庫(kù)時(shí),本庫(kù)會(huì)試圖以 AMD的方式來加載名為lodash
的 AMD 模塊。root
項(xiàng)表示在瀏覽器中加載運(yùn)行本庫(kù)時(shí),本庫(kù)會(huì)試圖取全局變量window._
(通過<script>
標(biāo)簽加載lodash.js
時(shí), lodash 會(huì)把自己注入到全局變量window._
中)。在一般應(yīng)用中,你或許會(huì)看到這樣的 externals 配置:
// webpack 配置 { // ...其它配置 externals: { lodash: '_' } }
這樣的 externals 配置方式意味著:無論在什么環(huán)境,都要取_
這個(gè)全局變量;如果當(dāng)前是在一般應(yīng)用且確定已經(jīng)使用<script>
來加載指定的第三方庫(kù)(比如 jQuery、 Vue 等核心庫(kù),的確很常以這種方式來加載),當(dāng)然大可直接這樣用;但我們作為庫(kù)的作者,應(yīng)提供更寬松更靈活的使用方式。
由于構(gòu)建不同模塊化規(guī)范的庫(kù)需要不同的 webpack 配置(其實(shí)也只是稍有不同)來進(jìn)行多次構(gòu)建,因此本文只針對(duì)構(gòu)建 UMD 格式且已壓縮這一場(chǎng)景來展示最簡(jiǎn)單的 webpack 配置示例;如果想知道如何更有效率地拼接 webpack 配置,請(qǐng)看 micro-schema-validator 項(xiàng)目的 webpack 配置文件。
// webpack.config.js const webpack = require('webpack'); const pkg = require('./package.json'); // 把 package.json 作為信息源 const banner = ` ${pkg.name} ${pkg.description}\n @version v${pkg.version} @homepage ${pkg.homepage} @repository ${pkg.repository.url}\n (c) 2019 Array-Huang Released under the MIT License. hash: [hash] `; module.exports = { entry: `${__dirname}/index.js`, devtool: 'cheap-module-source-map', output: { path: `${__dirname}/dist`, // 定義輸出的目錄 filename: 'micro-schema-validator.min.js', // 定義輸出文件名 library: 'MicroSchemaValidator', // 定義暴露到瀏覽器環(huán)境的全局變量名稱 libraryTarget: 'umd', // 指定遵循的模塊化規(guī)范 }, /* 排除第三方依賴 */ externals: { lodash: { commonjs: 'lodash', commonjs2: 'lodash', amd: 'lodash', root: '_' } }, module: { rules: [ { test: /(\.jsx|\.js)$/, loader: 'babel-loader', exclude: /(node_modules|bower_components)/ }, { test: /(\.jsx|\.js)$/, loader: 'eslint-loader', exclude: /(node_modules|bower_components)/ } ] }, plugins: [ new webpack.BannerPlugin(banner) // 輸出項(xiàng)目信息 ] };
對(duì)于 Vue 生態(tài)的庫(kù),如 Vue 組件、Vue 自定義指令等,可以使用 vue-cli (本文特指 vue-cli 3.0 后的版本)根據(jù)你的需求來定制 webpack 配置,可定制內(nèi)容包括:
定制完成后, vue-cli 將生成一個(gè)種子項(xiàng)目,該項(xiàng)目可執(zhí)行(包括本地開發(fā)和構(gòu)建生產(chǎn)環(huán)境的包)但沒有實(shí)際內(nèi)容(實(shí)際內(nèi)容不還得由你來寫嘛哈哈)。與一般的腳手架工具相比, vue-cli 除了可以生成 webpack 配置外,還將持續(xù)對(duì)其進(jìn)行管理和維護(hù),如:
摘自 vue-directive-window 項(xiàng)目的 vue.config.js 文件:
const webpack = require('webpack'); const pkg = require('./package.json'); const banner = ` ${pkg.name} ${pkg.description}\n @version v${pkg.version} @homepage ${pkg.homepage} @repository ${pkg.repository.url}\n (c) 2019 Array-Huang Released under the MIT License. hash: [hash] `; module.exports = { chainWebpack: config => { config.output.libraryExport('default'); config.plugin('banner').use(webpack.BannerPlugin, [ { banner, entryOnly: true, }, ]); }, };
看起來是不是比上文中最基礎(chǔ)的 webpack 配置還要簡(jiǎn)潔呢?當(dāng)項(xiàng)目的架構(gòu)逐漸豐富起來后,這個(gè)差距將不斷拉大。
在我的工作生涯中,我寫的絕大部分庫(kù)都是為公司的項(xiàng)目寫的,很可惜無法帶出來,但我會(huì)以我最近寫的兩個(gè)開源庫(kù):javascript-library-boilerplate 和 vue-directive-window 來作為實(shí)例項(xiàng)目代碼來輔助介紹。
javascript-library-boilerplate是一個(gè)現(xiàn)代前端生態(tài)下快速構(gòu)建 javascript 庫(kù)的腳手架(或稱種子項(xiàng)目,或稱示例代碼,看你理解了),本庫(kù)支持 GitHub 的 repository templates 功能,你可以直接在項(xiàng)目首頁點(diǎn)擊 Use this template來直接套用本腳手架的代碼來創(chuàng)建你自己的 javascript 庫(kù)。
vue-directive-window是一個(gè)可以快速讓模態(tài)框(modal)支持類窗口操作的增強(qiáng)庫(kù);類窗口操作主要包括三大類:拖拽移動(dòng)、拖拽調(diào)整窗口尺寸、窗口最大化; vue-directive-window 支持以 Vue 自定義指令或是一般 js 類的方式來調(diào)用。
vue-directive-window 相對(duì)于 javascript-library-boilerplate 來說,更貼近 Vue 生態(tài)圈,如果你最近想為 Vue 生態(tài)圈添磚加瓦,不妨參考一下本項(xiàng)目。
我會(huì)以我最近寫的兩個(gè)開源庫(kù):javascript-library-boilerplate 和 vue-directive-window 來作為實(shí)例項(xiàng)目代碼來輔助介紹。
javascript-library-boilerplate是一個(gè)現(xiàn)代前端生態(tài)下快速構(gòu)建 javascript 庫(kù)的腳手架(或稱種子項(xiàng)目,或稱示例代碼,看你理解了),本庫(kù)支持 GitHub 的 repository templates 功能,你可以直接在項(xiàng)目首頁點(diǎn)擊 Use this template來直接套用本腳手架的代碼來創(chuàng)建你自己的 javascript 庫(kù)。
vue-directive-window是一個(gè)可以快速讓模態(tài)框(modal)支持類窗口操作的增強(qiáng)庫(kù);類窗口操作主要包括三大類:拖拽移動(dòng)、拖拽調(diào)整窗口尺寸、窗口最大化; vue-directive-window 支持以 Vue 自定義指令或是一般 js 類的方式來調(diào)用。
vue-directive-window 相對(duì)于 javascript-library-boilerplate 來說,更貼近 Vue 生態(tài)圈,如果你最近想為 Vue 生態(tài)圈添磚加瓦,不妨參考一下本項(xiàng)目。
看完上述內(nèi)容,你們對(duì)如何使用webpack構(gòu)建一個(gè)js庫(kù)有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
文章標(biāo)題:如何使用webpack構(gòu)建一個(gè)js庫(kù)
新聞來源:http://bm7419.com/article42/psdihc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、虛擬主機(jī)、企業(yè)網(wǎng)站制作、定制開發(fā)、全網(wǎng)營(yíng)銷推廣、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)