一個月前,組內的一個內部使用的瀏覽器比價插件的前端部分交給我來維護,做爲一個老司機我是拒絕的,本身的代碼都是坑,還要去給別人填坑,搞笑地說。css
呵呵,能拒絕麼。。。。前端
好好享受吧,騷年。。。。。。ajax
看到代碼的那一刻我驚呆了,就一個js文件,接近2000行的代碼。這個還好,比這個行數多的我見的多了,這個還嚇不到我。有哪些問題,一會再說。
chrome
由於從我接手的那一刻算起,幾天後就要發新版本,我只要也只能調一些樣式。代碼重構,想都不要想,有想法我也得掐死。
json
我覺得很簡單,很快就能完成,too young too naive,上代碼:gulp
.hover(function(){ $("").css("border-top", "1px solid #5589d4"); $("").css("border-bottom", "1px solid #f4f4f4"); $("").css("border-left", "1px solid #5589d4"); $("#").css("border-right", "1px solid #f4f4f4"); $("#").css("border-left", "1px solid #e3e3e3"); $("#").css("border-right", "1px solid #5589d4"); });
文件內大量的這種內聯樣式寫法,是否是很666,並且好多地方的內聯樣式代碼仍是重複的,我要是直接在上面改,能累死煩死。
瀏覽器
基於樣式表現和行爲邏輯分離的原則,慢慢改吧,還好,慢慢調,兩個工做日基本完成了。
異步
ok,提交測試,沒問題。
but,兩天後,兄弟組在四級詳情頁新增的浮層抽獎效果,插件對其有影響,查代碼ide
//是這樣 $('.nodata').hide(); //以及這樣 $('.no-text').hide();
插件第一原則,never and never 影響或更改原有頁面的結構、行爲。模塊化
還好沒有對外推,要不用戶分分鐘把插件卸了。因此臨時改爲了這樣
//是否是區別不大?可是重複率低啊 $('.chm-x-nodata').hide();
做爲一個有輕微代碼潔癖的人,當時我就想,有時間我必定把丫重構了。
不過理智告訴我,先這麼着吧,千萬不要再來新版本了,這是一個大坑。
墨菲定律,該來的還得來。
此次是大改版,增長對某網站的支持。
ok,此次時間足夠了,重構。
項目目錄結構以下:
-plugin -- build ---- chrome //chrome插件模塊 ---- plug //內容 ------ dist --------- js //生成的js文件,包括.min.js ------ css //原來的css文件 ------ images ------ js //其餘js -- js_src ---- 01-x.js //公共變量、方法 ---- 02-mod.js //模塊化機制封裝 ---- .....js //子邏輯 ---- 90-main.js //主要邏輯 ---- 99-init.js //入口文件 -- gulpfile.js -- package.json
有意思的是,插件對象(x)內部定義了require
、define
對象,我覺得是採用了模塊化機制,實際上就是使用了一層皮。
(function(x) { x.mod={}; //構建模塊化機制 var defined = function(name, module) { x.modules[name] = module; } var require = function(name) { var m = star.modules[name]; if (!m) { return null; } else if(typeof m === 'function'){ //對象已實例化,直接返回 m = m.call(m); } return m; } x.mod.defined=defined; x.mod.require=require; })(x);
$
,很容易誤操做頁面DOM。//所以在`01-x.js`中,對其進行封裝。 var x=(function(win){ var _x={ modules:{} }; _x.$=function(str){ if (str === 'body' || typeof str === 'object') return $(str); //對根DOM要添加此類 return $('.x-root').find(str); } })(window); //調用 (function(x) { 'use strict'; var require=x.mod.require,defined=x.mod.defined; var qs=x.$; //這樣對頁面的影響幾乎降到了最低。 var m=qs("xxx"); })(x)
loginID
、password
竟然直接存,是否是醉了。/** * @description 封裝localStorage對象,防止對外暴露 */ if (!localStorage.getItem('x')) localStorage.setItem('x', JSON.stringify({})); x.getItem = function(key) { return JSON.parse(localStorage.getItem('x'))[key]; }; x.setItem = function(key, val) { var o = JSON.parse(localStorage.getItem('x')); o[key] = val; localStorage.setItem('x', JSON.stringify(o)); };
${x-Base-link}
佔位,上線前,測試時,都要批量替換,累不累啊親。直接在配置文件中定義好就能夠了啊。//爲了代碼統一,所有采用異步 //實際上用$.ajax更好,拼接url很討厭。 (function(x) { 'use strict'; var qs=x.$; var require=x.mod.require,defined=x.mod.defined; //工具模塊 defined('Tool', function() { return { //統一使用異步 xHttpRequest: function(url, callback) { return this.xHttpRequest_yb(url,callback); }, //封裝ajax操做---異步 xHttpRequest_yb: function(url, callback) { var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { callback(xhr.responseText); } } return xhr.send(); }, xFalseHttpRequest: function(url, callback) { return this.xHttpRequest_yb(url,callback); }, ); )(x);
//如判斷對象爲空的這種寫法屢次出現 if(x.userId == "" || x.userId == null || x.userId == 'null') //封裝一下就行了呀 function isNullOrEpmty(str) { return !str || str == ' ' || str == 'undefined' || str == 'null'; } //另外一樣的事件綁定,只是由於一兩處邏輯的不一樣,竟然又從新綁定了兩次,代碼只是更改了一點點啊
有了基本的脈絡後,實際上重構很快,三天多一點的時間就搞定了。坑填的差很少了,如若之後他人接手,但願坑很少。(逃
對了,最後附一下gulp.js文件,一些童鞋可能尚未接觸過。
// 引入 gulp及組件 var gulp = require('gulp'), //基礎庫 jshint = require('gulp-jshint'), //js檢查 uglify = require('gulp-uglify'), //js壓縮 rename = require('gulp-rename'), //重命名 concat = require('gulp-concat'), //合併文件 clean = require('gulp-clean'); //清空文件夾 var jsDst = './build/plug/dist/js'; var jsSrc='./js_src/*.js'; // js處理 gulp.task('jsTask', function() { gulp.src(jsSrc) .pipe(jshint()) .pipe(jshint.reporter('default')) .pipe(concat('dist.js')) .pipe(gulp.dest(jsDst)) .pipe(rename({ suffix: '.min' })) .pipe(uglify()) //.pipe(livereload(server)) .pipe(gulp.dest(jsDst)); }); // 清空圖片、樣式、js gulp.task('clean', function() { gulp.src(jsDst, {read: false}).pipe(clean()); }); // 默認任務 清空圖片、樣式、js並重建 運行語句 gulp gulp.task('default', ['clean'], function() { gulp.start('jsTask'); }); // 監放任務 運行語句 gulp watch gulp.task('watch', function() { gulp.watch(jsSrc, function() { gulp.run('jsTask'); }); });