摘要:概述從去年短時(shí)間內(nèi)對(duì)現(xiàn)有系統(tǒng)的改造到如今穩(wěn)定實(shí)施,已經(jīng)好幾個(gè)月,這套流程滿(mǎn)足了日常前端開(kāi)發(fā)的流程。在講這之前簡(jiǎn)單說(shuō)下前端模塊化歷程。模塊化以上是在規(guī)范出來(lái)之前的編碼方式,大家應(yīng)該非常熟悉。只要在代碼中用來(lái)異步加載模塊即可。
概述
從去年短時(shí)間內(nèi)對(duì)現(xiàn)有系統(tǒng)的改造到如今穩(wěn)定實(shí)施,已經(jīng)好幾個(gè)月,這套流程滿(mǎn)足了日常前端開(kāi)發(fā)的流程。由于之前項(xiàng)目組的模塊化本身做的不是很好,基本算是推到一半重來(lái),雖然陣痛,但回顧起來(lái)確實(shí)非常值得。webpack,簡(jiǎn)單來(lái)說(shuō)就是前端靜態(tài)資源的打包工具,確實(shí)好用,原理也很簡(jiǎn)單,比以AMD、CMD為標(biāo)準(zhǔn)的模塊加載器好用多了,難怪玉伯說(shuō)要給seajs、requirejs立一塊墓碑了。在講webpack這之前簡(jiǎn)單說(shuō)下前端模塊化歷程。
模塊化1.0// a.js (function(){ // todo a })(); // b.js (function(){ // todo b })(); // index.html
以上是在CommonJS規(guī)范出來(lái)之前的編碼方式,大家應(yīng)該非常熟悉。另外還有通過(guò)命名空間的方式來(lái)進(jìn)行模塊化,其實(shí)也沒(méi)有真正的解決問(wèn)題。
模塊化2.0// a.js define(function(require, exports, module){ // todo a }) // b.js define(function(require, exports, module){ var a = require("./a"); // todo b }) // index.html
這就是過(guò)去幾年大家都非常熟悉的模塊化方式,在發(fā)布上線(xiàn)時(shí)通過(guò)構(gòu)建工具,提取模塊id、以及模塊的依賴(lài),合并壓縮代碼等等構(gòu)建工作。
但是用requirejs或者seajs,還是有些問(wèn)題:
只能模塊化加載js、css,而且還不幫你合并,需要自己寫(xiě)插件去做合并的邏輯,組件化并不簡(jiǎn)單。
異步加載也不好用,尤其是部署時(shí),hash后的資源路徑自動(dòng)替換還比較麻煩。
程序還是要依賴(lài)seajs這個(gè)幾kb的庫(kù),總感覺(jué)有點(diǎn)多余。
模塊化3.0webpack出來(lái)后,優(yōu)雅的解決了很多問(wèn)題,并且簡(jiǎn)單好用。它能把各種資源,例如JS(含JSX)、coffee、樣式(含less/sass)、html、圖片等靜態(tài)資源都作為模塊來(lái)處理。同時(shí)擁有異步加載的能力,非常適用于大型復(fù)雜的webapp的場(chǎng)景。webpack有以下特點(diǎn):
兼容AMD/CMD的模塊加載
js模塊的寫(xiě)法遵循CommonJS規(guī)范
模塊化所有靜態(tài)資源(JS、CSS、html、圖片、字體等)
開(kāi)發(fā)、部署便捷,能替代大部分 grunt/gulp 的工作,比如打包、壓縮混淆、圖片轉(zhuǎn)base64等
通過(guò)一個(gè)簡(jiǎn)單的配置文件即可搞定這些。
實(shí)戰(zhàn)結(jié)合項(xiàng)目本身的特點(diǎn),部分功能webpack無(wú)法做到,最終選用gulp+webpack方式來(lái)支撐前端的工作流,項(xiàng)目需求:
最小化配置項(xiàng)(webpack.config.js)
所有資源使用增量發(fā)布策略,文件名全部 md5 版本化
支持多種模塊化策略,使用 webpack 進(jìn)行模塊化打包
自動(dòng)替換 html/js 內(nèi)部資源引用路徑,替換為 cdn/md5 版本化路徑
輕松支持 js資源內(nèi)嵌到頁(yè)面
開(kāi)發(fā)時(shí)監(jiān)聽(tīng)文件,自動(dòng)上傳到開(kāi)發(fā)機(jī)
由于css是由重構(gòu)同學(xué)寫(xiě),雪碧圖,壓縮、發(fā)布等等都由他們來(lái)做,所以沒(méi)有考慮加入到構(gòu)建流程中來(lái)。
項(xiàng)目目錄結(jié)構(gòu)如下:
src/ js/ widget/ css/ img/ project_tpl/ gulpfile.js app/ js/ css/ img/ index.html tpl/ webpack.config.js gulpfile.js app/
src目錄下是項(xiàng)目的源代碼,每個(gè)目錄(app)即為一個(gè)項(xiàng)目,為了盡量避免沖突,一個(gè)人開(kāi)發(fā)并維護(hù)一個(gè)項(xiàng)目下的代碼。
project_tpl為項(xiàng)目的模板,通過(guò)gulp新建項(xiàng)目,完成一些初始化配置,初始化后基本無(wú)需配置即可進(jìn)行項(xiàng)目開(kāi)發(fā)。
js/css/img為站點(diǎn)的一些公共資源模塊,widget為公共基礎(chǔ)組件。
app項(xiàng)目下為業(yè)務(wù)的css、js、tpl目錄,tpl為前端模板目錄,可以通過(guò)webpack的html-loader插件加載。
gulpfile.js、webpack.config.js 為項(xiàng)目的構(gòu)建工具配置文件。
這樣一個(gè)項(xiàng)目的腳手架搭建完成,可以開(kāi)始為項(xiàng)目添磚加瓦了??梢渣c(diǎn)擊這里看github上的例子。
webpack配置文件var webpack = require("webpack"); var globalConfig = require("../global.config"); var commonJSEntry = globalConfig.jsCommon; var path = require("path"); module.exports = { // 如果項(xiàng)目有多個(gè)HTML,或者多個(gè)入口 // 配置js入口文件,base是公共庫(kù)配置,除了打包工具自動(dòng)化抽取共用的模塊,也可以自定義配置哪些模塊為共用的。 entry:{ index: "./js/index", base: commonJSEntry, }, // 文件產(chǎn)出目錄 output:{ filename:"../test/js/[name].js", // 異步加載的chunk,命名規(guī)則,chunk我暫時(shí)理解為從合并的代碼里分離出來(lái)的代碼塊,在處理非首屏邏輯,或者異步加載邏輯可以用這個(gè)。只要在js代碼中用require.ensure來(lái)異步加載模塊即可。 chunkFilename: "../test/js/[chunkhash:8]_chunk.js", // 資源文件的CDN前綴 publicPath: debug ? "" : "http://cdn.xxx.com/webpack/test/" }, resolve: { // 模塊的別名,通常可以為第三方模塊 alias: { ajax: "../../js/base/ajax", dom: "../../js/base/dom" }, // root模塊的根路徑,可以指定從哪里找模塊,可以為數(shù)組[] // 這樣在模塊依賴(lài)的時(shí)候就不要寫(xiě)require(../../../xx.js) // 直接為require(xx) root: path.resolve("../../js") }, // 模塊加載器,加載不同類(lèi)型的文件,需要下載或者開(kāi)發(fā)loader插件,以下為加載html模塊的加載器 loader: [ {test: /.html$/, loader: "html"} ], /* 1、可以通過(guò)配置文件指定哪位模塊為公共模塊,這樣功能模塊可以長(zhǎng)期緩存。 解釋下這個(gè)插件的意思,就是提取公共的chunk,base對(duì)應(yīng)了entry中的配置,"../test/js/common.js"是產(chǎn)出的路徑,也就是將commonJSEntry中的配置模塊合并成一個(gè)common.js文件。 2、webpack也可自動(dòng)提取頁(yè)面之間公用的代碼作為公共部分。下面的代碼即是自動(dòng)提取公共代碼了。 var commonsPlugin = new webpack.optimize.CommonsChunkPlugin("../test/js/common.js"); */ plugins: [ new webpack.optimize.CommonsChunkPlugin("base", "../test/js/common.js") ] };
由于項(xiàng)目的特性,沒(méi)有用到熱插拔,所以就不進(jìn)行講解了。
gulp跑起來(lái)webpack最終是當(dāng)做gulp的一個(gè)插件來(lái)運(yùn)行,讀取的上述的webpack配置文件。
gulp.task("watch-html", function() { // upload }); gulp.task("watch-module", function() { var watchPath = [ "../js/**", "../css/**", "../widget/**", "js/**", "css/**", "tpl/**" ]; gulp.watch(watchPath, function(event){ gulp.src(watchPath) .pipe(webpack(require("webpack.config"))) .pipe(gulp.dest(releaseRelativePath + projectName)) .pipe(upload(opt, function(err, data){}) }) }); gulp.task("default", ["watch-html", "watch-module"]); // release build webpack module gulp.task("release-module", function() { var releasePath = [ "../js/**", "../css/**", "../widget/**", "js/**", "css/**", "tpl/**" ]; return gulp.src(watchPath) .pipe(webpack(require("webpack.config"))) .pipe(uglify()) .pipe(hash()) .pipe(rename(function(path) { // 獲取當(dāng)前的日期,將發(fā)布文件已日期歸類(lèi),更方便查找文件 path.dirname = path.dirname + "/" + year + month + day; }) .pipe(gulp.dest(releaseRelativePath + projectName)) .pipe(upload(opt, function(err, data){}) }) }); // release build html gulp.task("release", ["release-module"], function(){ gulp.src(["**/*.html"]) .pipe(parseHtml(releaseRelativePath + projectName, CDN_URL)) .pipe(gulp.dest(releaseRelativePath + projectName)) .pipe(upload(opt, function(err, data){}) .pipe(uploadToCDN()) })
(以上用到的部分npm模塊是自定義的)。
1、項(xiàng)目開(kāi)始前,通過(guò)gulp init -p YourProjectName 來(lái)初始化項(xiàng)目
2、開(kāi)發(fā)和發(fā)布兩套命令,開(kāi)發(fā):gulp,發(fā)布:gulp release
3、需要自行編寫(xiě)gulp插件來(lái)替換html中引用資源的路徑,原理也很簡(jiǎn)單,在構(gòu)建webpack模塊后,將產(chǎn)出的文件列表與原文件的映射關(guān)系保存在數(shù)組,查找html中引用的js路徑,替換成hash后就可以了。
通過(guò)以上方法,就可以滿(mǎn)足我們項(xiàng)目之前的需求,基本上做到自動(dòng)化,自動(dòng)構(gòu)建,自動(dòng)發(fā)布腳本,html文件走內(nèi)部發(fā)布系統(tǒng)發(fā)布。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/79464.html
摘要:前言與是目前圈子內(nèi)比較活躍的前端構(gòu)建工具。對(duì)于初學(xué)者來(lái)說(shuō),對(duì)這二者往往容易認(rèn)識(shí)不清,今天,就從事件的源頭,說(shuō)清楚與。它可以將許多松散的模塊按照依賴(lài)和規(guī)則打包成符合生產(chǎn)環(huán)境部署的前端資源。打包后形成的文件出口。 前言:Webpack 與 gulp是目前圈子內(nèi)比較活躍的前端構(gòu)建工具。網(wǎng)上有很多二者比較的文章,面試中也會(huì)經(jīng)常遇到gulp,Webpack的區(qū)別這樣的問(wèn)題。對(duì)于初學(xué)者來(lái)說(shuō),對(duì)這二...
摘要:所以它在某些程度上,跟的功能有些相同。嚴(yán)格上講,模塊化不是他強(qiáng)調(diào)的東西,他旨在規(guī)范前端開(kāi)發(fā)流程。更是明顯強(qiáng)調(diào)模塊化開(kāi)發(fā),而那些文件壓縮合并預(yù)處理等功能,不過(guò)是他附帶的功能。 1. webpack 是什么? showImg(https://segmentfault.com/img/remote/1460000012293461); 先來(lái)說(shuō)一下 webpack 是什么。 webpack 的...
摘要:主有前端后端,并加,各一名。本著工欲善其事,必先利其器的理念,一直以來(lái)在工作效率這塊,略懷執(zhí)念一個(gè)問(wèn)題不應(yīng)該被解決兩次。下圖為開(kāi)發(fā)項(xiàng)目機(jī)制所涉及到的插件工欲善其事,必先利其器,語(yǔ)言,框架皆可以歸結(jié)為器而不當(dāng)僅局限于開(kāi)發(fā)工具以及機(jī)。 原文鏈接: http://www.jeffjade.com/2016/05/08/106-vue-es6-jade-scss-webpack-gulp/ 一...
摘要:那時(shí)候所配置的任務(wù)監(jiān)聽(tīng)匹配文件的變化自動(dòng)刷新瀏覽器自動(dòng)編譯自動(dòng)補(bǔ)全前綴多雪碧圖合并拼圖等等基于編譯圖片的任務(wù),已經(jīng)是完全滿(mǎn)足我們的需求了。直至到后來(lái)在雪碧圖的合并,多倍圖的輸出上,在上苦苦找尋不了比較完美的解決方案等等。 折騰 從 2015 到現(xiàn)在,短短的三年內(nèi),幾乎每年折騰一下工作流的 更新?lián)Q代 。從最早開(kāi)始使用 Grunt 到 Gulp 再到 Webpack,再到 Rollup,...
閱讀 537·2021-10-09 09:44
閱讀 2148·2021-09-02 15:41
閱讀 3574·2019-08-30 15:53
閱讀 1853·2019-08-30 15:44
閱讀 1310·2019-08-30 13:10
閱讀 1220·2019-08-30 11:25
閱讀 1493·2019-08-30 10:51
閱讀 3383·2019-08-30 10:49