webpack官網,使用webpack前端重構感受

 2023-11-22 阅读 18 评论 0

摘要:2019獨角獸企業重金招聘Python工程師標準>>> 重構起點 在一個老項目中用webpack對前端代碼進行重構,重構的重心在于JS部分。這個老項目呢,有2年以上的歷史了。 JS部分從底數起: Mootools - core/more?1.5.0jQuery - 1.11.1underscore,我

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

重構起點

在一個老項目中用webpack對前端代碼進行重構,重構的重心在于JS部分。這個老項目呢,有2年以上的歷史了。

JS部分從底數起:

  1. Mootools - core/more?1.5.0
  2. jQuery - 1.11.1
  3. underscore,我也不記得什么版本了
  4. uikit + uikit部分components
  5. 用戶開發的底層JS:mootools-extends擴展,uikit-extends?- 基于uikit寫的一套ui部分交互的東西,mobile-detect - 適配個版本安卓用的東西,custom-functions - 各種常用方法。
  6. jQuery插件:jquery-address、jquery-mobile-event、owl-carousel、tablesaw、jquery.transit、jquery.event.drop等
  7. requirejs
  8. 各種開源的工具:ckeditor、jsoneditor、plupload、DateTimePicker(Mootools版)、highcharts等
  9. 用戶開發的上層JS:ui -?更具體的ui控制代碼,shopping - 與購物車、交易相關的代碼

上述這些是這次重構中,明確在前臺能夠找得到、有明確使用的類庫,其實很多都是擦邊球了,但怎么說還是有用到。

重構基礎JS并合并打包

webpack官網、這次重構有一些目的,就是起碼開源部分的類庫,能更新的,應該盡可能的更新,能不用的類庫,盡量去掉。

  1. Mootools 更新 1.6+,去掉More庫
  2. jQuery,更新2.2+
  3. underscore換成lodash,underscore作者已經哭暈了,coffee漸漸es6取代,underscore被lodash取代,backbones,也不是非他不可,前端mvc如phpmvc一般雨后春筍般冒出,underscore也很久不更新了。
  4. uikit 更新到2.15+
  5. requirejs,Good bye!!
  6. 清查無用的jQuery插件
  7. 開源的工具也依次更新等。
  8. 增加React(react、react-dom)

其次,從內到外,重新合并打包出基礎js(頁面只加載一次這個js)。

Mootools(這家伙重寫原生對象) => jQuery => lodash => uikit => 用戶開發的底層JS => jQuery插件 => 用戶開發的上層JS => 本次重構新寫的JS

React和ReactDOM實際上實在本次重構新寫的js中引入的。

上述內容是需要重新打包的js內容。webpack的入口文件——entry代碼如下:

// 第一階段
var jQuery = require('./lib/jquery_hack');
var lodash = require('./lib/lodash');
// var Mootools = require('./lib/mootools-core-1.5.1-full-nocompat');window.$ = document.id;
window.jQuery = jQuery;
window._ = lodash;// 第二階段 uikit ui部分擴展
var uikit = require('./lib/uikit');// 第三階段 各種亂七八糟的類庫,jQuery擴展之類的
require('./lib/jquery-address');
require('./lib/jquery-mobile-events');
require('./lib/jquery-datetimepicker');
require('./lib/jquery.pinto');
require('./lib/spark-md5');// 第四階段 自己寫的js加載
require('./base/mootools-extends');
require('./base/mobile-detect');
require('./base/custom-functions');
var uk = require('./base/uikit-extends');
// 這是一個jquery的插件
require('./base/tablesaw');var ui = require('./main/ui');
var shopping = require('./main/shopping');require('./components');
jQuery(document).ready(function() {ui.initNumberInput();require('./page');
});jQuery.fn.extend({animateCss: function (animationName) {var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';jQuery(this).addClass('animated ' + animationName).one(animationEnd, function() {jQuery(this).removeClass('animated ' + animationName);});}
});

webpack react、經過多方嘗試,發現Mootools新版Core庫,在PC端使用沒有問題,但是在手機中,存在各種錯誤,尤其是在手機中的webkit系瀏覽器中,估計是因為更新了es6的scoping的問題,因為mootools的源碼很多在塊({})與塊之間引用變量的問題,比如Slick、Element等,在這個塊定義的方法,在下一個塊就調用不到了。而且蘋果和安卓,還各有不同的特征,修正了安卓下的問題,蘋果又出毛病了。所以,最后實在沒辦法,Mootools 1.6.+ Core的代碼單獨在頁面優先加載,之后是按照上述規則打包出來的基礎JS。

下面是webpack的webpack.config.js,這個文件是用于生成開發版本調試用的:

const path = require("path");
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');const gbdo = 'public/assets', test = 'assets/public';const basePath = gbdo;module.exports = {entry: {gbdo: ['./assets/js/app.js'],},// target: 'node', // http://stackoverflow.com/questions/33001237/webpack-not-excluding-node-modules// externals: [nodeExternals()],output: {path: path.resolve(__dirname, basePath),// publicPath: "/",filename: '[name].js'},module: {loaders: [{test: /\.less$/,loader: ExtractTextPlugin.extract('style', 'css!less')},{test: /\.styl$/,loader: ExtractTextPlugin.extract('style', 'css-loader!stylus-loader')// loader: 'css-loader!stylus-loader?paths=node_modules/bootstrap-stylus/stylus/'},{test: /\.css$/,loader: "style!css"},{test: /\.(png|jpg|jpeg|gif|(woff|woff2)?(\?v=[0-9]\.[0-9]\.[0-9])?)$/,loader: 'url-loader?limit=1000'},{test: /\.(ttf|eot|svg)(\?[\s\S]+)?$/,loader: 'file'},{test: /\.(es6|jsx)?$/,exclude: /(node_modules|bower_components)/,loader: 'babel',query: {presets: ['es2015', 'react'],plugins: ["transform-es2015-block-scoping","transform-class-properties","transform-es2015-computed-properties"]}}]},plugins: [new webpack.optimize.UglifyJsPlugin({compress: {warnings: false,},output: {comments: false,},}),]
};

下面是webpack.build.js,是用于打包出最終的版本,以push到git用的:

const path = require("path");
const webpack = require('webpack');var config = require('./webpack.config');config.plugins.push(new webpack.DefinePlugin({'process.env':{'NODE_ENV': JSON.stringify('production')}
}));module.exports = config;

為什么單獨做一個webpack.build呢?這個后面會說到,其實主要問題是因為react這個多事鬼。

而ckeditor、jsoneditor、plupload、datetimepicker(jQuery版)、highcharts,這些屬于外圍的工具輔助類,以頁面需要用到的時候,才發起調用。

webpack vs?Gulp

gulp webpack。其實我還有另外一個一模一樣的打包的gulpfile.js,內容就不發了。兩者打包出來的容量是相當的,webpack是696kb,gulp是691kb,不過就調試環境而言,差別就很大了,如果webpack以dev-server方式啟動,他會保留完整的代碼引用結構,以方便你檢閱各個部分的代碼:

131648_6YvN_57579.png

所以如果同樣是合并輸出,webpack提供了更多的細節以讓你進行調試。

當然,其實gulp也可以透過sourceMap的方式來實現,不過我不得不吐槽,gulp如果要生成js的sourceMap,執行時間相差實在太大了,稍微大一些的文件,或者是結合了babel,起碼要等上幾秒乃至更長的時間,完全沒有實用的價值。

而且就合并處理的方式而言,當你執行webpack或者webpack-dev-server,如果轉譯的js或者css有錯,他只會跳過這個文件,而繼續往后執行,并且不中斷當前的進程,也即你并不需要去手動重啟webpack。

webpack require,而gulp的話,就比較頭疼了,雖然加入gutils對于部分的錯誤可以跳過,但是還是有一些異常是會讓gulp中斷的,所以用gulp watch的時候,你修改代碼,必須小心翼翼,起碼必須保證代碼不能包含一些語法檢查中可能引發的異常狀態。

而關于i/o檢索的準確性,gulp一直讓我比較頭疼,比如假定我監控的是指定的目錄下的全部js文件,如果你新加了一個js文件,gulp watch是不會馬上發現的,雖然他遲早會發現這個文件存在,但這需要有一個周期,所以更好的辦法是停止當前的gulp watch,然后重新啟動。

其次是,gulp雖然可以指定一個目錄下的文件來檢索,比如:js/*.js,js/*/*.js,可是一個很重要的問題是,這些文件加載是有序的,所以實際上你還是要一條一條來寫,或者使用gulp-order、gulp-sort之類的插件,但實際上你還是必須手動指定具體的內容的。非常不爽。

相較而言,webpack則完全保留了node_modules的目錄引用機制,就是該目錄下的index.js索引文件,比如:require('./dir'),實際上就是引用的是dir/index.js。

entry入口文件,你確定引用需要的目錄的索引文件,然后啟動webpack或者webpack-dev-server,之后增加或者刪除文件,修改entry文件,或者修改目錄索引文件,webpack都會實時檢索到更新,這比gulp操作起來要簡便多了。

webpack有什么用。最后就是代碼規模的問題,上面說了,同樣的素材源代碼,同樣的uglifyJS配置,最基本的壓縮,如果不壓縮js,gulp還是挺快的,可是加上uglifyJS,gulp就成了一臺年邁的老爺車。而webpack,除了上述的源代碼,還增加了很多很多webpack自己的源代碼,最后合并、并進行uglifyJS compress,依舊輕松愉快。

詳細的技術細節我就不分析太多了,webpack的hot update,得益于他清晰結構化的合并代碼結構,而不是純粹簡單的合并,不過這也會讓不熟悉js的用戶——尤其是不熟悉瀏覽器環境下調試的用戶,增加了一層復雜度。但從實際使用的體驗層面來說,webpack比gulp帶來更好的體驗感——最關鍵的是,gulp,還沒用,就要裝一大堆插件:

133954_qH7y_57579.png

258個文件,你確定不是在逗我?我只是想寫js……

webpack則相對要集中得多了。

webpack原理,從模式上來說,webpack關注的是集中,整合,并且嚴謹的檢查前端引用的每一個資源,并根據你的配置打包輸出到指定的目錄下,一絲不茍,但容錯性又很強。

相對來說,gulp兼容性很強,容忍,松散,效能低下,更嚴格意義上說,他只是你系統文件流的搬運工,而且容錯性很低。

從上手來說,gulp和webpack初始上手都很容易,大家表層的配置和調用的接口都設計的巨簡單。但是兩者深入使用的時候,都很復雜,gulp你需要安裝比jquery更多的插件,可能你項目實際用到的插件庫,還沒有gulp多。而webpack的配置,隱晦的東西太多太多,他是可以很牛掰,而且很多東西其實官網也有提過(但也就是那么一提),你不翻閱github issues,stackoverflow,根本不了解,哦原來官網那么簡單一提的東西,原來是有那么深刻的用意的。

所以嚴格來說,webpack要熟練精通的話,可能會需要更高的投入。

轉載于:https://my.oschina.net/janpoem/blog/677146

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/184467.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息