2019独角兽企业重金招聘Python工程师标准>>>

重构起点

在一个老项目中用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并合并打包

这次重构有一些目的,就是起码开源部分的类库,能更新的,应该尽可能的更新,能不用的类库,尽量去掉。

  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);});}
});

经过多方尝试,发现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

其实我还有另外一个一模一样的打包的gulpfile.js,内容就不发了。两者打包出来的容量是相当的,webpack是696kb,gulp是691kb,不过就调试环境而言,差别就很大了,如果webpack以dev-server方式启动,他会保留完整的代码引用结构,以方便你检阅各个部分的代码:

所以如果同样是合并输出,webpack提供了更多的细节以让你进行调试。

当然,其实gulp也可以透过sourceMap的方式来实现,不过我不得不吐槽,gulp如果要生成js的sourceMap,执行时间相差实在太大了,稍微大一些的文件,或者是结合了babel,起码要等上几秒乃至更长的时间,完全没有实用的价值。

而且就合并处理的方式而言,当你执行webpack或者webpack-dev-server,如果转译的js或者css有错,他只会跳过这个文件,而继续往后执行,并且不中断当前的进程,也即你并不需要去手动重启webpack。

而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操作起来要简便多了。

最后就是代码规模的问题,上面说了,同样的素材源代码,同样的uglifyJS配置,最基本的压缩,如果不压缩js,gulp还是挺快的,可是加上uglifyJS,gulp就成了一台年迈的老爷车。而webpack,除了上述的源代码,还增加了很多很多webpack自己的源代码,最后合并、并进行uglifyJS compress,依旧轻松愉快。

详细的技术细节我就不分析太多了,webpack的hot update,得益于他清晰结构化的合并代码结构,而不是纯粹简单的合并,不过这也会让不熟悉js的用户——尤其是不熟悉浏览器环境下调试的用户,增加了一层复杂度。但从实际使用的体验层面来说,webpack比gulp带来更好的体验感——最关键的是,gulp,还没用,就要装一大堆插件:

258个文件,你确定不是在逗我?我只是想写js……

webpack则相对要集中得多了。

从模式上来说,webpack关注的是集中,整合,并且严谨的检查前端引用的每一个资源,并根据你的配置打包输出到指定的目录下,一丝不苟,但容错性又很强。

相对来说,gulp兼容性很强,容忍,松散,效能低下,更严格意义上说,他只是你系统文件流的搬运工,而且容错性很低。

从上手来说,gulp和webpack初始上手都很容易,大家表层的配置和调用的接口都设计的巨简单。但是两者深入使用的时候,都很复杂,gulp你需要安装比jquery更多的插件,可能你项目实际用到的插件库,还没有gulp多。而webpack的配置,隐晦的东西太多太多,他是可以很牛掰,而且很多东西其实官网也有提过(但也就是那么一提),你不翻阅github issues,stackoverflow,根本不了解,哦原来官网那么简单一提的东西,原来是有那么深刻的用意的。

所以严格来说,webpack要熟练精通的话,可能会需要更高的投入。

转载于:https://my.oschina.net/janpoem/blog/677146

使用webpack前端重构感受相关推荐

  1. 高性能流媒体服务器EasyDSS前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间...

    本文围绕着实现EasyDSS高性能流媒体服务器的前端框架来展开的,具体EasyDSS的相关信息可在:www.easydss.com 找到! 接上回 <高性能流媒体服务器EasyDSS前端重构(一 ...

  2. webpack服务器性能,高性能流媒体服务器EasyDSS前端重构(三)- webpack + vue + AdminLTE 多页面引入 element-ui...

    接上篇 本文围绕着实现EasyDSS高性能流媒体服务器的前端框架来展开的,具体EasyDSS的相关信息可在:www.easydss.com 找到! element-ui 介绍 饿了么前端开发组件框架 ...

  3. EasyDSS高性能流媒体服务器前端重构

    本文围绕着实现EasyDSS高性能流媒体服务器的前端框架来展开的,具体EasyDSS的相关信息可在:www.easydss.com 找到! EasyDSS 高性能流媒体服务器前端架构概述 EasyDS ...

  4. 前端重构实践(一) —— 性能优化

    前言: 最近一直在做性能优化和模块化改造的工作,并完成了一次前端重构.在这里总结出一些经验和得失来帮助大家思考.共两篇文章,第一篇讨论性能优化,第二篇讨论模块化框架.而之所以把这两个话题放到一起,是因 ...

  5. webpack前端构建工具学习总结(一)之webpack安装、创建项目

    npm是随nodeJs安装包一起安装的包管理工具,能解决NodeJS代码部署上的很多问题: 常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器 ...

  6. vscode中6个好用的前端重构插件

    Visual Studio Code(简称VS Code)是一款由微软开发且跨平台的免费源代码编辑器.基于其丰富的插件体系与语言支持,目前已经成为了最流程的集成开发环境.本文介绍了笔者用过的最好用的几 ...

  7. # 什么是前端重构?

    前端是做什么的 说到前端,我们往往会随口蹦出一个后端,没错,如果单纯从计算机工程的角度来看待前端所做的工作,就是前端是后端的门面,用个形象的例子来比喻前后端,我们平常使用的手机是前端,而背后的手机系统 ...

  8. EasyDSS高性能流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载 - 副本...

    为了让页面更快完成加载, 第一时间呈现给客户端, 也为了帮助客户端节省流量资源, 我们可以开启 vue-router 提供的按需加载功能, 让客户端打开页面时, 只自动加载必要的资源文件, 当客户端操 ...

  9. 万字长文:2019 年 京东 PLUS 会员前端重构之路

    原  作  者:京东设计中心JDC 原文链接:https://url.cn/50og5J9 时光如梭,白驹过隙,2019 年转瞬即逝.这一年对于 PLUS 会员项目前端同学来说是坎坷和充实的,如白岩松 ...

最新文章

  1. python汉字编码错误_python解决汉字编码问题:Unicode Decode Error
  2. 统计学习导论 Chapter4--Classification
  3. 运维监控系统——配置服务监控项(Http,Nginx,MySQL)
  4. 【我眼中的戴尔转型】 (二) 厚积薄发,戴尔扩大战线迎头追击IBM HP
  5. C++标准库 第七章 STL迭代器
  6. 一步一步学习SignalR进行实时通信_5_Hub
  7. android 碎片问题,Android碎片问题
  8. qmenu qt 关闭,Qt实现点击菜单项后QMenu不关闭功能
  9. 20145109 《Java程序设计》第七周学习总结
  10. Command ‘docker‘ not found, but can be installed with:
  11. win10桌面右键一直转圈是什么原因
  12. FMI飞马网 | 【线上直播】如何处理好横向关系 在协同与合作中实现双赢(下)
  13. yaourt/yay 安装软件出现 parse “XXX“: first path segment in URL cannot contain colon 错误
  14. c 语言字符串查找替换,c ++ - 如何在标准字符串中搜索/查找和替换?
  15. C++ 泛型编程(五) 模版重载与特例化
  16. patch-package打补丁
  17. 阿里云被攻击用高防CDN的效果如何?
  18. 3D卷积的GEMM+IM2COL实现
  19. 每日学术速递4.12
  20. 中国老百姓十大欲望排行榜。

热门文章

  1. OpenCV(二)OpenCV的介绍和发展
  2. mybatis-generator 根据表生成对应文件
  3. 城市大脑 —— 数据重塑城市未来
  4. 为什么别人一周搞定Linux,而你却做不到
  5. centos6.3配置 kickstart   无人值守安装centos6.3系统 httpd方式
  6. OpenCV学习(17) 细化算法(5)
  7. sqlplus connect oracle
  8. DSOFramer使用说明(转载)))
  9. 【DFS + backtrack】LeetCode 37. Sudoku Solver
  10. 牛客网–华为机试在线训练7:取近似值