我和我的广告前端代码(六):webpack工程合并、也许我不需要gulp
随着年初开始使用webpack重构公司的广告代码,已经有将近一年的时间了,需求也渐渐的稳定了。我想也是时候将这几个工程整理一下,顺带着处理一些历史问题。
由于当年各个业务线没有整合、需求也没有固定,考虑到将来随着不同业务线的发展方向不同,我为不同业务线的广告代码创立了不同的git工程,分别开发。但是我仍然为他们采用了相同的项目配置和基础逻辑,为将来有一天需要整合的时候做准备。这就导致了在不同业务线的广告代码中我有很多相同的基础模块,一旦修改这些模块,就要分别手动同步一遍,费时费力。因此这一次的优化的第一要务就是合并工程。另外采用webpack开发,我日后加入es6模块后需要source-map来方便调试。最后就是进来使用vue-cli的感悟,我原有的工程太依赖gulp,在阅读了vue-cli生成的webpack工程后,我打算尝试将项目中的gulp替换成npm script。
因此我这次优化的任务就有了以下的几条:
1、工程合并:webpack多入口;
2、soucemap:加入sourcemap选项,并区分开发联调环境和上线环境;
3、npm script替换gulp;
4、bug修改;
一、工程合并、多入口
最开始的时候将pc和wap的广告代码分别配置了两个git仓库,由于业务模式是差不多的,所以才用了相似的架构,不同点在于两端的广告特型是不同的、浏览器适配方案不同,这就导致了两份代码中有大量的相同的模块,每次修改这些相同的模块时要同事修改另一个,当是的做法是将这些模块猎在一个json文件中,一旦有修改就跑一段gulp脚本同步一下。但是这样做终究不是办法。这本身就是一个很不合理的方案,那么我为什么要分成两个。原因是长期以来PC的后台和wap的后台长期由两个不同的后端组编写,而且后端架构分别由PHP和Java实现,不同业务线的维护工作有可能拆分到别的部门来维护,这是一个历史原因。正是基于这个原因,我没有将两个藕合在一起,以方有一天我需要将两份代码拆开交给不同的团队来维护。
但是我仍然考虑了有一天会合并在一起,所以一直强行规范这两个项目中逻辑结构和相同的功能模块保持同步,这为我能够在未来的某一天可以顺利的将两个工程合并以及当出现新业务线时,可以快速编译出一份新的广告代码,我的代码一定要能支持不同的场景,并不为了某一个业务线而产生。事实上随着广告业务资源的整合与稳定,我现在打算做出这种尝试。
我在最初选用webpack也是出于多入口,理论上我只需要将wap中不同的入口模块和业务特型拷贝到PC,然后修改webpack配置文件,就可以实现合并。
那么我简单说一下webpack的多入口配置(我先给出官方文档):
我们要关注的主要是webpack.config.js,当然你的工程中webpack配置文件可能不叫这个名字。以我的为例:
1 var path = require('path'); 2 var webpack = require('webpack'); 3 //var HtmlwebpackPlugin = require('html-webpack-plugin'); 4 //定义了一些文件夹的路径 5 var ROOT_PATH = path.resolve(__dirname); 6 var APP_PATH = path.resolve(ROOT_PATH, './src/app'); 7 var BUILD_PATH = path.resolve(ROOT_PATH, './src/build'); 8 // var NODE_PATH = path.resolve(__dirname, 'node_modules'); 9 10 module.exports = { 11 //项目的文件夹 可以直接用文件夹名称 默认会找index.js 也可以确定是哪个文件名字 12 entry: { 13 "yourcodepcv1": APP_PATH + '/index.js', 14 "yourcodewapv1": APP_PATH + '/index-wap.js' 15 }, 16 //输出的文件名 合并以后的js会命名为adsfehomev1.js 17 output: { 18 path: BUILD_PATH, 19 filename: '[name].js'//, 20 // sourceMapFilename: '[file].map', 21 // devtoolLineToLine: true 22 }, 23 devtool: '#source-map', 24 externals:{ 25 jquery: "jQuery" 26 } 27 };
其实,很简单。我们一起来看一下,主要看module.exports中的entry和output,entry接收我们传入一个对象如下图,每一组的键值对都是一个入口,我这里写了两个入口文件。
但是webpack并不允许我们传入一个好几组输出键值对。事实上入口中的每一个键值对在webpack中被视为一个“chunk”,我们在ouput中的[name]会被入口中的键名替换,可替换的不仅仅是键名,我们还可以加入[id]、[hash]、[chunkhash]等。
实际运行webpack后会看到终端中如下信息:
其中有一列chunks,看到我们有两个chunk: 0和1。 0是我的pc代码,1是wap的。而对应的source-map也不会新建chunk。输出是也用了我们的[name]。
实际开发中,当然不仅仅是入口不同,webpack通过require关键字查找文件,如果不同入口饮用了同一个模块,但是这个模块却依赖pc和wap各自的模块,我们可以在入口处定义好一个map缓存到一个通用的数据模块,这个模块的数据并不会硬编码,而是由入口处传入。也可以是各写各的,仅仅把复用的模块提出来饮用。但是这样做虽然简单但是当我想在加入一个入口时,就要写一溜文件,并不如入口定义map这种方便,加一个文件就行。当然方法有很多,条条大路通罗马,js语法是很强大的。
二、sourcemap
这个其实比较简单,webpack是支持的,看我上面的配置文件,就可以看到 :
devtool: '#source-map'
看过我第一篇文章的朋友会看到,我最开始是用requireJS写的,好处在于开发时文件有浏览器异步加载,调试的时候找到那个文件就比较好调试。可是现在不同了我用webpack在nodeJS环境预编译打成一个文件。试想一下文件挺大的,而且和我写的并不是完全一样,找个东西不太方便,何况我用ES6写的部分更是被转化了。我需要souce-map来告诉我应该对应源文件的那一行。
三、npm script代替gulp
我在开始写的时候直接用了gulp,不得不承认gulp很强大,而且很方便。可是我要做的事情并没有那么复杂,我需要的主要是:多任务、不用记不同的命令、webpack打包、mocha测试、jslint检查、开发环境变异、上线环境打包、部署等。其实不需要太深厚的nodejs功力,即使不实用gulp也可以搞定。
其实我这种想法来自于我前段时间写vue,当时我用到了vue官方的vue-cli,对 就是那个脚手架里面虽然用了webpack,可是没有用gulp、grunt等工具。取而代替,用的是npm script。用过的同学会了解,就是package.json中那个“scripts”快捷命令。其实从另一个方面来说gulp和jQuery都是让人又爱又恨的工具,好的是确实方便,不好的是这些工具让我们对原生技术的原理、机制有了错误的理解。而且npm的包要比gulp的包要多很多,一般来说,功能都是在npm有了用着不错,想在gulp中用才会被人封装成gulp-XXX包。相应的更新维护速度,谁比较快就比较明显了。
下面我就简单的以我的工程为例子介绍一下,如何使用npm script配置工程:
就一我dev(开发环境,watch编译)和build(打包、压缩)为例:npm run dev;npm run build就可以调用。
对于我来说开发环境只要在终端输入webpack就可以了。而我原来是怎么做的:为了让gulp能够控制整个流程,我是在gulp中require("webpack")而是利用gulp的watch,这么做的缺点在于为了用gulp无意中让webpack的使用更加繁琐,而且gulp的watch相当于gulp取监听文件变化,在取调用webpack,如果写的不好每次相当于从新运行webpack,ES5还好,如果用了很多loader,比如ES6 bable,就会很慢(10s以上,不能算是即时编译)。而webpack自带的 -w不同,第一次慢一点,之后就缓存在内存中了,即使是ES6,也会很快。
问题来了,我build为什么不想dev那样写?因为build不仅仅用到了webpack,而且用了不同的webpack配置。我把要做的事情封装到minitodist.js中,并且因为build任务和cdn任务很像,我在调用npm run build的语句中传入了一个参数‘dist’。那么有什么不同呢:
1、调取不同的webpack配置;
2、修改版本变量;
3、根据参数输出到不同文件夹;
其实webpack配置仅仅是一部分不同,所以我用了webpack-merge来生成build用的配置:
1 var path = require('path') 2 var webpack = require('webpack'); 3 var merge = require('webpack-merge'); 4 var baseWebpackConfig = require('./webpack.config'); 5 var ROOT_PATH = path.resolve(__dirname); 6 var APP_PATH = path.resolve(ROOT_PATH, './src/app'); 7 var BUILD_PATH = path.resolve(ROOT_PATH, './dist'); 8 9 var modifiedDate = +(new Date()); 10 11 var webpackConfig = merge(baseWebpackConfig, { 12 devtool: false, 13 output: { 14 path: BUILD_PATH, 15 filename: '[name].min.js', 16 }, 17 plugins: [ 18 new webpack.optimize.UglifyJsPlugin({ 19 compress: { 20 warnings: false 21 } 22 }), 23 new webpack.BannerPlugin('This file is modified at:' + modifiedDate) 24 ] 25 }); 26 27 module.exports = webpackConfig
先写var baseWebpackConfig = require('./webpack.config');来获取webpack.config.js。再调用webpack-merge模块创建新的配置,通过exports输出。
比如我想要在线上环境使用已经压缩的代码。我就在新的配置中的“plugins”中加入webpack.optimize.UglifyJsPlugin,并且在输出时将文件名改成XXX.min.js(也可以不加min)。我也可以在文件头加入有关版本的注释(webpack.BannerPlugin)。
关于node环境调用文件的参数的问题。当你用如下语句:
node xx.js ‘abc’
在xx.js中可以这样拿到:(具体原理就不解释了)
var arguments = process.argv.splice(2); console.log(arguments[0]);
如package.json文件我陆续的写了别的任务。目前是不需要使用gulp的,对比一下我前后的依赖列表:
之前:之后:
是不是感觉少了很多。
总结:不管部门的调整后,我是否还会维护这套广告代码,我仍希望交给别人一套易读的容易维护的工程,我希望我写的不仅仅是程序,而是工程,有始有终。
转载于:https://www.cnblogs.com/webARM/p/6058505.html
我和我的广告前端代码(六):webpack工程合并、也许我不需要gulp相关推荐
- 使用 vscode 调试前端代码
使用 vscode 调试前端代码 今天我们以webpack项目为基础讲解配置 复制代码 1. 安装插件 Debugger for Chrome 2. 修改 config/index.js 将devto ...
- 【转】在生产环境中部署前端代码
在生产环境中部署前端代码 本文章前端代码是基于vue+webpack开发的 Nginx是一款轻量级的Web 服务器/反向代理服务器 首先,webpack配置如下 在开发过程中,我们是通过npm run ...
- 最佳实践系列:前端代码标准和最佳实践
最佳实践系列:前端代码标准 @窝窝商城前端(刘轶/李晨/徐利/穆尚)翻译于2012年 版本0.55 @郑昀校对 isobar的这个前端代码标准和最佳实践文档,涵盖了Web应用开发的方方面面,我们翻译了 ...
- 测试你的前端代码 - part3(端到端测试)
本文作者:Gil Tayar 编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58d50da37413fc2e8240855c ...
- css初始化样式文件_前端必备技能 webpack 4. webpack处理CSS资源
每篇文章纯属个人经验观点,如有错误疏漏欢迎指正 因为 webpack 本身只具有识别 JS 的能力,所以涉及到其他资源,需要我们通过 loader 来进行特殊处理,针对不同的样式资源,需要以下几个 ...
- 前端代码标准最佳实践:HTML篇
Web前端代码中,HTML是根本,CSS和JavaScript也是围绕着既有的HTML结构来构建,所以良好的HTML代码结构,除了提高了HTML代码的可读性,可维护性和执行性能之外,也可以让相对应的C ...
- 网易智慧企业 Node.js 实践(2)| 平滑发布和前端代码
健康检查 前文提到我们通过网关把流量转发到 Node 应用,那网关是如何确定 Node 应用的可用性呢? 如果 Node 应用在发布的过程中也把流量转发过来,就会导致请求失败,所以我们的网关会对 No ...
- 时下最流行前端构建工具Webpack 入门总结
作者:wenjuanrao,腾讯 PCG 前端开发工程师 最近梳理了下以前 webpack 的相关开发经验,整理和总结了一份入门笔记,欢迎大家围观和批评指正. 随着 web 应用越来越复杂和庞大,前端 ...
- eslint规范_规范统一前端代码风格
背景 众所周知,前端项目的代码质量和代码格式的校验是不可或缺的.很早之前在一个人开发的时候,脚手架生成vue项目的时候都没有打开过eslint,后面有位大佬加入,给boss说,加了个插件(eslint ...
最新文章
- LeetCode第 146 号问题: LRU 缓存机制
- quot;streambufquot; ambiguous symbol的问题如何解决
- 一个IO的传奇一生(8) -- elevator子系统
- mysql三范式_MySQL设计之三范式的理解
- React 正常渲染后端返回的HTML代码
- php开发入门,PHP开发入门教程之面向对象
- 【3】C++语法与数据结构之MFC_CList学生管理系统_链表外排序_函数指针
- 模板类的析构函数如何写_顶尖文案如何写?这6大模板、29个方法,奥美大咖都在用!|优惠最后1天...
- 前端学习(2915):数据绑定
- 多机器人路径规划的代码_知荐 | 地平线机器人算法工程师总结六大路径规划算法...
- 实时数仓与离线数仓总结(一)
- 再发Wallop和GMail邀请各4个!
- 大专适合学习php么_中专毕业上大专好还是出来工作?
- 计算机视觉 - 字典学习
- 如何快速看懂英文论文?
- 基于HL7-V3医疗系统信息交换标准SOAP开发
- 如何在MS Access中创建用户权限和自定义菜单
- php怎么分栏,wps怎么分栏排版
- 二项式(伯努利),多项式分布
- Spring Data ElasticSearch 3.2版本发布,相关新特性说明
热门文章
- 六大设计原则之迪米特法则
- Solr Zookeeper ACL权限配置
- 在 GridView 控件中添加一列复选框51
- 在VS中MFC、ATL与WIN32有什么联系或区别?
- 随机生成器、thread(暂停)、清屏定义
- Codeforces 427 D. Match amp; Catch
- 关于Ubuntu 安装tftp服务器的问题解决
- io操作是指什么_各种IO模型,一篇打尽
- 文件上怎么盖章_投标文件该怎么盖章呢?投标人必看!
- javascript字典中添加数组_如何在JavaScript中使用数组方法:Mutator方法