├── .gitignore ├── img ├── cd.jpg ├── pwa-2.jpg ├── ssr.png ├── tfc-1.png ├── tfc-2.png ├── pwa-1.jpeg └── architech.png ├── blog ├── webpack-plugin.md ├── ie7compatible.md ├── postcss.md ├── CI.md ├── git-vscode.md ├── TFC.md ├── vue-test.md ├── AC.md ├── bem.md ├── jsonp.md ├── iframe-height.md ├── vue-startup.md └── perfomance.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | .idea -------------------------------------------------------------------------------- /img/cd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaicFE/blog/HEAD/img/cd.jpg -------------------------------------------------------------------------------- /img/pwa-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaicFE/blog/HEAD/img/pwa-2.jpg -------------------------------------------------------------------------------- /img/ssr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaicFE/blog/HEAD/img/ssr.png -------------------------------------------------------------------------------- /img/tfc-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaicFE/blog/HEAD/img/tfc-1.png -------------------------------------------------------------------------------- /img/tfc-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaicFE/blog/HEAD/img/tfc-2.png -------------------------------------------------------------------------------- /img/pwa-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaicFE/blog/HEAD/img/pwa-1.jpeg -------------------------------------------------------------------------------- /img/architech.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PaicFE/blog/HEAD/img/architech.png -------------------------------------------------------------------------------- /blog/webpack-plugin.md: -------------------------------------------------------------------------------- 1 | # webpack插件 2 | 3 | - [image-webpack-loader](https://github.com/tcoopman/image-webpack-loader) 4 | - [multipage-webpack-plugin](https://github.com/mutualofomaha/multipage-webpack-plugin) 5 | - [ejs-compiled-loader](https://github.com/bazilio91/ejs-compiled-loader) -------------------------------------------------------------------------------- /blog/ie7compatible.md: -------------------------------------------------------------------------------- 1 | # ie 7兼容想法 2 | 3 | nodejs express Nunjucks less bootstrap2 jquery1 require.js gulp 4 | 5 | 正因为是兼容ie7或者ie8以上的pc端的页面,我在整个项目的计划中,因为ie7不支持了es5的语法。直接和react和vue等框架说“byebye”。虽然网上有很多的兼容的方法,但是怕一旦使用了整个过程就变得很尴尬。 6 | 7 | 这时,我第一反应就是用express和模版语言,实现动态的数据单项绑定,技术有点旧,但是保证了兼容性以及组件化的拆分。而js的模块化则是用require.js和gulp的自动化操作。 -------------------------------------------------------------------------------- /blog/postcss.md: -------------------------------------------------------------------------------- 1 | # POSTCSS使用技巧 2 | 3 | postcss的发展非常快,它可以对css进行逻辑的控制,变量的提取,更像一个插件平台,提高项目的开发效率。 4 | 5 | ## [autoprefixer](https://github.com/postcss/autoprefixer) 6 | 7 | 不同浏览器的样式会有不同的前缀,如果在构建项目的过程当中,我们需要一个一个浏览器考虑兼容,确实不符合我们的开发效率。 8 | 9 | 10 | 11 | ## BEM 12 | 13 | BEM分别代表着Block,Element,Modifier。 14 | 15 | Block指的是块,我们可以理解为组件。整个网站是由很多个块组成。 16 | 17 | Element可以理解为块里面的一个元素。使用`__` 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /blog/CI.md: -------------------------------------------------------------------------------- 1 | # 持续集成 2 | 3 | 产品迭代的过程,我们需要成熟的整个持续集成的流程。 4 | 5 | > 持续集成的优点 6 | 7 | >(1)快速发现错误。每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易。 8 | >(2)防止分支大幅偏离主干。如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。 9 | 10 | 11 | > Martin Fowler说过,"持续集成并不能消除Bug,而是让它们非常容易发现和改正。" 12 | 13 | ## 持续部署和持续交付 14 | 15 | ![持续部署和持续交付](../img/cd.jpg) 16 | 17 | 它俩的区别在于主要是在完成编码,测试,集成,测试后,部署到生产环境的这一个过程是自动还是人为的。人为有人为的好处。 18 | 19 | ## Jenkins 20 | 21 | 22 | 23 | ## Travis 24 | 25 | ## Gitlab 26 | 27 | [Continuous Deployment of Node.js Applications](https://blog.risingstack.com/continuous-deployment-of-node-js-applications/) -------------------------------------------------------------------------------- /blog/git-vscode.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 提交信息 4 | 5 | `git commit`提交信息的规范,建议在提交信息头部加上这几个类型。 6 | 7 | - 增加功能 8 | - 更新功能 9 | - 删除功能 10 | - 优化代码 11 | - 合并代码 12 | - 修复bug 13 | 14 | ## ITREM + OH MY ZSH的相关操作 15 | 16 | #### 安装 17 | 18 | **via curl** 19 | 20 | ```bash 21 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" 22 | ``` 23 | 24 | **via wget** 25 | 26 | ```bash 27 | sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)" 28 | ``` 29 | 30 | #### 环境变量的配置 31 | 32 | ```bash 33 | vim ~/.zshrc 34 | ``` 35 | 36 | ```bash 37 | alias code='/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code' 38 | alias subl='/Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl' 39 | alias ngrok='~/software/ngrok' 40 | ``` 41 | 42 | ## vscode关于eslint配置 43 | 44 | ```javascript 45 | "eslint.validate": [ 46 | "javascript", 47 | "javascriptreact", 48 | "html", 49 | "vue" 50 | ], 51 | "eslint.options": { 52 | "plugins": ["html"] 53 | }, 54 | "git.confirmSync": false 55 | ``` 56 | 57 | 参考[【译】让人倾倒的 11 个 npm trick](https://segmentfault.com/a/1190000006804410) 58 | 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blog 2 | Blog for PAIC FE Team 3 | 4 | - [【技术分享】Vue的选型和Webpack的入门](https://github.com/PaicFE/blog/issues/1) by 项伟平 5 | - [【技术研究】如何动态获取跨域iframe高度](https://github.com/PaicFE/blog/issues/2) by 项伟平 6 | - [【技术分享】国内开发加速方法合集](https://github.com/PaicFE/blog/issues/3) by 项伟平 7 | - [【技术分享】JSONP和跨域](https://github.com/PaicFE/blog/issues/8) by 项伟平 8 | - [【技术研究】性能优化之路](https://github.com/PaicFE/blog/issues/9) by 项伟平 9 | - [【技术分享】参加腾讯Web前端大会体验](https://github.com/PaicFE/blog/blob/master/blog/TFC.md) by 项伟平 10 | - [【技术分享】手牵手使用Husky & Nodejs自定义你的Git钩子](https://github.com/PaicFE/blog/issues/10) by 杨凯 11 | - [mocha的单元测试](https://github.com/PaicFE/blog/issues/11) by 项伟平 12 | - [入门BEM](https://github.com/PaicFE/blog/issues/12) by 项伟平 13 | - [AlloyTeam 前端大会的技术一览](https://github.com/PaicFE/blog/issues/13) by 项伟平 14 | - [Vue的自动化测试](https://github.com/PaicFE/blog/issues/14) by 项伟平 15 | - [Phantomjs教你如何实现浏览器截图并上传截图文件](https://github.com/PaicFE/blog/issues/15) by 杨凯 16 | - [多页面打包框架(mpa)](https://github.com/PaicFE/blog/issues/16) by 项伟平 17 | - [PWA技术分享会](https://github.com/Cainankun/cainankun.github.io/issues/1) by 蔡南坤 18 | - [webpack版本的差异性](https://www.jianshu.com/writer#/notebooks/9046660/notes/22174344) by 项伟平 19 | 20 | 21 | 22 | 欢迎点击watch订阅我们博客。 23 | 24 | -------------------------------------------------------------------------------- /blog/TFC.md: -------------------------------------------------------------------------------- 1 | # 【技术分享】参加腾讯Web前端大会体验 2 | 3 | 我是第一次参加那么正式的前端技术交流大会。趁着“前端”的这点热度,我也来抽个热闹。这里讲讲我自己比较印象深刻的几点感受。 4 | 5 | ## Nicolás Bevacqua的 The Future of Writing Javascript 6 | 7 | 我看了一下来自阿根廷布宜诺斯艾利斯的[Nicolás Bevacqua](https://github.com/bevacqua/)的github。他真是javascript界的大牛,他参与的组织和他提交的代码量挺疯狂的,项目随便都是上万星的,简直就是偶像。 8 | 9 | ![参与的组织](img/tfc-1.png) 10 | 11 | ![提交的代码](img/tfc-2.png) 12 | 13 | 14 | 虽然他的英语口音非常重,但是他讲的内容还是相当友好浅显的。es6已经成为我们项目的标配,但是我相信很多同事还没有完全懂的如何使用es6的新语法。何况es2017已经渐渐到来。Nicolas讲述了整个javascript从讨论,提案,草案,候选,完成的过程。不同的stage都完成这不同的特性。让我们感受到javascrit还在快速的发展,据我了解“面向对象如今支持私有变量”。在实际的应用当中,我们更应该用上新语法特性提高开发效率。它具体介绍了以下几个特性。 15 | 16 | - Promise的finally方法 17 | - 类的修饰器 18 | - 正则表达式的命名捕获 19 | - 正则表达式的后行断言 20 | - async和await 21 | 22 | ## 玉龙大大的初创公司前端工程体系建设 23 | 24 | 玉龙大大的干货真是非常实用,没有什么最热门的前端框架的讨论,更多是后端渲染的模版。语言简练却富含实战性。 25 | 26 | 给我影响深刻的是Gitlab CI的持续集成和dom diff的测试提交。 27 | 28 | #### Gitlab CI的持续集成 29 | 30 | 我们公司更多是使用Jenkins去完成自动集成,主要原因是因为后端大部分是JAVA语言。Jenkins其实还是能保证一个很好的部署效率,但是明显更不上时代的节奏。现在的持续继承技术非常强大。 31 | 32 | 玉龙大大指出的多个测试域名的“思路”,也是让我“叹为观止”。为每个feature的实现独立设置域名,保证了每个功能开发的完整性,同时,提高了测试的效率。保证每个开发者有独立的测试环境,无形地提高了“并行”开发的可能性。 33 | 34 | #### dom diff的测试提交 35 | 36 | 我认为我们组的测试效率不高,很大一部分是**show case**的质量很差。业务和产品经常改需求,导致测试的效率大大降低。native的测试占用了大量的时间,留给H5的并不多。所以我们需要的是提高show case的效率。把每个dom的变化分类提交。 37 | 38 | ## JustJavaC的V8性能优化 39 | 40 | sorry,我才疏学浅没怎么听懂。大概是混合语言的部分更多是数据类型的转换。V8的性能优化更多是数据类型的转化。 41 | 42 | ## PWA和AMP 43 | 44 | 我认为这是我在TFC的又一大收获。PWA是一个相对成熟的技术,受到的影响更多是因为ios暂不支持的阻碍。我个人认为像react native或者weex等混合语言开发的,需要非常大地学习成本。react到react native的改造不是一两天能完成的,但是PWA的改造是完全可以通过一两个小时完成,只需要你了解servive worker的接口。在如今流行的前端框架中,vue,react和preact都有支持pwa的模版。 45 | 46 | - vue 47 | 48 | ```bash 49 | vue init pwa my-project 50 | ``` 51 | 52 | ```bash 53 | 54 | ``` 55 | 56 | 57 | -------------------------------------------------------------------------------- /blog/vue-test.md: -------------------------------------------------------------------------------- 1 | # Vue的自动化测试 2 | 3 | Vue官方脚手架会自带测试配置,但是我们知道国内的前端友人大多不写测试,也不会写测试。 4 | 5 | **为什么我们需要测试?** 6 | 7 | > 让产品可以快速迭代,同时还能保持高质量 -- [阮一峰 持续集成是什么?](http://www.ruanyifeng.com/blog/2015/09/continuous-integration.html?utm_source=tuicool&utm_medium=referral) 8 | 9 | **什么是持续集成?** 10 | 11 | **它和持续部署有什么区别?** 12 | 13 | 代码集成到主分支的时候,需要经过一系列的自动化测试,当测试都通过之后,可以完成自动化部署。只要一个测试用例不通过,就不能集成。这说明了自动化测试的重要性,有时候我们不能等测试工程师去发现问题。 14 | 15 | 在Vue脚手架当中,Karma和NightWatch分别对应着单元测试和e2e测试。单元测试更多是面向JS功能逻辑的检验,而NightWatch更多是面对业务逻辑的检验。 16 | 17 | ## Karma 18 | 19 | [Karma](https://github.com/karma-runner/karma)是一个专门的测试运行器(runner),它不是一个测试框架框架,也不是以一个断言库。 20 | 21 | Karma兼容[Jasmine](https://github.com/karma-runner/karma-jasmine),[Mocha](https://github.com/karma-runner/karma-mocha)和[QUnit](https://github.com/karma-runner/karma-qunit),可以集成mocha,webpack等功能,成为以Karma为平台的单元测试。它拥有一些测试插件: 22 | 23 | - [karma-webpack](https://github.com/webpack-contrib/karma-webpack) 用webpack预处理文件 24 | - [karma-coverage](https://github.com/karma-runner/karma-coverage) 测试覆盖率 25 | - [karma-mocha](https://github.com/karma-runner/karma-mocha) 接入mocha测试框架 26 | - [karma-spec-reporter](https://github.com/mlex/karma-spec-reporter) 输出报告 27 | - [karma-phantomjs-launcher](https://github.com/karma-runner/karma-phantomjs-launcher) 控制PhantomJS 28 | - [karma-phantomjs-shim](https://github.com/tschaub/karma-phantomjs-shim) 给PhantomJS兼容的控制 29 | 30 | karma-coverage是基于[istanbul](https://github.com/gotwarlost/istanbul)。这些插件可以集成为一个测试平台,把webpack打包的vue项目,在测试里面的组件实现的功能。包括独立的组件库,业务逻辑和请求范围。 31 | 32 | 33 | ## NightWatch 34 | 35 | NightWatch是一个专门的端对端测试运行器(runner)。 36 | 37 | 它依赖于浏览器控制器selenium,而selenium是一个`.jar`后缀的文件,需要java的运行环境。所以你需要安装java并配置好环境变量。然而,selenium需要对应的driver配合来操控浏览器。 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /blog/AC.md: -------------------------------------------------------------------------------- 1 | AlloyTeam Conf是一个干货非常集中的前端大会。就前端的技术,我分享一下前端大会的内容,谈谈自己的想法。 2 | 3 | ## 面向亿万级用户的Web同构直出 4 | 5 | 直出技术也就是传说中的服务端渲染“SSR”技术,Web首屏页面的加载速度能得到极大提升。AlloyTeam采用的是React技术栈同构直出,我们采用Vue技术栈的同构直出。 6 | 7 | 主讲人李强用实战经历说明了手Q在高访问量的直出表现,他说道,直出其实减轻了浏览器的负担,但是增加了服务器的负担,大概是以前的5倍。这个在生产环境实现起来事有难度的。 8 | 9 | #### 实现原理 10 | 11 | 12 | ![ssr](http://upload-images.jianshu.io/upload_images/685800-f92b59720ec0501c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 13 | 14 | 15 | SSR技术说白了就是在服务端和浏览器端各有一个入口,共用一份代码。服务端会把内容拼接好,缓存起来,提高首屏效率。代码的差异性需要处理,例如生命周期不同。 16 | 17 | > 由于没有动态更新,所有的生命周期钩子函数中,只有 beforeCreate 和 created 会在服务器端渲染(SSR)过程中被调用。这就是说任何其他生命周期钩子函数中的代码(例如 beforeMount 或 mounted),只会在客户端执行。 18 | 19 | 所以有些浏览器相关的内容要在 mounted 底下写。简而言之,SSR的vue项目需要注意的点和普通项目不同,迁移会带来成本。 20 | 21 | 因为涉及到更多的服务端,SSR会带来更大的服务器宕机的风险。腾讯的做法事监测服务器的负载,负载过高的情况有柔错处理,也就是服务器会指向“Plan B”非SSR的页面。这样,也就是你一套代码要打包出两套页面(SSR和非SSR)。 22 | 23 | 24 | ## 大型Web项目可用性提升 - 零脚本错误的实战 25 | 26 | 脚本错误对于前端开发者一点都不陌生。测试工程师手上机型有限,一旦发生脚本错误,轻则影响页面的一些功能,重则直接导致页面白屏。大众用户处在不同的网络情况、不同的浏览器。也有可能是后台改了数据类型等,更新数据出错都有可能反应在前端。 27 | 28 | 高效的错误收集分类是非常重要,有这么一个平台可以收集到很多数据,从而进一步优化整个页面,这是一个良性的反馈。[Sentry](https://github.com/getsentry/sentry)是有名的错误上报平台,服务端是python写的,提供很多款语言的SDK,进行定制化的错误分类分析。 29 | 30 | 同时,他提到在测试环境做了错误定位组件,也非常有实用价值。 31 | 32 | ## 高效H5动画设计与性能优化 33 | 34 | h5的动画是随着flash正式退出历史舞台,它需要一个重要的蜕变。它包含了动图,css3动画,canvas,webgl等。要让页面变得生动活泼起来,绝对不是一件简单的事情。在那些场景用动图,那些场景用css3,那些场景用canvas,其中的选型变得非常重要。 35 | 36 | css3动画可以采用GPU加速,“willchange”等能够挽回一些安卓低端机型的劣势,但是过分的滥用会同样会造成资源浪费。 37 | 38 | 39 | ## 后函数式编程 40 | 41 | 函数式变成离我们产品的需求应该是最远。函数式编程,带来的是代码高维护性和观察者模式。rx.js,cycle.js应该在项目中可以有可以没有。在数据同步和响应方面更多可以从需求的复杂程度下手。我另外一个受益点,即是纯函数的编写,纯函数的结果不受外部的变量影响,可以缓存,可以测试,有助于代码的编写。 42 | 43 | ## Service Worker与PWA展望 44 | 45 | 相比与其他技术,Service Worker是离我们投入生产环境最近。随着很多厂家逐渐兼容PWA技术,例如安卓微信浏览器。PWA技术的优势在于不需要大范围改代码,而且轻松兼容旧浏览器。 46 | 47 | 48 | ![pwa](http://upload-images.jianshu.io/upload_images/685800-32231b98b7c206d0.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 49 | 50 | 51 | Service Worker更像一个“媒介”“代理”。检查着静态资源的更新情况,优先价值离线资源,旧的资源将会被更新,其中包括了html,js,css还有fetch请求等。整个执行会有“安装”“激活”的过程,其实非常简单,完成即可从浏览器读取数据。结合多页面的Vue框架,将会是成为我下一年的一个重点工作目标。 52 | 53 | 54 | ![pwa](http://upload-images.jianshu.io/upload_images/685800-aa61f757adefff05.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 55 | 56 | 57 | ## 总结 58 | 59 | 我在AlloyTeam Conf的收获还是特别多,我认为能够和自己工作能联系在一起的技术,才是真正的“好技术”,继续加油。 60 | -------------------------------------------------------------------------------- /blog/bem.md: -------------------------------------------------------------------------------- 1 | # 【技术分享】入门BEM 2 | 3 | ## 前言 4 | 5 | **为什么不用ID标识符** 6 | 7 | 主要考虑到样式重用性以及与页面的耦合性。ID本来就是唯一的而且权值那么大,还不如写在行内样式。 8 | 9 | ``` 10 | #button { 11 | text-decoration: underline; 12 | } 13 | ``` 14 | 15 | **为什么不用大于三层嵌套选择器** 16 | 17 | 嵌套选择器增加了代码耦合,使重用变得不可能,过多的嵌套会导致显示性能下降。简洁的选择器不仅可以减少css文件大小,提高页面的加载性能,让浏览器解析时也会更加高效。同时也会提高开发人员的开发效率,降低了维护成本。子代选择器不好的地方还在于,如果层次关系过长,逻辑不清晰,非常不利于维护。 18 | 19 | css的匹配原理**不是从左到右的,而是从右到左的**,从右边开始匹配是为了尽早过滤掉一些无关的样式规则和元素。 20 | 21 | ```css 22 | .button_hovered .button__text { 23 | text-decoration: underline; 24 | } 25 | ``` 26 | 27 | **为什么不用组合选择器** 28 | 29 | 组合选择器的耦合性更强,而且可维护性更加差。 30 | 31 | ```css 32 | .button.button_theme_islands { 33 | text-decoration: underline; 34 | } 35 | ``` 36 | 37 | ## 介绍 38 | 39 | BEM是**Block,Element,Modifier**的缩写。下面分别来介绍一下这三个概念: 40 | 41 | - 块(Block)是一个块级元素,可以理解为组件块,比如头部是个block,内容也是block,一个block可能由几个子block组成。 42 | - 元素(Element)element是block的一部分完成某种功能,element依赖于block,比如在logo中,img是logo的一个element,在菜单中,菜单项是菜单的一个element。 43 | - 修饰符(Modifier)modifier是用来修饰block或者element的,它表示block或者element在外观或行为上的改变,例如actived。 44 | 45 | 这里引用[BEM的定义](http://www.w3cplus.com/css/bem-definitions.html)一文中的两张图: 46 | 47 | ![Definitions-BEM-5.jpg](http://upload-images.jianshu.io/upload_images/685800-3b3eebb021d6f352.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 48 | 49 | ![Definitions-BEM-6.jpg](http://upload-images.jianshu.io/upload_images/685800-e889f5883e808f98.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 50 | 51 | 我们通过BEM命名法写样式如下: 52 | * .block{} 53 | * .block__element{} 54 | * .block--modifier{} 55 | * .block__element--modifier{} 56 | 57 | BEM解决了的问题, 58 | 59 | - 页面CSS模块化,每个block就是一个模块,模块间相互独立,不会造成污染 60 | - 多级的class命名,避免选择器的嵌套结构 61 | - 减少通配符*或者类似[hidden="true"]这类选择器的使用 62 | - 巧妙运用scss的特性,保证了样式的可维护性 63 | 64 | BEM将页面解析为block和element,然后根据不同的状态使用modifier来设置样式,在scss的属性帮助下,其实,写BEM并不麻烦。 65 | 66 | ## 使用scss写BEM 67 | 68 | #### 灵活的& 69 | 70 | 当嵌套使用`&`时,它会直接抓取父选择器的类名,自动拼接上元素名字,避免CSS文件中组件样式的冲突。这样,我们可以得到一个完整的BEM结构的类名,这样有效利用scss的嵌套特性避免CSS文件中组件样式的冲突。 71 | 72 | 示例: 73 | 74 | ```scss 75 | .header { 76 | &__text { 77 | text-decoration: underline; 78 | } 79 | &__image { 80 | background-color: steelblue; 81 | } 82 | } 83 | ``` 84 | 85 | #### 强大的@extend 86 | 87 | `@extend`是scss的继承语法,它可以将父级的属性继承到子级。主要使用在modifier上,因为改变状态的属性和原来的基本保持一致。你可以弄少一个classname。 88 | 89 | 示例: 90 | 91 | ```html 92 | 100 | ``` 101 | 102 | ```scss 103 | .nav { 104 | background-color: steelblue; 105 | &__container { 106 | display: flex; 107 | justify-content: space-between; 108 | } 109 | &__item { 110 | color: white; 111 | &--active { 112 | @extend .nav__item; 113 | border-bottom: 1px solid red; 114 | } 115 | } 116 | } 117 | ``` 118 | 119 | 120 | ## 参考 121 | 122 | - [BEM的定义](http://www.w3cplus.com/css/bem-definitions.html) 123 | - [如何更好的使用BEM](http://www.w3cplus.com/preprocessor/getting-sass-y-with-bem.html) 124 | - [CSS性能分析,如何优化CSS提高性能](http://www.cnblogs.com/xiaoloulan/p/5801663.html) 125 | -------------------------------------------------------------------------------- /blog/jsonp.md: -------------------------------------------------------------------------------- 1 | # 【技术分享】 JSONP和跨域 2 | 3 | 撰稿人:项伟平 4 | 5 | 跨域是一位前端工程师经常面对的问题。 6 | 7 | 面试的时候,面试官会问你一个问题,“解释一下什么是跨域?”,其实百分之八十的面试者都会回答jsonp。如果你回答了jsonp,又会出现很多问题,例如“jsonp的实现原理”,“不用jquery怎么实现jsonp”,“jsonp的安全问题”。如果你回答CORS,也会出现很多问题,例如“CORS的实现原理”,“CORS较jsonp的优点在哪里”,“为什么CORS不用jsonp”。 8 | 9 | ## jsonp是什么? 10 | 11 | ### jsonp的实现原理 12 | 13 | jsonp是一个很老的技术,为啥现在还在使用?很大一部分原因是因为相对来说配置相对简单,后端工程师偷了懒。实现原理用自己的话说就是使用HTML的动态脚本的漏洞。在js端构建一个``,通过一个callback参数构建一种关系,你想得到的参数通过函数回调完成。 14 | 15 | 为了生动形象地展示一下jsonp,我用koa写一个简单的实现。 16 | 17 | ```javascript 18 | const Koa = require('koa'); 19 | const querystring = require('querystring'); 20 | const app = new Koa(); 21 | 22 | const main = ctx => { 23 | var data = { 24 | "name": "Monkey" 25 | }; 26 | var qs = querystring.parse(ctx.request.url.split('?')[1]); 27 | data = JSON.stringify(data); 28 | var callback = qs.callback+'('+data+');'; 29 | ctx.response.body = callback; 30 | }; 31 | 32 | app.use(main); 33 | app.listen(3000); 34 | ``` 35 | 36 | ### 不用jquery怎么实现jsonp 37 | 38 | [jquery](https://github.com/jquery/jquery)或者[zepto](https://github.com/madrobby/zepto)实现jsonp跨域操作非常简单,在设置`dataType`字段时设置为jsonp即可。但是,如果没有了jquery,怎么去实现jsonp,你可能会选择去创建一个动态脚本。把参数和callback拼在url上。 39 | 40 | 如果你使用的是Vue的项目,你应该不会使用jquery,那你怎么使用jsonp? 41 | 42 | - [vue-resource](https://github.com/vuejs/vue-resource) 是支持jsonp 43 | - [axios](https://github.com/mzabriskie/axios) 不支持jsonp 44 | 45 | axios因为在node.js端和browser端同时都支持,而且长期支持。axios的维护者并不打算支持jsonp,正因为它存在着安全性隐患,如果你希望兼容jsonp的接口,可以使用这个库[webmodules/jsonp](https://github.com/webmodules/jsonp)替代部分的功能。vue-resource相对来说,曾经被官方放弃,从设计方面vue-resource相对来说考虑得比较全面,全面兼容jsonp。 46 | 47 | ### jsonp的安全问题 48 | 49 | 从[webmodules/jsonp](https://github.com/webmodules/jsonp)这个库,我们可以看到它的实现方式。jsonp的漏洞在于callback函数,它可以植入脚本影响后端代码。[JSONP 安全攻防技术](http://blog.knownsec.com/2015/03/jsonp_security_technic/)里面介绍了在使用jsonp存在的安全性问题,一方面是json挟持,另一方面是callback植入脚本的漏洞。解决漏洞的方法可以在头文件中加上`Content-Type: application/json`,但是在老版本的ie还是会出现编码安全问题,还需要限制编码`charset=utf-8`。 50 | 51 | > 1. 严格安全的实现 CSRF 方式调用 JSON 文件:限制 Referer 、部署一次性 Token 等。 52 | > 2. 严格安装 JSON 格式标准输出 Content-Type 及编码( Content-Type : application/json; charset=utf-8 )。 53 | > 3. 严格过滤 callback 函数名及 JSON 里数据的输出。 54 | > 4. 严格限制对 JSONP 输出 callback 函数名的长度(如防御上面 flash 输出的方法)。 55 | > 5. 其他一些比较“猥琐”的方法:如在 Callback 输出之前加入其他字符(如:/**/、回车换行)这样不影响 JSON 文件加载,又能一定程度预防其他文件格式的输出。还比如 Gmail 早起使用 AJAX 的方式获取 JSON ,听过在输出 JSON 之前加入 while(1) ;这样的代码来防止 JS 远程调用 56 | 57 | ## CORS是什么? 58 | 59 | CORS即是跨域资源共享(全称为Cross-origin resource sharing)。它的实现需要后端配合,可以针对域名,端口和请求方式等作出限制。这样保证了跨域请求的安全性。阮一峰老师的[跨域资源共享 CORS 详解](http://www.ruanyifeng.com/blog/2016/04/cors.html)详细地介绍了两类请求,简单请求(simple request)和非简单请求(not-so-simple request)。 60 | 61 | ### CORS的实现原理 62 | 63 | CORS的实现需要浏览器和服务器同时支持,IE浏览器不能低于IE10。所以对于老版本的IE需要jsonp接口的兼容。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样,主要是服务器配置的附加头文件。 64 | 65 | 下面是非简单请求CORS在express上的具体实现方式: 66 | 67 | ```javascript 68 | app.all('*', function(req, res, next) { 69 | res.header("Access-Control-Allow-Origin", "http://localhost:3333"); 70 | res.header("Access-Control-Allow-Headers", "X-Requested-With"); 71 | res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); 72 | res.header("X-Powered-By",' 3.2.1') 73 | res.header("Content-Type", "application/json;charset=utf-8"); 74 | next(); 75 | }); 76 | ``` 77 | 78 | - Access-Control-Allow-Origin 必需,是对域名的限制 79 | - Access-Control-Allow-Methods 必需,是支持跨域请求的方法 80 | - Access-Control-Allow-Credentials 是否允许发送coookie 81 | - Access-Control-Allow-Headers 服务器支持的所有头信息字段 82 | - Access-Control-Max-Age 预检的有效时间 83 | 84 | ### CORS比jsonp的优点在哪里 85 | 86 | JSONP只支持GET请求,CORS支持所有类型的HTTP请求。相比之下,CORS的兼容性稍逊一筹,但是它在安全性上更有保障,如果是新版接口尽可能使用CORS方式跨域。 87 | 88 | -------------------------------------------------------------------------------- /blog/iframe-height.md: -------------------------------------------------------------------------------- 1 | # 【技术研究】如何动态获取跨域iframe高度 2 | 3 | 撰稿人:项伟平 4 | 5 | ## 引言 6 | 7 | iframe是一个“好东西”,但是又会带给你很多头疼的“问题”,特别是在ios的兼容性问题。在ios当中,iframe里的页面不会随着外层的网页大小自适应弹性缩放。相比之下,PC浏览器浏览器和安卓的浏览器则是可以实现缩放,这导致了差异性。这时候第一时刻,想到的是兼容的写法。专门针对ios专门设置iframe的scrolling属性为“no”,其他浏览器为“yes”,如下方源码。但是如果iframe子页面中存在响应式部件tab,高度进行变化,则会引起重绘重排,导致页面突然跳到顶部。 8 | 9 | ```html 10 |
11 | ``` 12 | 13 | ```css 14 | html, body{ 15 | height: 100%; 16 | } 17 | 18 | #url-wrapper{ 19 | margin-top: 51px; 20 | height: 100%; 21 | } 22 | 23 | #url-wrapper iframe{ 24 | height: 100%; 25 | width: 100%; 26 | } 27 | 28 | #url-wrapper.ios{ 29 | overflow-y: auto; 30 | -webkit-overflow-scrolling:touch !important; 31 | height: 100%; 32 | } 33 | 34 | #url-wrapper.ios iframe{ 35 | height: 100%; 36 | min-width: 100%; 37 | width: 100px; 38 | *width: 100%; 39 | } 40 | ``` 41 | 42 | ```javascript 43 | function create_iframe(url){ 44 | 45 | var wrapper = jQuery('#url-wrapper'); 46 | 47 | if(navigator.userAgent.match(/(iPod|iPhone|iPad)/)){ 48 | wrapper.addClass('ios'); 49 | var scrolling = 'no'; 50 | }else{ 51 | var scrolling = 'yes'; 52 | } 53 | 54 | jQuery(' 102 | ``` 103 | 104 | 源码参考[brandonxiang/iframe-height](https://github.com/brandonxiang/iframe-height/tree/master/agent)。 105 | 106 | ## postMessage 107 | 108 | 有些人觉得上面的方法非常难理解,因为中间代理层的缘故,增加了请求量,影响了加载效率。 109 | 110 | 随着HTML5 API的发展,postMessage是不同的html页面之间进行数据通信的方法,大大简化了上述方法的步骤。 111 | 112 | 在b.html中添加一段代码,在它加载完成后,往父页面跨域发送自己的高和宽,并且可以限制你发送的父网站的ip地址,大大保证安全性。 113 | 114 | ```javascript 115 | //b.html 116 | document.addEventListener('DOMContentLoaded', function () { 117 | var tbody = document.body 118 | var width = tbody.clientWidth 119 | var height = tbody.clientHeight 120 | window.parent.postMessage({ height: height, width: width }, '*') 121 | }, false) 122 | ``` 123 | 124 | 还需要在a.html网站添加一个事件监听,获取iframe内的b.html发送的高与宽,从而设置父页面的iframe的高与宽。 125 | 126 | ```javascript 127 | //a.html 128 | var frame = document.getElementById('other') 129 | window.addEventListener('message', function(e){ 130 | frame.style.height = e.data.height+'px' 131 | frame.style.width = e.data.width+'px' 132 | }) 133 | ``` 134 | 135 | 源码参考[brandonxiang/iframe-height](https://github.com/brandonxiang/iframe-height/tree/master/postmessage)。 136 | 137 | ## 总结 138 | 139 | 相比之下,第二种方法会比较简单和有效。但是由于跨域限制,你不得不要求对方添加一段代码去“消除”跨域限制,也是出于安全性不得已的实现方法。 140 | 141 | 总的来说,iframe在移动端受非常多的限制,尽可能地慎用。 142 | 143 | 欢迎订阅我们的博客,请点击上方的watch按钮噢。 144 | 145 | ## 参考 146 | [跨域iframe高度自适应的多种方法](http://blog.csdn.net/aaronpan21/article/details/51245685) 147 | 148 | -------------------------------------------------------------------------------- /blog/vue-startup.md: -------------------------------------------------------------------------------- 1 | # 【技术分享】Vue的选型和Webpack的入门 2 | 3 | 撰稿人:项伟平 4 | 5 | ## Vue的选型 6 | 7 | ![Vue全家桶](https://raw.githubusercontent.com/PaicFE/keynote/master/img/architech.png) 8 | 9 | 现在面试前端者都会在自己简历上写上精通这三个框架,但是仔细一问就三不知。在纵观几个大型前端框架后,我想得出一结论,问什么选择Vue框架呢? 10 | 11 | 下面我们对这三个框架进行对比。 12 | 13 | ### Vue与Angular 14 | 15 | 一切要从Vue1.0讲起,回顾一下历史。Vue在项目初期命名为Angular Lite,说明了我们Vue1.0和Angular之间的关系,它的初始目标是一个精简版的Angular。它们的共同点在于它们都拥有**双向绑定**机制和指令。Angular(后面简称为ng)和Vue的异同点如下: 16 | 17 | - ng是一个完整的mvvm框架,vue主要是view层展示 18 | - ng双向绑定基于模版编译规则(“脏”检查), vue是采用es5的get和set机制 19 | - vue可以el对象进行实例化,组件化 20 | - ng框架重,整个设计模式具有依赖注入的思想,学习曲线比较陡峭 21 | - ng2断层式升级,但是ng2更吸引人 22 | 23 | 总而言之,Angular的“大而整”的结构让它在构建项目的过程当中得心应手,但是Vue的“小而美”组件化结构却是符合我轻量级应用项目的需求。因为现在很多的页面内容都集中在移动端。说到小而美的“组件化思想”,我们会提到Vue和React。 24 | 25 | ### Vue与React 26 | 27 | ![React VS Vue](https://raw.githubusercontent.com/PaicFE/keynote/master/img/switch_react_vue.jpg) 28 | 29 | 在听了尤雨溪的知乎live后,我更加明白vue2大量地借鉴了很多React的特性。React也算是“js大一统”思想的鼻祖,运用了css in html(jsx)和css in js的特点,实现组件化的高度复用。而尤大大则是另辟蹊径制作了[vue-loader](https://github.com/vuejs/vue-loader)和[vueify](https://github.com/vuejs/vueify),通过[webpack](https://github.com/webpack/webpack)和[browserify](http://browserify.org)打包项目工程内容。运用`