flutter cnode android 客户端
最近在学习flutter, 但是光看文档感觉有点枯燥而且也没有直观的感受 所以借用 cnode 的open api 写了个客户端, 加深下理解 客户端功能不多, 但还是欢迎大家能试用下哈
下载地址
- 64位
- 32 位
最近在学习flutter, 但是光看文档感觉有点枯燥而且也没有直观的感受 所以借用 cnode 的open api 写了个客户端, 加深下理解 客户端功能不多, 但还是欢迎大家能试用下哈
我有一个package.json的文件.
scripts部分的缩进是6个空格
在linux上面通过git拉取代码下来,进行npm install
变为了4个空格的缩进。
npm install
之前
npm install
之后
我的依赖项
"dependencies": {
"@grpc/proto-loader": "^0.5.3",
"amqplib": "^0.5.5",
"async": "^3.1.0",
"dateformat": "^3.0.3",
"grpc": "^1.24.2",
"ioredis": "^4.14.1",
"md5": "^2.2.1",
"mongodb": "^3.4.0",
"mysql": "^2.17.1",
"request": "^2.88.0"
}
翻了下文档和npm install部分源码我发现fs
模块只有执行过读文件操作,并没有写(或许我忽略了)。
请问各位这是什么原因导致格式化?
项目中有一个下载图片的需求,现在在编写下载代码的过程中遇到了一些问题。
我的需求是进行批量下载,如果下载失败需要进行记录,然后用本地的404图片替代。 下载完的图片需要马上放入docx文件中,所以需要对下载的过程进行整体阻塞。
一开始我是使用最简单的方法进行下载
function download(src, dest) {
return new Promise((res,rej) => {
const pipe = request(src).pipe(fs.createWriteStream(dest))
pipe.on('close',() => res());
pipe.on('error',(err) => rej(err));
});
}
后面我发现, 如果目标是404的话,他会将404的信息写入到图片中,而不会有报错信息。 我的代码变成 request.get({url}, (err,res) => { if(err) return rej(err); if(res.statusCode === 404) return rej(‘404’); fs.writeFile(dest, responseBody, ‘binary’, err => { if(err) return rej(err); return res(1); }); }); 但组长说得使用流的方式写, 不然占用太多内存。 我又使用了wget,但是写完了之后发现偶尔会有一两张下载不完全,导致后面代码获取的时候出错。 查看了一下wget的代码,
var downloader = new EventEmitter(),
req = request(options, function(res) {
var fileSize, writeStream, downloadedSize;
if (res.statusCode === 200) {
downloadedSize = 0;
fileSize = res.headers['content-length'];
writeStream = fs.createWriteStream(output, {
flags: 'a',
encoding: 'binary'
});
res.on('error', function(err) {
writeStream.end();
downloader.emit('error', err);
});
res.on('data', function(chunk) {
downloadedSize += chunk.length;
downloader.emit('progress', downloadedSize/fileSize);
writeStream.write(chunk);
});
res.on('end', function() {
writeStream.end();
downloader.emit('end', output);
});
} else {
downloader.emit('error', 'Server respond ' + res.statusCode);
}
});
我的代码里是用 downloader.on(‘end’,() => res());来判断是否成功, 但是在res.on(‘end’)的方法里面,writeStream.end();结束写入了,但好像还没有彻底完成? 所以我决定这样写
downloader.on('end',async () =>{
await sleep(500);
return res();
});
发现问题解决, 但是组长说不能这么写。
所以我又开始考虑superagent 我尝试是这么写
request.get(src)
.ok(res => res.statusCode === 200)
.then(res => {
const pipe = res.pipe(writeStream);
pipe.on....
})
但是这里报错,显示 end() has already been called, so its too late to starting piping
那么现在问题来了, 怎样才能在判断了statusCode 的情况下使用流下载图片啊
express+vue部署到服务器怎么弄 求详细的教程
同时我们还有产品经理、HR 等岗位正在招聘!您可以直接到我们的官网 https://hr.aftership.com查看详情!
或者您可以将您的简历以 [姓名+应聘职位+论坛名称+日期] 为名的邮件发送到 qs.jin@aftership.com来与 HR 更直接的沟通!
AfterShip (爱客科技)( https://www.aftership.com/)是一个为国际性电商企业而设的 B2B SaaS 平台,通过提供全方位和全自动化的工具,帮助电商降低营运成本及实现智能营销。公司全自动化系统涵盖市场推广、订单管理、运单打印、快递跟踪及退换货管理等。
2012 年成立于香港,2014 年开始盈利,业务遍布全球,与全球 500 多家物流公司达成合作,涉及 30 多种主流语言业务体系。客户有 Amazon, Wish, eBay, Paypal, Groupon, Etsy,及各大小电商超过 100,000 家,是国际快递查询领域里面的龙头企业。
AfterShip 是一家以产品为驱动,技术为核心的公司,日均承担过亿 API 请求。从公司成立开始,便大量使用优秀开源系统,拥抱创新科技,公司有良好的 SaaS 付费习惯,浓厚的工具化文化。
AfterShip 注重人才培养,在这里工作,每个人都可参加从用户沟通、需求讨论、产品开发、到上线部署的环节 ,团队国际化,公司成员来自十个不同的国家。
戳这里看看用一个开源项目做的代码风格的公司介绍: https://activity.lagou.com/gracie/pc/AfterShip0213.html
AfterShip 是香港早期 Google Cloud Platform ( GCP ) 客户之一,并且成为香港第一家 GCP 案例分析的公司,正是对 AfterShip 使用创新技术的肯定。 https://cloud.google.com/customers/aftership/
1、公司提供 Macbook Pro 与 LG 4K 显示器;
2、全额工资购买五险一金,补充购买商业险;
3、带薪病假和年假,转正可享 5 天带薪年假;
4、每人每月 100 元团队聚餐基金(可月累计);
5、购买书籍、在线课程均可报销(不限类别);
6、每天下午茶、每周羽毛球,不定期生日会;
7、每年不定期进行正规医院 /体检机构健康检查;
8、每年不定期市内 /省内 /国内 /国外外出旅游;
9、支持使用可以帮助工作做得更好的付费工具。
我们是一群热爱编程的代码农,但我们不是代码奴!
我们不会单纯接受指令去编程,我们会问为什么要编写这些功能,谁是我们的用户,我们关心用户体验,要打造世界级的产品。
我们为写的代码负责,对代码质素有要求,由代码风格开始,测试,编写技术文档,一丝不苟。 我们注重自动化,使用自动化测试,持续集成与持续交付提升生产力。
我们很挑工具,因为我们深信工欲善其事,必先利其器,选对工具非常重要,善借于物能极大提高开发效率。
我们使用 New Relic 作系统监测、Pingdom, Pagerduty 报警、Cloudflare CDN 加速、Twilio 发 SMS, Sendgrid 发邮件、1Password 管理密码、Zoom 视象会议还有很多很多的工具。
我们为 AfterShip 公司自豪,不是因为公司开明、慷慨,所有工具不论是否要付费,公司愿意给我们支持,全数买单。而是因为 AfterShip 对员工的重视,人才永远放在第一,为员工负责,不断推动我们学习,提升技能。
我们大量使用开源软件,因为我们深信分享是最伟大的。
我们愿意意贡献我们有用的,把好的东西跟全世界分享。
我们使用的 SaaS 工具: https://github.com/AfterShip/SaaS
我们的代码风格: https://github.com/AfterShip/eslint-config-aftership
自动格式化全球电话号码: https://github.com/AfterShip/phone
Koa middleware for New Relic: https://github.com/AfterShip/koa-newrelic
不太理解官网上的描述,
return new Promise((resolve, reject) => { //…some code });
promise这样用法,发现内存暴涨 ,求大佬解答
毋庸置疑,NodeJS全栈开发包括NodeJS在前端的应用,也包括NodeJS在后端的应用。CabloyJS前端采用Vue+Framework7,采用Webpack进行打包。CabloyJS后端是基于EggJS开发的上层框架。我们知道,EggJS采用的是约定优于配置
的原则,当服务启动时,会在约定的目录加载controller
、servier
诸如此类的文件。那么,我们基于EggJS开发的后端代码,是否也可以像前端一样进行Webpack打包呢?
为什么要提出这样一个命题:NodeJS后端编译打包?
因为NodeJS后端编译打包
有如下两个显著的好处:
编译打包
,可以将源码进行丑化,满足保护商业代码的需求。虽然丑化javascript代码无法完全避免反编译,但我们要基于一个原则:丑化最主要的目的是保护开发团队的工作量
。可以想象,反编译
及以反编译
为基础的二次开发,工作量并不小
编译打包
,可以将众多散乱的javascript文件合并成一个文件,从而提升后端服务的启动性能。这在大型项目的开发中,效果更加显著
在接下来的案例中,我们会以模块egg-born-module-test-party
为例。该模块后端有63
个js源码文件,通过编译打包后只生成一个backend.js
文件。当后端服务启动时,一个模块只需加载一个文件,性能肯定优于加载63
个文件。如果一个大型项目包含100
个业务模块,这种性能优势就会更加明显
进行JS文件打包的工具有很多,由于CabloyJS前端是采用Webpack进行打包,因此,在这里,我们也只探讨Webpack在后端的打包方式
我们知道,Webpack是从一个入口文件开始,通过检索require
方法,得到一棵完整的文件依赖树,然后把这些依赖树合并成一个文件,最后进行丑化
而EggJS采用的是约定优于配置
的原则,文件之间的依赖关系是隐性约定的,而不是通过require
显式声明的。因此,在这种机制下面,Webpack打包是不起作用的
但是EggJS的定位就是框架的框架
,使得我们可以在EggJS的基础之上开发新的框架。CabloyJS后端就是在EggJS的基础之上,进行了进一步的扩展和封装,使得controller
、service
、middleware
、config
等诸如此类的定义文件,可以通过require
方法显式声明,从而可以让Webpack提炼出一棵完整的文件依赖树,进而完成编译打包工作
这篇文章的重点,不是要说明CabloyJS后端是如何对EggJS进行的扩展和封装,而是要说明,在已经实现require
显式声明的前提条件下,NodeJS后端如何进行编译打包
egg-born-module-test-party
是CabloyJS的测试模块,包含大量测试用例。我们以该模块为例来说明NodeJS后端编译打包的方方面面
我们先将模块源码下载到本地
$ git clone https://github.com/zhennann/egg-born-module-test-party.git
如果没有git命令行工具,可以直接从GitHub官网下载:https://github.com/zhennann/egg-born-module-test-party
$ npm i
npm run build:backend
只要我们指定了入口文件,Webpack就会自动通过require
检索文件依赖树。因此,剩下的核心工作,就是通过配置文件来调整Webpack的行为
const path = require('path');
const config = require('./config.js');
const nodeModules = {
require3: 'commonjs2 require3',
};
function resolve(dir) {
return path.join(__dirname, '../../backend', dir);
}
module.exports = {
entry: {
backend: resolve('src/main.js'),
},
target: 'node',
output: {
path: config.build.assetsRoot,
filename: '[name].js',
library: 'backend',
libraryTarget: 'commonjs2',
},
externals: nodeModules,
resolve: {
extensions: [ '.js', '.json' ],
},
module: {
rules: [],
},
node: {
console: false,
global: false,
process: false,
__filename: false,
__dirname: false,
Buffer: false,
setImmediate: false,
},
};
通过entry/output
的组合,我们指定了一个入口文件src/main.js
,最终编译打包成一个输出文件backend.js
Webpack是一个通用的打包工具,既可以用于前端浏览器,也可以用于后端NodeJS。因此,我们需要指定target为node
,从而为后端NodeJS打包。比如,在后端node
场景下,一些内置的模块就会被排除在打包之列,如fs
、path
等等
为了让原本为后端NodeJS开发的代码可以在前端浏览器中运行,Webpack提供了模拟策略。比如,global
、process
、__filename
和__dirname
都是NodeJS内置的对象。如果代码中包含了这些对象,而代码又需要在前端运行,就需要进行模拟。我们这里讨论的是后端编译,所以,就直接统一赋值false
,从而禁用模拟行为
如果我们在使用require
引用源码文件时没有指定文件扩展名,那么Webpack会通过resolve.extensions
帮我们匹配合适的文件名
Webpack除了可以打包js文件,还可以打包css/image/text等资源文件。因为这里是后端打包,所以,不需要设置module.rules
在这里重点要说的是节点externals
在实际的业务开发中,我们难免会用到大量第三方模块,这些模块一般都安装在node_modules目录,比如moment
。因为我们也是通过const moment=require('moment')
的方式引用第三方库,所以,Webpack也会尝试把moment
打包进来
一方面,第三方模块数量众多,如果进行打包,最终输出文件过大。另一方面,对于保护商业代码没有任何意义。所以,我们需要想一个办法把这些第三方模块从打包依赖树中排除掉
如果我们要排除moment,可以这样配置:
externals: {
moment: 'commonjs2 moment'
}
如果我们要排除node_modules目录下的所有第三方模块,可以这样配置:
var fs = require('fs');
var nodeModules = {};
fs.readdirSync('node_modules')
.filter(function(x) {
return ['.bin'].indexOf(x) === -1;
})
.forEach(function(mod) {
nodeModules[mod] = 'commonjs2 ' + mod;
});
module.exports = {
...
externals: nodeModules
...
}
针对这种场景,CabloyJS单独开发了一个NPM模块require3
: https://github.com/zhennann/require3
我们只需要在externals中排除require3
这一个模块就可以了。其余的模块都通过require3进行引用,从而轻松避免了被打包的行为
const nodeModules = {
require3: 'commonjs2 require3',
};
module.exports = {
...
externals: nodeModules
...
}
在实际业务代码中,一般这样引用:
const require3 = require('require3');
const moment = require3('moment');
moment通过
require3
引用,从而避免被Webpack打包
const webpack = require('webpack');
const config = require('./config.js');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const env = config.build.env;
const plugins = [
new webpack.DefinePlugin({
'process.env': env,
}),
];
const webpackConfig = merge(baseWebpackConfig, {
mode: 'production',
devtool: config.build.productionSourceMap ? 'source-map' : false,
plugins,
optimization: {
runtimeChunk: false,
splitChunks: false,
minimize: config.build.uglify,
},
});
module.exports = webpackConfig;
通过指定mode为production
,指示Webpack使用与production
相关的内置的优化策略
指示Webpack是否生成source map文件,如果要生成,source map的文件格式是什么
详细的格式清单,请参考:https://webpack.js.org/configuration/devtool/
由于我们只需输出一个单文件,所以只需通过optimization.minimize
指示Webpack是否需要最小化(丑化)即可
最后,让我们再执行一次NodeJS后端的编译打包指令
npm run build:backend
1 写法 和 2 写法的区别是什么?
zxczxczx
如题
我在使用Koa和SuperAgent写爬虫脚本时遇到了些问题。 但是当我运行项目时,会引发报错。
代码
const Koa = require('koa');
// const request = require('request')
const superagent= require('superagent');
const app = new Koa();
app.use(async ctx => {
const res = await superagent.get('https://www.google.com');
ctx.body = res
})
app.listen(3000);
报错信息
Error: end() has already been called, so it's too late to start piping
at Response.response.pipe (F:\Project\Self_Project\Boxcc\node_modules\superagent\src\node\index.js:923:13)
at respond (F:\Project\Self_Project\Boxcc\node_modules\koa\lib\application.js:256:43)
at handleResponse (F:\Project\Self_Project\Boxcc\node_modules\koa\lib\application.js:164:34)
at process._tickCallback (internal/process/next_tick.js:68:7)
(node:20500) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
Error: end() has already been called, so it's too late to start piping
at Response.response.pipe (F:\Project\Self_Project\Boxcc\node_modules\superagent\src\node\index.js:923:13)
at respond (F:\Project\Self_Project\Boxcc\node_modules\koa\lib\application.js:256:43)
at handleResponse (F:\Project\Self_Project\Boxcc\node_modules\koa\lib\application.js:164:34)
at process._tickCallback (internal/process/next_tick.js:68:7)
在多人协作开发一个koa2的项目的时候,不同开发者用于测试的本地服务器配置可能是不相同的,例如:开发者A本地数据库的密码是123456 B开发者本地数据库的密码是root,如果他们修改的是同一个数据库配置文件的话,代码就会起冲突。
想知道这时候该怎么办,使用.gitignore文件忽略数据库配置文件吗?
假如: let arr = [ {nid:3,name:“张三”}, {nid:2,name:“李四”}, {nid:2,name:“王五”} ]; arr.sort((a,b)=>{ return a.nid -b.nid });
运算结果: 是否任何环境下的结果都是: [ {nid:2,name:“李四”}, {nid:2,name:“王五”}, {nid:3,name:“张三”}, ]; 问题? 有没可能出现: [ {nid:2,name:“王五”}, {nid:2,name:“李四”}, {nid:3,name:“张三”}, ];
1.熟练使用 javascript 异步编程
2.能编写简单算法
3.理解HTTP/TCP协议
4.熟练使用mongodb redis
5.有github开源项目者优先
6.有高并发、分布式处理经验者优先
7.有ELK Kafka rabbitmq protobuf 使用经验者优先
boss直聘小程序链接:
如题求解
最近在学习nodeJS,再往大前端方向升级自己,但是自己的本是8年的老本已经无法满足自己的开发需求,想更换一台,求大神推荐
Hello,大家好,我最近在github上做一个关于Vue源码的开源项目,项目内容是:
利用工作之余时间逐行剖析Vuejs源码,将Vuejs源码分为九大模块,逐个击破,希望能帮助到更多的Vue初学者。
阅读地址:https://nlrx-wjc.github.io/Learn-Vue-Source-Code/阅读地址是源码的解析文档,可在线阅读
项目地址:https://github.com/NLRX-WJC/Learn-Vue-Source-Code项目地址里包括了一份带有注释的vue源码和解析文档的源文件
目前数据侦测篇,虚拟DOM篇,模板编译篇,生命周期篇,实例方法篇,全局API篇,过滤器篇均已完成,接下来剖析Vue中的指令和内置组件,后续持续更新中。。。
写作是一件十分枯燥的事情,如果我写的这些文字对你有些许帮助的话,还请赏个star哈~~
另外,本项目受到了阮一峰老师的肯定,已刊登在阮一峰老师微信公众号科技爱好者第87期。
【1封新邀请】5大主题干货满满 ECUG For Future技术盛宴等你参加!
Q:主办方是否提供发票? A:如需开发票,活动结束后添加工作人员微信(ID:qiniuguanfang),会务组核对无误后,将会在2周内统一安排发放,如遇节假日顺延。
Q:是否有交流群?如何加入? A:成功报名活动后,现场扫码加入现场交流群。
Q:活动是否含餐? A:签到处会统一发放当天午餐券,凭餐券就餐。(就餐处距离活动地点50米)
Q:如何签到? A:活动当天,您需要凭活动行发给您购票的参会二维码,到现场签到处签。如二维码遗失,也可以通过“手机号”签到。
Q:参会人员座位是否有预留?现场是否需要对号入座? A:靠前第一排会给讲师预留座位,观众票座位不对号入座,不预留座位。
自己写了一个 egg 的插件,在插件代码 agent.js中 beforeStart 生命周期内添加了插件启动前的一些必要操作,在脚手架生成的单元测试代码中并没有执行,查看插件官方文档也没有对这个情况的单元测试进行说明,请问有了解的大佬吗? 测试代码如下
'use strict';
const mock = require('egg-mock');
const assert = require('assert');
describe('test/apollo-ddz.test.js', () => {
let app;
before(() => {
app = mock.app({
baseDir: 'apps/apollo-ddz-test',
});
return app.ready();
});
after(() => app.close());
afterEach(mock.restore);
it('should GET /', async () => {
await app.initApollo();
assert(app.config.nodeConfig, ' apollo 配置获取失败');
});
});