使用webpack前端重构感受
2019独角兽企业重金招聘Python工程师标准>>>
重构起点
在一个老项目中用webpack对前端代码进行重构,重构的重心在于JS部分。这个老项目呢,有2年以上的历史了。
JS部分从底数起:
- Mootools - core/more 1.5.0
- jQuery - 1.11.1
- underscore,我也不记得什么版本了
- uikit + uikit部分components
- 用户开发的底层JS:mootools-extends扩展,uikit-extends - 基于uikit写的一套ui部分交互的东西,mobile-detect - 适配个版本安卓用的东西,custom-functions - 各种常用方法。
- jQuery插件:jquery-address、jquery-mobile-event、owl-carousel、tablesaw、jquery.transit、jquery.event.drop等
- requirejs
- 各种开源的工具:ckeditor、jsoneditor、plupload、DateTimePicker(Mootools版)、highcharts等
- 用户开发的上层JS:ui - 更具体的ui控制代码,shopping - 与购物车、交易相关的代码
上述这些是这次重构中,明确在前台能够找得到、有明确使用的类库,其实很多都是擦边球了,但怎么说还是有用到。
重构基础JS并合并打包
这次重构有一些目的,就是起码开源部分的类库,能更新的,应该尽可能的更新,能不用的类库,尽量去掉。
- Mootools 更新 1.6+,去掉More库
- jQuery,更新2.2+
- underscore换成lodash,underscore作者已经哭晕了,coffee渐渐es6取代,underscore被lodash取代,backbones,也不是非他不可,前端mvc如phpmvc一般雨后春笋般冒出,underscore也很久不更新了。
- uikit 更新到2.15+
- requirejs,Good bye!!
- 清查无用的jQuery插件
- 开源的工具也依次更新等。
- 增加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前端重构感受相关推荐
- 高性能流媒体服务器EasyDSS前端重构(二) webpack + vue + AdminLTE 多页面提取共用文件, 优化编译时间...
本文围绕着实现EasyDSS高性能流媒体服务器的前端框架来展开的,具体EasyDSS的相关信息可在:www.easydss.com 找到! 接上回 <高性能流媒体服务器EasyDSS前端重构(一 ...
- webpack服务器性能,高性能流媒体服务器EasyDSS前端重构(三)- webpack + vue + AdminLTE 多页面引入 element-ui...
接上篇 本文围绕着实现EasyDSS高性能流媒体服务器的前端框架来展开的,具体EasyDSS的相关信息可在:www.easydss.com 找到! element-ui 介绍 饿了么前端开发组件框架 ...
- EasyDSS高性能流媒体服务器前端重构
本文围绕着实现EasyDSS高性能流媒体服务器的前端框架来展开的,具体EasyDSS的相关信息可在:www.easydss.com 找到! EasyDSS 高性能流媒体服务器前端架构概述 EasyDS ...
- 前端重构实践(一) —— 性能优化
前言: 最近一直在做性能优化和模块化改造的工作,并完成了一次前端重构.在这里总结出一些经验和得失来帮助大家思考.共两篇文章,第一篇讨论性能优化,第二篇讨论模块化框架.而之所以把这两个话题放到一起,是因 ...
- webpack前端构建工具学习总结(一)之webpack安装、创建项目
npm是随nodeJs安装包一起安装的包管理工具,能解决NodeJS代码部署上的很多问题: 常见的使用场景有以下几种: 允许用户从NPM服务器下载别人编写的第三方包到本地使用. 允许用户从NPM服务器 ...
- vscode中6个好用的前端重构插件
Visual Studio Code(简称VS Code)是一款由微软开发且跨平台的免费源代码编辑器.基于其丰富的插件体系与语言支持,目前已经成为了最流程的集成开发环境.本文介绍了笔者用过的最好用的几 ...
- # 什么是前端重构?
前端是做什么的 说到前端,我们往往会随口蹦出一个后端,没错,如果单纯从计算机工程的角度来看待前端所做的工作,就是前端是后端的门面,用个形象的例子来比喻前后端,我们平常使用的手机是前端,而背后的手机系统 ...
- EasyDSS高性能流媒体服务器前端重构(五)- webpack + vue-router 开发单页面前端实现按需加载 - 副本...
为了让页面更快完成加载, 第一时间呈现给客户端, 也为了帮助客户端节省流量资源, 我们可以开启 vue-router 提供的按需加载功能, 让客户端打开页面时, 只自动加载必要的资源文件, 当客户端操 ...
- 万字长文:2019 年 京东 PLUS 会员前端重构之路
原 作 者:京东设计中心JDC 原文链接:https://url.cn/50og5J9 时光如梭,白驹过隙,2019 年转瞬即逝.这一年对于 PLUS 会员项目前端同学来说是坎坷和充实的,如白岩松 ...
最新文章
- python汉字编码错误_python解决汉字编码问题:Unicode Decode Error
- 统计学习导论 Chapter4--Classification
- 运维监控系统——配置服务监控项(Http,Nginx,MySQL)
- 【我眼中的戴尔转型】 (二) 厚积薄发,戴尔扩大战线迎头追击IBM HP
- C++标准库 第七章 STL迭代器
- 一步一步学习SignalR进行实时通信_5_Hub
- android 碎片问题,Android碎片问题
- qmenu qt 关闭,Qt实现点击菜单项后QMenu不关闭功能
- 20145109 《Java程序设计》第七周学习总结
- Command ‘docker‘ not found, but can be installed with:
- win10桌面右键一直转圈是什么原因
- FMI飞马网 | 【线上直播】如何处理好横向关系 在协同与合作中实现双赢(下)
- yaourt/yay 安装软件出现 parse “XXX“: first path segment in URL cannot contain colon 错误
- c 语言字符串查找替换,c ++ - 如何在标准字符串中搜索/查找和替换?
- C++ 泛型编程(五) 模版重载与特例化
- patch-package打补丁
- 阿里云被攻击用高防CDN的效果如何?
- 3D卷积的GEMM+IM2COL实现
- 每日学术速递4.12
- 中国老百姓十大欲望排行榜。
热门文章
- OpenCV(二)OpenCV的介绍和发展
- mybatis-generator 根据表生成对应文件
- 城市大脑 —— 数据重塑城市未来
- 为什么别人一周搞定Linux,而你却做不到
- centos6.3配置 kickstart 无人值守安装centos6.3系统 httpd方式
- OpenCV学习(17) 细化算法(5)
- sqlplus connect oracle
- DSOFramer使用说明(转载)))
- 【DFS + backtrack】LeetCode 37. Sudoku Solver
- 牛客网–华为机试在线训练7:取近似值