2020年9月30日 By mikel 分类: JavaScript, 项目管理

来源: Webpack打包 – 简书

image.png

一. 概述

什么是webpack

模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

为什么使用webpack

现在是网络时代,在我们的生活中网络成为了必不可少的,我们在网络上可以看到很多漂亮的功能丰富的页面,这些页面都是由复杂的JavaScript代码和各种依赖包组合形成的,那么这些都是怎么*组合在一起的呢,组合在一起需要花费多少精力呢,经过漫长发展时间现前端涌现出了很多实践方法来处理复杂的工作流程,让开发变得更加简便。

  • 模块化 可以使复杂的程序细化成为各个小的文件
  • 预处理器 可以对Scss,less等CSS预先进行处理
    ……

二. weback使用流程

1、创建项目

这里用的是命令创建项目,当然你也可以去鼠标右键创建项目

mkdir webpackDemo // 创建项目
cd webpackDemo // 进入项目
mkdir app // 在项目中创建app文件
mkdir common // 在项目中创建common文件
cd app // 进入app文件夹
touch app.js // 创建app.js文件
touch main.js // 创建main.js文件
cd .. //返回到webpackDemo项目根目录
cd common // 进入common文件
touch index.html // 创建index.html文件
  • mkdir:创建文件夹
  • cd ..:返回所在目录的上级目录
  • touch:创建文件
  • app:用来存放原始数据和我们将写的JavaScript模块
  • common:用来存放之后供浏览器读取的文件(包括使用webpack打包生成的js文件以及一个index.html文件)

目录结构

image.png

基础代码
index.html是主入口,需要设置根目录并且将打包后的文件导入

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="root"></div>
    <script type="text/javascript" src="index.js"></script>
</body>
</html>

app.js是我们写的模块,并依据CommonJS规范导出这个模块,这里我们以输出welcome to use webpack为例

module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = "welcome to use webpack!";
  return greet;
}

main.js其实是一个组件,它的目的是将我们写的一些代码模块返回并插入到页面中

const greeter = require('./app.js');
document.querySelector("#root").appendChild(greeter());
2. 安装

因为安装webpack要用npm,所以安装之前我们首先要安装node
第一步 要在项目根目录用npm init初始化,生成package.json文件

npm init

初始化过程中会有好多提示,如果非正式项目下可以直接回车调过,括号里的都是默认的,正式项目下可以根据情况填写每一步

name: (webpackDemo) // 项目名称
version: (1.0.0) // 版本号
description: // 项目的描述
entry point: (index.js) // 入口文件
test command: // 测试命令
git repository: // git仓库
keywords: // 关键字
author: // 作者创始人
 license: (ISC) //许可:(ISC)
About to write to C:\Users\Administrator\Desktop\webpackDemo\package.json:

{
  "name": "webpackdemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Is this ok? (yes) // 这里直接输入yes就可以了

第二步 安装webpack

npm install webpack -g // 全局安装
npm install webpack --save-dev // 项目内安装

如果不想安装最新的版本那么得在webpack后面加一个@然后在填入你要安装的版本号,当然安装最新版本时可以加@版本号也可以不加@版本号

npm install webpack -g
npm install webpack --save-dev

webpack有两个版本分别是webpack2和webpack4,这两个版本安装配置有差异。
先来看看webpack2
本次安装的是3.5.6的版本,运行的是以下命令

npm install webpack@3.5 --save-dev

接下来看下我们创建的package.json文件,里面的都是我们刚配置的

{
  "name": "webpackdemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^3.5.6"
  }
}

接下来看webpack4
webpack4版需要去额外安装webpack-cli

npm install webpack@4 --save-dev
npm install webpack@4 webpack-cli --save-dev

接下来看下配置文件

{
  "name": "webpackdemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.29.5",
    "webpack-cli": "^3.2.3",
  }
}

注意:package.json文件中不能有注释,在运行的时候请将注释删除

第三步 使用Webpack打包
webpack可以在终端中使用,基本的使用方法如下:

// webpack2的命令
node_modules/.bin/webpack app/main.js common/index.js 
// webpack4的命令
node_modules/.bin/webpack app/main.js -o common/index.js
  • app/main.js:是入口文件的路径,本文中就是上述main.js的路径
  • common/index.js:是打包文件的存放路径

注意:是非全局安装情况
webpack2打包命令执行后

image.png

webpack4打包命令执行后
如果你的webpack是最新的版本webpack4那么就不能用webpack2的打包命令,如果用webpack2的命令会报错打包失败,如下:

image.png
  • 黄色部分:webpack4是需要指定打包为开发环境还是生产环境的,目前我们没有指定是什么环境所以就会有这个警告
  • 红色部分:因为webpack4的打包命令和webpack2的打包命令不同,所以用webpack2的打包命令时就会提示打包的路径找不到

如果你用webpack4的打包命令,打包如下

image.png

黄色警告下面会解决这个问题
从打包的结果可以看出webpack同时编译了main.js 和app,js,并且打包成功,现在打开编辑器,可以看到如下结果

image.png

webpack2的打包文件

image.png

webpack4的打包文件

image.png

接下来我们在看下页面

image.png

是不是很激动我们已经将welcome to use webpack!在页面打包生成,但是这种方式需要在终端运行复杂的命令而且容易出错很不方便,如果能更方便点就好了,那么接下来我们在看下它的升级版打包。

第四步 通过配置文件webpack.config.js来使用webpack
Webpack拥有很多其它的比较高级的功能,这些功能其实都可以通过命令行模式实现,但是在终端中进行复杂的操作,这样不太方便且容易出错的,更好的办法是定义一个配置文件,这个配置文件其实也是一个简单的JavaScript模块,我们可以把所有的与打包相关的信息放在里面。
在当前项目webpackDemo文件夹下新创建一个文件webpack.config.js,写入简单的配置代码,目前的配置主要涉及到的内容是入口文件路径和打包后文件的存放路径

// webpack2的配置
module.exports = {
    entry:  __dirname + "/app/main.js", // 之前提到的唯一入口文件
    output: {
        path: __dirname + "/common", // 打包后的文件存放的地方
        filename: "index.js" // 打包后输出文件的文件名
    }
}
// webpack4的配置
module.exports = {
    // webpack4需要添加这个配置,development为开发环境,production为生产环境
    mode: "development",
    entry:  __dirname + "/app/main.js", // 之前提到的唯一入口文件
    output: {
        path: __dirname + "/common", // 打包后的文件存放的地方
        filename: "index.js" // 打包后输出文件的文件名
    }
}

注:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。
有了这个配置之后,再打包文件,只需在终端里运行webpack(全局情况下)或node_modules/.bin/webpack(非全局安装需使用)命令就可以了,不需要再命令行打入主入口和打包文件的路径了,这条命令会自动引用webpack.config.js文件中的配置选项。
示例如下:

image.png
image.png

是不是很简单这样我们就不用再终端输入那么多烦人的配置文件的路径了,那么如果node_modules/.bin/webpack这条命令都不用在终端输入,是不是更简单呢?,接下来接着往下看。
更加方便的打包操作
根据上面的方式来看我们只要配置了webpack.config.js就可以将打包的路径命令省去,那么我们想是否可以以这种方式将node_modules/.bin/webpack命令省去呢? 答案是可以,只不过不是在这个文件内配置,也不用去新建文件配置。
npm可以引导任务执行,对npm进行配置后可以在命令行中使用简单的npm start命令来替代上面略微繁琐的命令。在package.json中对scripts对象进行相关设置即可,设置方法如下。

{
  "name": "webpackdemo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack" // 修改的是这里,JSON文件不支持注释,引用时请清除
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^3.5.6"
  }
}

注:package.json中的script会安装一定顺序寻找命令对应位置,本地的node_modules/.bin路径就在这个寻找清单中,所以无论是全局还是局部安装的Webpack,你都不需要写前面那指明详细的路径了。
npm的start命令是一个特殊的脚本名称,其特殊性表现在,在命令行中使用npm start就可以执行其对于的命令,如果对应的此脚本名称不是start,想要在命令行中运行时,需要这样用npm run {script name}npm run build,我们在命令行中输入npm start,看看输出结果是什么,输出结果如下:

image.png
image.png

现在只需要使用npm start就可以打包文件了,有没有觉得webpack也不过如此嘛,不过不要太小瞧webpack,要充分发挥其强大的功能我们还需要配置很多。

其他配置可以查看以下文章

(一)Source Maps
(二)构建本地服务器
(三)Loaders
(四)Babel
(五)模块化处理
(六)插件(Plugins)
(七)产品阶段的构建

结尾

文章到这里就要和大家告一段落了,通过这篇文章大家可以初步的了解webpack的打包流程,以及webpack的一些工具和插件,并且可以简单的去打包一些demo。
其实webpack还有很多需要我们去学习和深入了解去探索的东西。
最后祝愿大家能够早日将webpack掌握并熟练的去运用,也祝大家事业有成,最重要的一点是:“一定要注意身体吆!”

作者:秉持本心
链接:https://www.jianshu.com/p/1192cfd4a012
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Webpack打包 – 简书已关闭评论
2020年9月30日 By mikel 分类: 项目管理

来源: git 一个可以提高开发效率的命令:cherry-pick – 良许Linux – 博客园

各位码农朋友们一定有碰到过这样的情况:在develop分支上辛辛苦苦撸了一通代码后开发出功能模块A,B,C,这时老板过来说,年青人,我们现在先上线功能模块A,B。你一定心里一万只草泥马奔腾而过,但为了混口饭吃必须得按老板的意思办事啊。

怎么办?一个办法就是,重新建一个分支,然后再把功能模块C回退,留下功能模块A,B。这种做法不是不行,但是有更好的办法,那就是git所提供的cherry-pick功能。

cherry-pick类似于一个定制化的merge,它可以把其它分支上的commit一个个摘下来,合并到当前分支。

废话不多说,直接上实例。

比如我现在有个文件a.c,我在develop分支完成了三个功能模块:feature A,feature B,feature C。如下图:

现在,坑爹的老板只要feature A,feature B,我们现在用cherry-pick命令直接把feature A,feature B的提交合并到master分支里,如下操作:

可以看到,功能模块feature A,feature B已经被合并到master分支里。请注意,合并到master分支里的提交哈希值发生了改变,与原来的不同。

可以看出,cherry-pick命令使用方法很简单,即:

git cherry-pick commitID

刚刚是一个个提交cherry-pick到master分支,但如果有100个commit要合并到master分支呢?总不能这样一个个操作吧?git一样帮你想到了,它提供了一个区间操作方法。具体来讲是这样的:

git cherry-pick commit1..commit100

但是要注意,这是一个左开右闭的操作,也就是说,commit1不会被合并到master分支,而commit100则会。这样的话上面的需求可以如下操作来实现:

注意:上面讲到cherry-pick命令每拣选一个commit就会提交一次生成一个新的commit id。 如果我们想让每个commit 拣选后暂缓提交,等到所有commit都拣选完成后,自己手动commit,应该怎么办呢?答案是用-n 选项:

怎样,是不是很简单?学会了cherry-pick命令妈妈再也不用担心老板时不时的头脑发热了。快扫描下方二维码和良许一起学习更多git神操作!

更多精彩内容,请关注公众号良许Linux,公众内回复1024可免费获得5T技术资料,包括:Linux,C/C++,Python,树莓派,嵌入式,Java,人工智能,等等。公众号内回复进群,邀请您进高手如云技术交流群。

git 一个可以提高开发效率的命令:cherry-pick – 良许Linux – 博客园已关闭评论
2020年9月30日 By mikel 分类: 互联网, 网络营销

来源: 最简单的精准引流方法-音频矩阵引流 – 卢松松博客

通过声音来引流精准客户,是的,没错。小白能做吗?能。怎么做?

我来说说,说完你就明白,不用花钱学习也能自己引流。

音频主要平台就是喜马拉雅,企鹅,蜻蜓这几个流量还不错能确实引流来人。其他的还有,考拉,荔枝,网易云,懒人听书。似乎,数据都有问题。

然后说,怎么做。

先看看哪些产品适合。

先看你是做什么产品的,并不是所有的产品都适合音频。先说适合的:情感,美容,瘦身,教育类,养生类,孩子故事类,知识付费类,都可以。就是有的说,有很多知识点,不需要看到实物,描述就可以听懂的。

不适合的:机械设备,pos机,只可眼见不可描述的东西也不适合,医疗,黑灰产也不适合。

第一步:定位。

比如:我要做一个某宝无货源项目,如果我是个小白,没事。音频成全你。无货源当然就要定位到无货源项目,那就是讲关于这方面的知识,操作步骤等。

如果你是瘦身的,那就是瘦身类的的知识对吧。这很简单。

定位完了。下一步就是对标。

第二步:对标。

当然啊,你如果够流弊,那你自己讲最好了,脱口而出,各种知识存在脑子里,这是最棒的。难不住你,自带知识,自带流量。如果你是小白,那你就要学习,怎么做?每天看 几篇文章,看几个视频,看完后,拿个小本子记下来要点,学到了什么?

然后总结一下,拿出手机,对着手机录一段5分钟内的音频。

那怎么找内容?网上多了去了、推荐几个地方:公证号,百度,头条,知乎,悟空问答,等等。这样的内容网上一搜一大把。

最简单的精准引流方法 音频矩阵引流 流量 经验心得 第1张

别说你这都不会找啊。

最简单的精准引流方法 音频矩阵引流 流量 经验心得 第2张

找评论多的,阅读多的播放多的。

文章既然能这么受欢迎,那我们加工成音频应该也不错。

打开手机录音这个我不说了,录完后,记住:手机登录一个qq,电脑登录同一个qq,把音频文件从手机的qq传到电脑上的“我的电脑”。因为这样,不会被压缩。压缩了上传到喜马拉雅可能会通不过。

传到电脑后,打开喜马拉雅,创作中心。

然后:创建专辑。

这里重点说一下专辑的名称,一定要带有客户想搜的关键词才可以。

最简单的精准引流方法 音频矩阵引流 流量 经验心得 第3张

这里的关键词与百度霸屏的关键词不同。霸屏里需要突出产品名称。但是这里不能这样。因为在喜马拉雅的用户会去搜一些行业大词。比如:怎么减肥?减肥吃什么比较好。

所以,我们的专辑名称可以是:减肥瘦身方法 ,减肥的秘密之类的。而不能直接突出产品词。

创建完后,就是上传了。

最简单的精准引流方法 音频矩阵引流 流量 经验心得 第4张

具体不说了,都是超级简单。

传完,等半小时后,数据就会出来,有多少人听了。然后,根据收听效果做进一步的优化。

这就是整个简单的过程,所以,音频引流是最简单的引流方式。谁都可以做,宝妈,上班族,每天拿出5分钟就可以录一条。

好了,说到这吧。这是个很简单的,没什么技术含量的完全靠体力去执行就能出单的引流方法。

去执行吧,说了不做,不如不说。

公众号:老船长李阳

最简单的精准引流方法-音频矩阵引流 – 卢松松博客已关闭评论
2020年9月29日 By mikel 分类: 架构设计, 项目管理

来源: 一篇文章搞定 Nginx 反向代理与负载均衡 – 哈喽沃德先生 – 博客园

要想弄明白反向代理,首先要知道啥是正向代理,要搞懂正向代理只需要知道啥是代理即可。代理其实就是一个中介,在不同事物或同一事物内部起到居间联系作用的环节。比如买票黄牛,房屋中介等等。

互联网中代理更多指的是代理服务器,代理服务器位于客户端和服务器之间,它充当两者之间的中介。这种代理在生活中是比较常见的,比如我们常说的搭个梯子上网,用到的就是代理技术。

 

2|0正向代理

 

正向代理(forward proxy):是一个位于客户端和目标服务器之间的服务器(代理服务器),为了从目标服务器取得内容,客户端向代理服务器发送一个请求并指定目标,然后代理服务器向目标服务器转交请求并将获得的内容返回给客户端。

比如国内访问谷歌,直接访问是不行的,我们可以通过一个能够访问谷歌的正向代理服务器,请求发到代理服务器,由代理去谷歌获取数据并返回,这样就变相的实现了访问谷歌的需求。

一句话总结:正向代理,就是代理服务器代理了客户端,去和目标服务器进行交互。

 

 

正向代理的用途

  • 突破 IP 访问限制
  • 通过缓存加速访问资源
  • 隐藏客户端真实 IP
  • 客户端访问授权

 

3|0反向代理

 

反向代理(Reverse Proxy):与正向代理正好相反,反向代理中的代理服务器,代理的是服务器那端。代理服务器接收客户端请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给客户端,此时代理服务器对外表现为一个反向代理服务器的角色。

反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。

一句话总结:反向代理,就是代理服务器代理了目标服务器,去和客户端进行交互。

 

 

反向代理的用途

  • 隐藏服务器真实 IP
  • 负载均衡
  • 通过缓存加速访问资源
  • 提供安全保障

 

4|0负载均衡

 

实际生产环境中,反向代理服务器代理的目标服务器可能不止一个。比如开发好的某个应用部署在一台 Tomcat 服务器上,而 Tomcat 的并发上限不优化情况下,默认只有两百左右,这时候为了解决高并发的问题,就只能选择更替服务器或者搭建多台服务器通过反向代理与负载均衡的技术解决并发问题。

 

 

负载均衡(Load Balance)是由多台服务器以对称的方式组成一个服务器集群,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助。经过某种负载分管技术,将外部发送来的中央请求均匀分配到对称结构中的某一台服务器上。

 

5|0总结

 

正向代理,就是代理服务器代理了客户端,去和目标服务器进行交互。现实生活中的场景:黄牛买票。

反向代理,就是代理服务器代理了目标服务器,去和客户端进行交互。现实生活中的场景:房屋中介。

 

6|0Nginx 反向代理与负载均衡

 

 

前面我们提到搭建多台服务器并通过反向代理与负载均衡的技术可以解决并发问题,那么负载均衡的实现从哪来?为了避免重复造轮子,我们选择现成已有的成熟工具帮助我们完成这项工作。Nginx 就是一个不错的选择。

Nginx 是由 Igor Sysoev(伊戈尔 · 赛索耶夫)为俄罗斯访问量第二的 https://www.rambler.ru/ 站点开发的。Nginx 是一个高性能的 HTTP 和反向代理服务器,可以扛得住 5W 左右的并发。Ngnix 一方面可以做反向代理服务器,另外一方面还可以做静态资源服务器。本文主要学习如何使用 Nginx 实现反向代理与负载均衡。

官网:http://nginx.org/

 

6|1环境

 

  • 三台 CentOS 7.8.2003 机器
  • 192.168.10.101 安装 Nginx 1.18.0
  • 192.168.10.102 和 192.168.10.103 安装 Tomcat 9.0.38

 

6|2安装 Nginx

 

下载资源

 

下载 Nginx 并解压。

# 下载 nginx 压缩包 wget -P /usr/local/src http://nginx.org/download/nginx-1.18.0.tar.gz # 解压 tar -zxvf /usr/local/src/nginx-1.18.0.tar.gz -C /usr/local/src

 

安装依赖

 

Nginx 是基于 C 语言开发的,HTTP 模块使用了 pcre 来解析正则表达式,且可以使用 zlib 对 HTTP 包的内容进行 gzip 压缩,Nginx 不仅支持 HTTP 协议,还支持 HTTPS,HTTPS 需要 openssl 提供支持,所以安装 Nginx 之前必须先安装它所依赖的环境。

yum install -y gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl-devel

 

安装 Nginx

 

编译并安装。

# 切换至 nginx 的解压目录 cd /usr/local/src/nginx-1.18.0 # 创建 nginx 的安装目录 mkdir -p /usr/local/nginx # 指定 nginx 的安装路径 ./configure –prefix=/usr/local/nginx/ # 编译并安装 make && make install

 

常用命令

 

# 切换目录 cd /usr/local/nginx # 启动 sbin/nginx # 重启 sbin/nginx -s reload # 停止 sbin/nginx -s quit

 

访问

 

启动 Nginx 以后,浏览器访问:http://192.168.10.101:80/ 结果如下:

 

6|3安装 Tomcat

 

下载资源

 

下载 Tomcat 并解压。

# 下载 tomcat 压缩包 wget -P /usr/local/src https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.38/bin/apache-tomcat-9.0.38.tar.gz # 创建目录 mkdir -p /usr/local/tomcat # 解压 tar -zxvf /usr/local/src/apache-tomcat-9.0.38.tar.gz -C /usr/local/tomcat

 

修改页面

 

修改 Tomcat 自带 ROOT 项目中的 index.jsp 页面。

# 编辑 index.jsp vim /usr/local/tomcat/apache-tomcat-9.0.38/webapps/ROOT/index.jsp

在 body 标签中随便添加点内容用于区分不同的服务器。

<h1 style=“color:red”>192.169.10.102:8080</h1> <h1 style=“color:red”>192.169.10.103:8080</h1>

 

启动访问

 

/usr/local/tomcat/apache-tomcat-9.0.38/bin/startup.sh 启动 Tomcat。

启动 Tomcat 以后,浏览器访问:http://192.168.10.102:8080/ 和 http://192.168.10.103:8080/ 结果如下:

 

6|4配置 Nginx

 

vim /usr/local/nginx/conf/nginx.conf 编辑配置文件。

在 http 节点下,添加 upstream 节点。使用 upstream name{} 语法定义一组服务器。

然后在 server 节点的 80 端口下添加下图中的内容。默认情况下,Nginx 是按加权轮询的方式将请求分发到各个服务器,当权重 weight 不指定时,各服务器 weight 相同。关于 Nginx 启动用户的问题请根据自身实际环境进行配置。

 

6|5反向代理负载均衡

 

通过上面的流程,我们已经完成基于 Nginx 实现反向代理 Tomcat 服务器集群与负载均衡的需求。重启 Nginx 以后,此时再访问 Nginx 则会被路由到被代理的 Tomcat 服务器上,并且采用了轮询方式(默认)的负载均衡算法。客户端请求到 Nginx 的中央请求会每台一次的平均分配至 Tomcat 每个机器上。关于 Nginx 更多详细的配置及负载均衡算法我们后面再另开文章细说。

本文采用 知识共享「署名-非商业性使用-禁止演绎 4.0 国际」许可协议

大家可以通过 分类 查看更多关于 Nginx 的文章。

一篇文章搞定 Nginx 反向代理与负载均衡 – 哈喽沃德先生 – 博客园已关闭评论
2020年9月28日 By mikel 分类: C#

最近遇到某些音樂播放器,由其是SONY的車用音響,都出現了這個問題,就是它根本不照我們放置檔案的順序或是其他排序方式(時間)去撥放。而這支程式就是用來重建他的檔案順序用的。

At some Sony music players or car audios,  it read mp3 files order is not follow filename sort or otherwise sort on the USB drive. This program will regenerate file order to the right!

假如我有一個USB隨身碟資料夾,裡面的檔案清單就如下面這張圖:

在 Windows 檔案總管下,看起來就是上面這樣子的,因為檔案總管會預設以檔案名稱來排序,正常得情況我們在 Windows 的播放軟體也會依照這個規則來執行。

然而,目前我在SONY音樂播放器上遇到這個播放順序的問題,它是照下面這種順序去撥放的:

比較前後兩張清單後注意到了嗎?

第二章的清單順序根本不知道它是依循啥麼的啊??事實上這就是我在 SONY音樂播放器上遇到的問題。

經過不斷的檢查後發現,原來第二張的檔案順序是在 FAT 表上的出現順序啊!!!!!

這啥鬼?

原來 SONY 音樂播放器是直接照 FAT 表讀出的檔案順序來播放音樂的,無怪乎我怎麼改檔案名稱,或是檔案時間都沒有用。

要是按照這種方式播放的話,如果要整理檔案,就得把 MP3 檔全部 移出 USB 隨身碟後,再依順序一個一個拷貝(搬移)回 USB 隨身碟。

真是天殺的,如果 USB 隨身碟有滿滿 16 GB音樂檔,那不就搬到天花地老了。這個會死人啊,老兄。SONY,我真服了你們了,東西又不便宜,程式卻寫得這麼爛,真不像 SONY 的產品啊。

索性,自己寫一支程式,專門來做檔案順序『重建』就可以保證在 FAT 上是依照自己訂的順序來跑了。

有興趣的就自己下載看看:

下載檔案/原始碼

這是用 dotNetFramwork 4.5 製作的,所以要執行的話,電腦至少要能支援 dotNetFramwork 4.5 ,或是到這裡下載。記得選擇您使用的語系再安裝。

程式載點(Google drive)

原始碼載點(Github)

操作方式:

點選左上方『開啟資料夾』,然後選擇你要重建的資料夾,請注意,它只支援一層檔案內容,並不會處理子資料夾內容,原因是這只是針對播放器的處理,而一般播放器比較不會支援二層以上資料夾:

 

在上圖,我選擇831的資料夾進行重建。

一開始,檔案不一定會照你所知道的順序出現,如果是這種狀況通常是 FAT 的檔案順序。

接下來你可以,依照需要選擇排序方式:

或是,手動選擇檔案,進行位置調整。

排好檔案順序後就可以按『處理』鈕進行重建了

接下來就是等待處理完成。

重建處理時會在該資料夾的磁碟機內產生一個暫存資料夾 TempF

如果發生狀況,檔案會保存在此處,您可以把狀況處理完後,在把這資料夾檔案複製回去就可以了。

重建完的檔案就可以在這些『特殊』的播放器上正常依照你指定的順序撥放了。

小工具開發 – 檔案實序排定器已关闭评论
2020年9月28日 By mikel 分类: JavaScript

来源: soulTable的小bug_qq_36307903的博客-CSDN博客

layui框架有一个刷新当前页在这里插入图片描述功能,当你和soulTable一起用时就会出现一个问题,soulTable的写法是判断你是否是第一次进入,如果是重载表格的列,让你之前对表格列的处理可以记忆,但是你刷新当前页时,他就会判断你不是第一次进入,导致不对列进行处理,恢复表格最开始的情况,所以需要对代码做一下处理,先在定义一个新的变量用于判断是否是真正的第一次进入
在这里插入图片描述
在这里插入图片描述
这里改成(isFirst||aaa)随便一个变量名,并且在引入后

soulTable的小bug_qq_36307903的博客-CSDN博客已关闭评论
2020年9月25日 By mikel 分类: JavaScript, Debug

来源: Angular $injector:unpr Unknown provider 问题原因汇总_大V的博客-CSDN博客

Unknown provider: tProvider <- t 对于很多Angular 1.x 的使用者来说,是非常头疼的一件事情,因为使用者根本不知道原因在哪里。

本文总结了迄今为止所有导致这一个问题的可能原因,希望大家遇到此问题时,不要慌!跟着下面内容一步步排查:

问题描述:

Unknown provider 一般是由于无法解析注入的一个依赖所导致的。原因一般有如下这几种可能:

1. 依赖没有定义

  1. angular.module(‘myApp’, [])
  2. .controller(‘MyController’, [‘myService’, function (myService) {
  3. // Do something with myService
  4. }]);

上述代码,由于之前没有定义myService这个依赖,会报错 [$injector:unpr] Unknown provider。如果发现有没定义的依赖,首先要提前定义好这个依赖。

  1. angular.module(‘myApp’, [])
  2. .service(‘myService’, function () { /* … */ })
  3. .controller(‘MyController’, [‘myService’, function (myService) {
  4. // Do something with myService
  5. }]);

2. 重新使用了angular.module

  1. angular.module(‘myModule’, [])
  2. .service(‘myCoolService’, function () { /* … */ });
  3. angular.module(‘myModule’, [])
  4. // myModule has already been created! This is not what you want!
  5. .directive(‘myDirective’, [‘myCoolService’, function (myCoolService) {
  6. // This directive definition throws unknown provider, because myCoolService
  7. // has been destroyed.
  8. }]);

上述代码中,重复使用了angular.module(‘myModule’, []),会让angular重新定义myModule这个模块,导致报错。angular.module(‘myModule’, []) 这个语法一般是再次定义module,为了避免这个问题,在定义module之后直接使用angular.module(‘myModule’)或者使用一个变量代替之即可。

  1. angular.module(‘myModule’, []);
  2. .service(‘myCoolService’, function () { /* … */ });
  3. angular.module(‘myModule’)
  4. .directive(‘myDirective’, [‘myCoolService’, function (myCoolService) {
  5. // This directive definition does not throw unknown provider.
  6. }]);
  7. 或者
  8. var app = angular.module(‘myModule’, []);
  9. app.service(‘myCoolService’, function () { /* … */ });
  10. app.directive(‘myDirective’, [‘myCoolService’, function (myCoolService) {
  11. // This directive definition does not throw unknown provider.
  12. }]);

3. 把一个controller当依赖注入到另外一个controller中

  1. angular.module(‘myModule’, [])
  2. .controller(‘MyFirstController’, function() { /* … */ })
  3. .controller(‘MySecondController’, [‘MyFirstController’, function(MyFirstController) {
  4. // This controller throws an unknown provider error because
  5. // MyFirstController cannot be injected.
  6. }]);

其实如果要实例化controller,可以使用$controller服务(后续博客会更新)

4. 把$scope注入到不是controller或者directive的组件中

  1. angular.module(‘myModule’, [])
  2. .service(‘MyController’, [‘$scope’, function($scope) {
  3. // This controller throws an unknown provider error because
  4. // a scope object cannot be injected into a service.
  5. }]);

发生这个情况,也很好排查,只要牢记,只有controller和directive才能注入$scope作为依赖。

5. 使用angular压缩版导致报错

可以使用ngStrictDi

好了,希望本文能帮助到大家,遇此问题千万别慌了神!

Angular $injector:unpr Unknown provider 问题原因汇总_大V的博客-CSDN博客已关闭评论
2020年9月25日 By mikel 分类: JavaScript, Debug

来源: Angular 之 ngStrictDi_大V的博客-CSDN博客

ngStrictDi主要是讲angular依赖注入的写法问题,如果写法不规范,可能会在加载压缩版Angular的时候导致Unknown provider的错误。

  1. var app = angular.module(‘ngAppStrictDemo’, []);
  2. 1. 不规范写法
  3. app.controller(‘BadController’, function($scope) {
  4. $scope.a = 1;
  5. $scope.b = 2;
  6. });
  7. 2.规范写法
  8. //使用了详细的注释,数组形式注入
  9. app.controller(‘GoodController1’, [‘$scope’, function($scope) {
  10. $scope.a = 1;
  11. $scope.b = 2;
  12. }]);
  13. //直接使用$inject服务,注入
  14. app.controller(‘GoodController2’, GoodController2);
  15. function GoodController2($scope) {
  16. $scope.name = ‘World’;
  17. }
  18. GoodController2.$inject = [‘$scope’];

在1.6.x之后,依赖注入的书写越来越严格,这是为了避免压缩代码后产生的unknown provider问题。尤其是小编使用了webpack打包Angular项目之后,这个问题尤为突出。

如果依赖过多,显示或者解读代码不时,推荐大家使用规范写法的第二种。

Angular 之 ngStrictDi_大V的博客-CSDN博客已关闭评论
2020年9月25日 By mikel 分类: C#, Debug, 数据库

RedisHelper

来源: csredis – 在西天取经的路上…… – 博客园

源码地址:https://github.com/2881099/csredis

1、增加了 CSRedisClient 现实集群与连接池管理,和 RedisHelper 静态类快速上手

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//普通模式
var csredis = new CSRedis.CSRedisClient("127.0.0.1:6379,password=123,defaultDatabase=13,poolsize=50,ssl=false,writeBuffer=10240,prefix=key前辍");
 
//集群模式
 
var csredis = new CSRedis.CSRedisClient(null,
  "127.0.0.1:6371,password=123,defaultDatabase=11,poolsize=10,ssl=false,writeBuffer=10240,prefix=key前辍",
  "127.0.0.1:6372,password=123,defaultDatabase=12,poolsize=11,ssl=false,writeBuffer=10240,prefix=key前辍",
  "127.0.0.1:6373,password=123,defaultDatabase=13,poolsize=12,ssl=false,writeBuffer=10240,prefix=key前辍",
  "127.0.0.1:6374,password=123,defaultDatabase=14,poolsize=13,ssl=false,writeBuffer=10240,prefix=key前辍");
//实现思路:根据key.GetHashCode() % 节点总数量,确定连向的节点
//也可以自定义规则(第一个参数设置)
 
//mvc分布式缓存注入 nuget Install-Package Caching.CSRedis
 
//初始化 RedisHelper
RedisHelper.Initialization(csredis,
  value => Newtonsoft.Json.JsonConvert.SerializeObject(value),
  deserialize: (data, type) => Newtonsoft.Json.JsonConvert.DeserializeObject(data, type));
//注册mvc分布式缓存
services.AddSingleton<IDistributedCache>(new Microsoft.Extensions.Caching.Redis.CSRedisCache(RedisHelper.Instance));
 
//提示:CSRedis.CSRedisClient 单例模式够用了,强烈建议使用 RedisHelper 静态类
RedisHelper.Set("test1""123123", 60);
RedisHelper.Get("test1");
//...函数名基本与 redis-cli 的命令相同

2、订阅与发布(分布式读写分离的场景)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//普通订阅
RedisHelper.Subscribe(
  ("chan1", msg => Console.WriteLine(msg.Body)),
  ("chan2", msg => Console.WriteLine(msg.Body)));
 
//模式订阅(通配符)
RedisHelper.PSubscribe(new[] { "test*""*test001""test*002" }, msg => {
  Console.WriteLine($"PSUB   {msg.MessageId}:{msg.Body}    {msg.Pattern}: chan:{msg.Channel}");
});
//模式订阅已经解决的难题:
//1、集群的节点匹配规则,导致通配符最大可能匹配全部节点,所以全部节点都要订阅
//2、本组 "test*", "*test001", "test*002" 订阅全部节点时,需要解决同一条消息不可执行多次
 
//发布,
RedisHelper.Publish("chan1""123123123");
//无论是集群或普通模式,RedisHelper.Publish 都能正常通信

3、缓存壳

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//不加缓存的时候,要从数据库查询
var t1 = Test.Select.WhereId(1).ToOne();
 
//一般的缓存代码,如不封装还挺繁琐的
var cacheValue = RedisHelper.Get("test1");
if (!string.IsNullOrEmpty(cacheValue)) {
    try {
        return JsonConvert.DeserializeObject(cacheValue);
    catch {
        //出错时删除key
        RedisHelper.Remove("test1");
        throw;
    }
}
var t1 = Test.Select.WhereId(1).ToOne();
RedisHelper.Set("test1", JsonConvert.SerializeObject(t1), 10); //缓存10秒
 
//使用缓存壳效果同上,以下示例使用 string 和 hash 缓存数据
var t1 = RedisHelper.CacheShell("test1", 10, () => Test.Select.WhereId(1).ToOne());
var t2 = RedisHelper.CacheShell("test""1", 10, () => Test.Select.WhereId(1).ToOne());
var t3 = RedisHelper.CacheShell("test"new [] { "1""2" }, 10, notCacheFields => new [] {
  ("1", Test.Select.WhereId(1).ToOne()),
  ("2", Test.Select.WhereId(2).ToOne())
});
csredis – 在西天取经的路上…… – 博客园已关闭评论
2020年9月24日 By mikel 分类: ASP.NET MVC, ASP.NET, C#, Debug

来源: .NET MVC 简单实现GZIP – 无记 – 博客园

GZIP的好处大家都知道,不过一般系统来说页面不会太大,很多人也没注意过这玩意儿。前段时间做一个系统用了一个国人开发的JQuery富客户端框架DWZ(个人感觉这个框架还是蛮不错的),类似EXT的AJAX框架,框架的JS加上我自己的真不小。

 

 

打算用GZIP来做压缩,之前在IIS6上做过,这个项目用MVC做,发现在.NET MVC下有更简单好用的办法来解决:写一个ActionFilter来实现GZIP,优点大家用了就知道,呵呵

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class CompressAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var acceptEncoding = filterContext.HttpContext.Request.Headers["Accept-Encoding"];
        if (!string.IsNullOrEmpty(acceptEncoding))
        {
            acceptEncoding = acceptEncoding.ToLower();
            var response = filterContext.HttpContext.Response;
            if (acceptEncoding.Contains("gzip"))
            {
                response.AppendHeader("Content-encoding", "gzip");
                response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
            }
            else if (acceptEncoding.Contains("deflate"))
            {
                response.AppendHeader("Content-encoding", "deflate");
                response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
            }
        }
    }
}

用法:

1
2
3
4
5
6
7
[Longin]
[Compress]
public ActionResult Index()
{
    
        return View();
}

只要在打算用GZIP压缩的Action上写上[Compress]就OK了,是不是很简单,呵呵~

.NET MVC 简单实现GZIP – 无记 – 博客园已关闭评论
备案信息冀ICP 0007948