首页
Search
1
解决visual studio code (vscode)安装时没有选择安装路径问题
138 阅读
2
Linux 下 Bash 脚本 bad interpreter 报错的解决方法
131 阅读
3
Arch Linux 下解决 KDE Plasma Discover 的 Unable to load applications 错误
107 阅读
4
如何在 Clash for Windows 上配置服务
77 阅读
5
Uniapp如何引入自定义样式文件
75 阅读
clash
服务器
javascript
全部
游戏资讯
登录
Search
加速器之家
累计撰写
1,061
篇文章
累计收到
0
条评论
首页
栏目
clash
服务器
javascript
全部
游戏资讯
页面
搜索到
624
篇与
的结果
2024-10-21
基于webpack搭建前端工程的思考
前端工程化的概念和思想早就已讨论过,并且之前也用 requireJS 和 seaJS 实现过,同时,在 2015 年,ECMAscript 也发布了 js 的正式版 ES6。在 ES6(ES2015)中,实现了标准上的统一,从底层上实现了模块化的支持。不过由于浏览器发展的滞后性,尤其是 IE,ES6 中很多的属性依然是不支持的,因此也就出现了第三方工具babel,将 ES6 语法转换为浏览器统一支持的 ES5。在上一篇文章中,我们对 webpack 也有个简单的了解了,在 webpack 中,一切皆资源,CSS,JS,图片等都可以作为资源处理。将资源进行分类,模块化的管理,适配到不同的页面。 1. 资源管理 # 项目的工程化,最主要的就是对资源的管理,对整个项目进行思考后,如何拆分资源。对于业务上的组件,我们可以放到components的目录中,然后对外暴露接口。webpack 对 CommonJS,AMD 和 ES6 的模块化都有非常好的支持,不过我们最好还是安装 ES6 的标准来写代码。webpack 编译打包后,都会打包到一个文件中。同时,webpack 让我们更加专注逻辑代码的编写,而不用关心代码是如何被引用的。关于export和import具体如何使用,可以参考阮一峰的文章 Module 的语法 。 2. 本地开发环境 # 一个项目的目录结构可以是这样的:`-out # 编译后 `-src # 原文件 `---css `---img `---js `---components # 组件 `-entry.js `-package.json `-webpack.config.js # 配置文件 `-index.html 为了方便本地的开发和调试,我们使用webpack-dev-server搭建一个本地服务:npm install webpack-dev-server --save-dev 下载安装完成后,我这里对应的版本号是:{ "webpack": "^2.7.0", "webpack-dev-server": "^2.9.1" } 本来安装网上的教程配置 server 时,各种出错,后来就一点点注释,看看是哪里配置错了,结果只能把整个devServer的配置全部注释掉。启动服务:webpack-dev-server --open -hot 程序会自动打开浏览器http://localhost:8080。但是,这里有个问题,页面该怎么引入静态资源呢,其实静态资源的路径就是在 webpack.config.js 中的output中配置的:output : { publicPath: '/dist/', filename: '[name].js' } 那么 src 中的静态资源就会编译到 /dist/ 的路径中了,页面中直接引用就行了。不过,当我们查看项目目录时,却没有 dist 目录,其实在使用webpack-dev-server启动本地服务后,编译的 /dist/ 目录是只存在在内存中的,服务关闭后,dist 目录就不存在了。 3. webpack 的配置 # 在之前的文章中,我们把 webpack 的配置写到了webpack.config.js中。编译时,默认就是调用该文件中的配置。但是,从代码开发到部署到线上,要经历 3 个环境: 本地开发环境、测试环境与正式环境。不过我们这里,只配置本地开发环境和测试环境,正式环境与测试环境的代码已经一样了,只是正式环境是另一套发布流程了: webpack.base.config.js 基础配置 webpack.dev.config.js 本地开发环境 webpack.pro.config.js 测试环境 webpack.base.config.js :var webpack = require('webpack'), path = require('path'), ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: function () { return { index: './src/index.js', }; }, output: { publicPath: '/dist/', filename: '[name].js', }, // 新添加的module属性 module: { rules: [ { test: /\.js?$/, loader: 'babel-loader', exclude: /(node_modules|bower_components)/, options: { presets: ['es2015'], }, }, { test: /\.css$/, // loader: "style!css" use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader', }), }, { test: /\.(jpg|png)$/, loader: 'url?limit=8192', }, { test: /\.scss$/, // loader: "style!css!sass" use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!sass-loader', }), }, ], }, plugins: [], }; webpack.dev.config.js :const base = require('./webpack.base.config'), ExtractTextPlugin = require('extract-text-webpack-plugin'); const config = Object.assign({}, base, { output: { publicPath: '/dist/', filename: '[name].js', }, plugins: [new ExtractTextPlugin({ filename: '[name].css', disable: false, allChunks: true })], }); module.exports = config; webpack.pro.config.js :const base = require('./webpack.base.config'), ExtractTextPlugin = require('extract-text-webpack-plugin'); const config = Object.assign({}, base, { output: { publicPath: './build/', filename: '[name]-[chunkhash:8].js', }, plugins: [ new ExtractTextPlugin({ filename: '[name].css', disable: false, allChunks: true }), new webpack.BannerPlugin('created at ' + new Date().toLocaleString()), ], }); module.exports = config; webpack.base.config.js 是基础文件,不直接调用,我们在 package.json 中把命令简化一下:"scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot --config config/webpack.dev.config.js", "build": "cross-env NODE_ENV=production webpack --progress --hide-modules --config config/webpack.pro.config.js" } 运行npm run dev命令时,调用的是 webpack.dev.config.js,进行本地开发;运行npm run build,调用 webpack.pro.config.js,进行预发布编译。 4. 总结 # 因为项目的难易程度,部署代码、测试发布的流程都不一样,在 webpack 的开发过程中,也依然需要遵循公司的标准进行自动化的整合。
2024年10月21日
5 阅读
0 评论
0 点赞
2024-10-21
移动端里的逐帧动画
这几天在做一个感恩节的html5页面,得到了一个非常大的教训。页面地址: https://news.qq.com/FERD/ganen/main.htm页面里有比较多2,3帧的动画,我最初的设想是:针对2帧的动画,那么就用2张图交互的进行显示;针对3帧的动画,那么就3张图片轮流显示。在2帧动画里,一半时间显示,一半时间隐藏:样式:@keyframes shake2{ 0%{ opacity: 1; } 50%{ opacity: 1; } 51%{ opacity: 0; } 100%{ opacity: 0; } } .img1{ -webkit-animation: shake2 600ms linear infinite; animation: shake2 600ms linear infinite; } .img2{ -webkit-animation: shake2 600ms -300ms linear infinite; animation: shake2 600ms -300ms linear infinite; } 结构: 这种实现,在PC的模拟器上没有问题,移动端目前也没有问题。但是,如果当前页面中的图片非常多时,2帧动画就会出现问题。我们发现上面中的img1和img2会几乎同时的显示和隐藏,有一种闪屏的效果,如果图片较大,能亮下我的狗眼。在android手机里,动画更是简直没法看。刚开始是怀疑loading效果造成的,因为页面在loading完成之前,整个页面是隐藏的,会不会是animation在对隐藏的节点上出现问题呢。但是我也发现另一个现象,就是有的动画效果是在一张图片上完成的,比如扇子绕着扇子的根节点扇动,这里只需要为扇子添加一个transform:rotate的animation即可,这种动画就完全没有问题。后来在两张图片之前的思路上一直修修补补,但是完全没有左右。估计是图片的loading加载,导致animation的时间没有起作用,后来请教了一下同事,就把所有的2帧和3帧效果都用animation中的steps来实现。网上也有很多用animation-steps实现逐帧动画,在一张图片里,保存这种事物的不同形态,比如小人走路的不同状态,当切换这几种走路的状态时,小人就走起来了。如果没有使用steps,那么animation中的状态会以指定的动画慢慢变化;但steps是跳跃式动画,当前状态时间完成后会直接跳跃到下一个状态,没有过渡效果。语法:steps(number[, end | start]) 参数说明: number参数指定了时间函数中的间隔数量(必须是正整数) 第二个参数是可选的,可设值:start和end,表示在每个间隔的起点或是终点发生阶跃变化,如果忽略,默认是end。注意:第二个参数还有两个内置值,step-start等同于steps(1,start),动画分成1步,动画执行时以左侧端点为开始;step-end等同于steps(1,end):动画分成1步,动画执行时以结尾端点为开始。因此上面的2帧动画可以用steps实现,以下是用sass语法实现的逐帧动画,方便调用:@mixin keyframes($animationName, $width){ @-webkit-keyframes #{$animationName}{ 100%{ -webkit-transform: translate3d(-#{$width}, 0, 0); transform: translate3d(-#{$width}, 0, 0); } } @keyframes #{$animationName}{ 100%{ -webkit-transform: translate3d(-#{$width}, 0, 0); transform: translate3d(-#{$width}, 0, 0); } } } @mixin donghua($alltime: 0.9, $step: 2, $width:0){ $animation-name: unique-id(); // 生成唯一的animation name -webkit-animation: #{$animation-name} #{$alltime*1000}ms steps(#{$step}) infinite 0s; animation: #{$animation-name} #{$alltime*1000}ms steps(#{$step}) infinite 0s; @include keyframes(#{$animation-name}, $width); } 这时,动画在iOS和android都能正常展示了。欢迎访问: https://news.qq.com/FERD/ganen/main.htm 。参考: https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation-timing-function
2024年10月21日
6 阅读
0 评论
0 点赞
2024-10-21
innerHTML对IScroll组件的影响
我们在移动端的页面中有时候会使用到IScroll的滚动组件,要么是应用到页面的整个区域,要么是其中的某个div。当我们已经对这块区域进行初始化后,再向页面中添加元素时会出现什么情况呢? 1. 向滚动区域中添加元素 # 一种情况是向滚动区域中添加元素,这个元素影响到了滚动内容的高度,比如这样的代码,.main是滚动区域的外壳:var myscroll = new IScroll('.main', { mouseWheel: true, scrollbars: true }); document.querySelector('.main .con').innerHTML += 'author: wenzi'; 在向页面中添加一个div元素后,如果不做任何改动,滚动条拉到底部是看不到这个新div元素的。只有使用refresh()方法,刷新滚动区域后,滚动条才重新计算:myscroll.refresh(); 2. 向滚动区域的父级元素中添加元素 # 还有一种情况就是向滚动区域的父级元素中添加元素,比如直接追加到元素body中:document.querySelector('.main .con').innerHTML += 'author: wenzi'; 当我们以innerHTML方式向body中追加元素后,出现了一个严重的问题,IScroll滚动区域直接卡死,无法滚动了。即使使用refresh()方法也不能奏效。那么是什么原因造成的呢?问题就出在innerHTML上,使用innerHTML为该元素添加html代码时,实际上是重写了该元素里所有的html代码,之前的代码全部被覆盖掉,才导致绑定在内部的IScroll事件失效,无法进行滚动了。在第一部分中,因为修改的是在IScroll滚动区域内部的内容,不会影响到IScroll的执行,所以添加的内容只是影响了滚动区域的高度,但滚动功能还是能正常使用的。我们可以再做一个实验: 使用innerHTML向.main元素的兄弟元素里添加或者修改元素,IScroll是完全没有影响的。 3. 解决方案 # 那使用什么方法向某个元素(比如body)中追加元素呢,答案是appendChild了,我们可以先用createElement创建一个div元素,然后把内部所有的内容都填充到这个div的内容,然后再在该元素上appendChild这个div元素:var div = document.createElement('div'); div.className = 'dialog'; div.innerHTML = 'author: wenzi'; document.querySelector('body').appendChild(div); 这种方式既不会对IScroll造成影响,也不用对IScroll的代码进行改动。方便作为第三方向某个成熟的系统中添加代码,不会对原系统产生影响。 4. 总结 # 关于innerHTML和appendChild,这里稍微总结下: - innerHTML appendChild 功能 重写该元素内所有的html 向该元素追加一个子元素 性能 高 低 事件 需添加到页面上才能绑定事件 创建后即可绑定事件 耦合度 高 低 关于使用哪种方式添加元素还得看这个项目的复杂程度。如果仅仅要实现一个简单的需求的话,用innerHTML性能还是好些。如果需要大规模重写html的话,可以使用模板引擎来完成。
2024年10月21日
5 阅读
0 评论
0 点赞
2024-10-21
再见2017,你好2018
类似的标题,不一样的心情。每年在写总结的时候,心里都是挺沉重的,原来才发现,这一年又白干了。活儿没少干,不过就是没挣到钱。“钱都去哪儿了”2017年里,确实发生了很多的事情,感觉比之前更焦虑了一些。简单的梳理下2018年里发生的事儿吧:5月初时,我们部门去内蒙草原见识了一番草原的风景。那天在去的路上,还飘着雪花,着实是一种别样的味道,到达草原时已经是晚上12点了,吃了羊肉大餐后,就去放烟花、篝火,然后去看星星。说实话,草原的5月份还是很冷的,晚上睡觉还要开电暖气和电热毯的。月底时,去了天津一趟,去那里办了点事情,很是匆忙,也没有去自己的逛逛。8月,忽然接到了家里的电话,爷爷不幸去世了。真是非常的突然,5月底回家时,还去奶奶家歇了会儿,爷爷的身体虽说不太好,但也没什么毛病,一顿饭也还能吃下2、3个馒头。不过爷爷就是一个闲不住的人,腿脚不灵便了还要地里转转,然后就再也没回来。真是那句话:“明天和意外,你永远不知道哪个先来”,岁月不饶人,在我们还没来得及尽孝心,他们就走了。父母在,不远游。载我们还有机会的时候,多尽一份孝心。9月时,部门有一次去深圳进行学术交流的机会,去聆听其他前端团队的技术经验,也见到了毕业好几年的大学同学。在听课的过程中,线上项目出了一些问题,课程没仔细听,净修改bug了。京东的双11从11月1号就开始了,除了买一些日常用品,还买了4本书:《你不知道的javascript(上)》,《俞敏洪》、《中国近代史》和《沈从文》。在之前一直说要去798转转,只是没有合适的机会,这次终于是陪着朋友去了一趟,说实话,真没什么看的,艺术氛围?我等俗人是感受不到。11月18时,大兴发生了一场大火,于是,浩浩荡荡的清理活动就开始了,所有的物流网点全部彻查,该关的都关了,本来在19大时,进京的物流就很慢了,这次的大火差点把北京的快递整瘫痪了。大兴也开始清理所谓的低端人口,而且,还不止是大兴,海淀、丰台等待那个区域都在清理,中介、房东也趁着这个机会把租金涨了一波,你爱租不组,现在市场上有的是人在找房子。后来北京又开始了大规模的拆广告牌活动,我们公司的牌子在拆了第2天后,海淀临时叫停了拆广告牌,什么时候恢复还得等待通知。当然,还有全国浩浩荡荡的煤改气、煤改电,为了所谓的环保政绩,简直是丧心病狂了。不管你怎么过冬、反正不能烧煤,煤改气工程也没完工、收你的烧煤炉子、贩煤的全部抓起来,河北、河南、山西等地全面车辆限号。12月份时,我们之前的中介被新中介昊园恒业收购了,这个中介比之前的中介还要黑,要么强制交满1年的房租,要么使用他的“元宝E家”;而这两种方案,选择哪个都不好,毕竟我们不会住到到期的,中间就要重新找房子。拖了一段时间到该交下次房租的时候,他们给出一个新的方案: 之前住的时间不算了,重新签1年,而且你可以压2付3的方式交房租,如果中间要转租的话,交半个月的转租费,同时新租户续租也签1年的合同。而且,之前交的卫生费泡汤了,这个新中介根本就没有保洁了。展望2018年,发现生活依然很艰难。生活虽然很艰难,但我们依然砥砺前行: 争取在2018年能升上一个职级; 努力挣钱,要努力; 前端的技术上能更上一层楼; 愿每个善良的人,都能被生活善待!
2024年10月21日
5 阅读
0 评论
0 点赞
2024-10-21
Vue与Git结合进行环境区分与自动化部署
因为上半年的事情确实多了点,很久没有写文章了。回到公司后没多久,病了一场,住院住了好多天。今天也是把之前项目里的经验拿出来给大家做一个参考,希望能有所借鉴。做的每个项目都要对自己多少有个突破,比如我之前做的“腾讯新闻-捐时长,做公益”的项目里,就第一次直接用 Vue 上手开始做,刚开始时也有点不熟悉,也是边做边查,最终也按照正常工期上线了。这里要讲的就是 Vue 里做开发,如何进行环境的区分。 1. 进行环境的区分 # 环境的区分主要是分为:开发环境、测试环境、预发布环境与正式环境。每个环境里的配置都是不一样的,比如首先是接口地址不一样,测试环境用的是测试接口,预发布环境和正式环境用的是正式接口;同时,每个环境从本地发布到发布系统时的流程也有些区别,比如往测试环境推送时,不用 md5 命名,推送文件即可,不用推送到 CDN 等等。这个项目我是用vue-cli生成脚手架的基础上进行开发的,在这个脚手架里,有一个全局变量process.env.NODE_ENV,代码里可以通过这个变量知道当前处于什么环境。process.env.NODE_ENV 规定了 3 个值: testing, development, production。在代码里就可以这么使用,根据不同的环境使用不同的接口:const apiOrigin = { production: window.location.protocol + '//api.xxx.com/', development: window.location.protocol + '//api.xxx.com/', testing: window.location.protocol + '//test.xxx.com/', location: '/', }; 那么怎么调用编译呢,一个最简单的方法是使用npm scripts,在 package.json 文件中配置好:{ "scripts": { "build:testing": "webpack config/webpack.testing.conf.js", "build:development": "webpack config/webpack.development.conf.js", "build": "webpack config/webpack.production.conf.js" } } 然后根据不同的操作,npm run不同的命令即可。可是你也发现了,有几个文件是没有的,需要自己配置。 2. 根据 Git 分支分别进行构建 # 我们早期没有自动的 CI/CD 构建发布流程,这里仅是根据 Git 的钩子来触发构建而已,然后顺带把源码放到 Git 服务上。我们的代码都是托管在 git 上的,那么可以根据不同的分支来表示不同的环境,通过下面的代码,能获取当前所在的分支:const { execSync } = require('child_process'); const fs = require('fs'); const async = require('async'); const str1 = execSync('git status', { encoding: 'utf8' }); const re = str1.match(/^On branch (.+)\s/); const branch = re[1]; console.log('当前分支为: ' + branch); 拿到分支后,再获取对应的配置即可。同时,为了更加简化我们的操作指令,可以利用 git 的钩子机制,将 npm script 操作写到钩子中,因为我们的内部系统,git 服务器我们是无法自定义的,因此只能在本地进行压缩和上传到访问服务器。这里我们使用的是pre-push钩子,在发出git push命令后,根据对应的分支进行相应的操作,操作完成后,再将源码推送到 git 服务器即可。访问服务器放置的是用户访问的 html 文件和静态资源,而 git 上只存放我们的源码。我们后续再根据 git 的原理进行分支管理和版本管理即可。【2022 年 2 月份补充】现在自动构建和发布流程已经很完善了,不用再单独通过上面的代码触发构建了,按照规范配置自动构建发布流程即可。
2024年10月21日
5 阅读
0 评论
0 点赞
1
...
27
28
29
...
125