您现在的位置是:网站首页> NodeJS
nodejs开发笔记
- NodeJS
- 2025-09-08
- 1319人已阅读
nodejs开发笔记
pkg Nodejs Web应用打包成exe可执行文件并打开浏览器
Apify SDK-用于JavaScript的可伸缩web爬行和抓取库/节点.js
nodejs中exports和module.exports的区别
nodejs介绍
使用n模块进行管理
首先需要先安装n模块
npm install -g n
然后执行以下命令,即可将npm升级至最新版本
n latest npm
然后执行以下命令,即可将node.js升级至最新版本
n latest
npm 是 Node.js 自带的,pnpm 是需要额外安装的第三方工具。
npm install -g pnpm
当用正常安装出错时如:
npm install @types/lodash
解决办法
方式一、临时使用其他仓库进行下载安装
npm --registry https://registry.npm.taobao.org/ install @types/lodash
方式二、切换仓库进行下载安装
如何更换npm仓库
你可以使用以下命令来切换npm仓库:
npm config set registry <仓库地址>
方式三、通过cnpm来安装
安装cnpm
npm intsall -g cnpm -- registry=https://registry.npm.taobao.org/
查看版本
cnpm -v
npm仓库有哪些
使用下面指令可以查看镜像源:
npm config get registry
官方仓库 - https://registry.npmjs.org/
官方镜像仓库 - https://skimdb.npmjs.com/registry/
淘宝镜像仓库(旧域名) - https://registry.npm.taobao.org/
淘宝镜像仓库(新域名) - https://registry.npmmirror.com/
腾讯仓库 - https://mirrors.cloud.tencent.com/npm/
cnpm仓库 - https://r.cnpmjs.org/
yarn仓库 - https://registry.yarnpkg.com/
nodejs 全局包路径的有时候命令行无效记得加入path
打开:nodejs安装?录/node_modules/npm/.npmrc这个文件件,修改路径
prefix = E:\nodejs\npm_global_modules
查看全局路径
npm config ls
将E:\nodejs\npm_global_modules 加入path以便在别的地方可以执行命令
如pkg打包
pkg的缓存目录:C:\Users\Administrator\.pkg-cached
$ pkg -t win server.js
> pkg@5.6.0
> Fetching base Node.js binaries to PKG_CACHE_PATH
fetched-v16.14.2-win-x64 [ ] 0%> Not found in remote cache:
{"tag":"v3.3","name":"node-v16.14.2-win-x64"}
> Building base binary from source:
built-v16.14.2-win-x64
> Fetching Node.js source archive from nodejs.org...
> Error! AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
大意是缓存里缺少相应的二进制文件fetched-v16.14.2-win-x64,咱们只要下载到相应的文件,放到相应的缓存目录就好。
去官网下载相应版本文件,比如我的是node-v16.14.2-win-x64
官网地址:https://github.com/vercel/pkg-fetch/releases
将上一步下载的文件node-v16.14.2-win-x64重命名为fetched-v16.14.2-win-x64,放到当前用户的缓存目录中。
比如我的缓存目录是C:\Users\Administrator\.pkg-cache,拼接上fetch的tag就变成了最终的目录,参照报错中的信息,可以得到tag为v3.3
{"tag":"v3.3","name":"node-v16.14.2-win-x64"}
当然,你的tag可能和我不一样,看你自己的报错信息把。
咱们可以得到最终的父目录为C:\Users\Administrator\.pkg-cache\v3.3,
所以最终的文件地址为C:\Users\Administrator\.pkg-cache\v3.3\fetched-v16.14.2-win-x64
打包
pkg.cmd -t win main.js
pkg Nodejs Web应用打包成exe可执行文件并打开浏览器
将Node.js打包为可执行文件的工具有pkg、nexe、node-packer、enclose等,从打包速度、使用便捷程度、功能完整性来说,pkg是最优秀的。
pkg Nodejs Web应用打包成exe可执行文件并打开浏览器
引言
我们都知道nodejs的项目本身是没办法编译成二进制可执行文件的,这给我们很多的业务场景造成了一些问题,比如要给客户演示程序的时候,可能还得安装node环境,然后在安装一堆的依赖包,这还必须是网络环境较好的情况下,而有时候,一般企业如果安全看的特别重,限制在局域网内访问互联网,那么连包都没办法安装,显然对于你和对于客户都是不友好的情景。
还有一种情况:如果我们演示项目时,把代码交给对方部署,我们自己也不放心啊:Nodejs代码是明文JS代码,代码泄露怎么办?当然,防代码泄露可以用JShaman平台对JS代码进行混淆加密。
pkg可以直接将nodejs项目打包成可执行文件,直接可以在没有node环境下的freebsd,linux,alpine,macos,win上运行。
pkg打包的原理
pkg实际上并不是直接将程序转换成可执行文件,而是将node环境一起打包到了程序中,这样就可以做到不用在没有node环境下的电脑上运行node项目了,是不是很方便。下面我就将带领大家一起来看下如何使用pkg打包。测试用例使用的是nodejs的express
使用场景
在没有来源的情况下制作商业版的应用程序
在没有来源的情况下制作应用的演示/评估/试用版
立即为其他平台制作可执行文件(交叉编译)
制作某种自解压存档或安装程序
无需安装Node.js和npm来运行打包的应用程序
无需下载无数个文件npm install来部署您的应用程序。将其部署为单个文件
将您的资产放在可执行文件中,使其更具可移植性
针对新的Node.js版本测试您的应用程序而不安装它
首先安装pkg
npm install -g pkg
然后在项目目录下执行
pkg entrance.js
即可打包linux,macos,win3个平台的可执行文件。entrance.js为你node项目的入口文件。
如果只想打包windows下的exe,则加上-t参数。win即为打包成windows平台下的exe文件,具体可选参数参见项目目录
pkg -t win entrance.js
稍等片刻后项目目录下就会生成打包好的entrance.exe文件。
pkg会自动从入口文件开始查找依赖的文件并全数打包进去,无须修改项目里的任何代码。
其他
pkg可以根据package.json下的配置进行打包,默认入口文件为bin指向的文件。
执行
pkg .
或是
pkg package.json
即可自动按照package.json的配置打包。
//package.json
{
//其他配置项
"bin": "service.js",//入口文件
"pkg": {
"scripts": [
"build/**/*.js"//需要打包进来的其他js文件,可添加多个
],
"assets": [
"dist/**/*"//静态文件的目录,可添加多个
]
}
}
注意:静态文件需要在项目中将文件的引用换成
path.join(__dirname, 'dist')
的形式,才可以正常打包,否则可能会读取不到。
示例
使用vue-cli建立项目,并使用npm run build将你的项目编译生成静态文件到dist目录下。这些都是vue-cli自带的内容,不再赘述。
在项目目录下新建一个service.js文件,并添加以下代码,在本地起一个express静态服务器,使你能够在本地访问你的网站(部署到线上也是类似)
//service.js
const express = require('express');
const app = express();
const path = require('path');
app.use(express.static(path.join(__dirname, 'dist')));//注意这里使用path.join(__dirname, 'dist')而不是'dist',虽然在命令行中执行起来效果是一样的,不过pkg打包会无法识别到dist目录
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log(`AIbuy agents server start successfully on http://${host}:${port}`)
})
此时你可以在控制台执行
node service.js
来启动你的服务器了,启动完成后,浏览器访问http://localhost:8081/即可查看你的网站。
接下来我们使用将service.js和dist目录打包成一个exe文件,方便他人使用
首先安装pkg
npm install -g pkg
然后修改package.json,添加bin(如果不是service.js的话)和pkg项
{
//其他配置项
"bin": "service.js",//指定入口文件
"pkg": {
"assets": [
"dist/**/*"//指定要打包的静态文件目录
]
}
}
然后在项目目录下执行
pkg -t win package.json
完成后即生成一个exe文件,双击启动即相当于执行node service.js,然后你浏览器里(http://localhost:8081/)就能访问打包好的项目了!也不需要提前安装node,给老板演示很方便有木有!
上面是我整理给大家的,希望今后会对大家有帮助。
$ pkg -t win server.js
> pkg@5.6.0
> Fetching base Node.js binaries to PKG_CACHE_PATH
fetched-v16.14.2-win-x64 [ ] 0%> Not found in remote cache:
{"tag":"v3.3","name":"node-v16.14.2-win-x64"}
> Building base binary from source:
built-v16.14.2-win-x64
> Fetching Node.js source archive from nodejs.org...
> Error! AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
大意是缓存里缺少相应的二进制文件fetched-v16.14.2-win-x64,咱们只要下载到相应的文件,放到相应的缓存目录就好。
去官网下载相应版本文件,比如我的是node-v16.14.2-win-x64
官网地址:https://github.com/vercel/pkg-fetch/releases
将上一步下载的文件node-v16.14.2-win-x64重命名为fetched-v16.14.2-win-x64,放到当前用户的缓存目录中。
比如我的缓存目录是C:\Users\MangoDowner\.pkg-cache,拼接上fetch的tag就变成了最终的目录,参照报错中的信息,可以得到tag为v3.3
{"tag":"v3.3","name":"node-v16.14.2-win-x64"}
当然,你的tag可能和我不一样,看你自己的报错信息把。
咱们可以得到最终的父目录为C:\Users\MangoDowner\.pkg-cache\v3.3,
所以最终的文件地址为C:\Users\MangoDowner\.pkg-cache\v3.3\fetched-v16.14.2-win-x64
再次编译,成功!
$ pkg -t win server.js
> pkg@5.6.0
pkg的缓存目录:C:\Users\Administrator\.pkg-cache
Apify SDK-用于JavaScript的可伸缩web爬行和抓取库/节点.js
Apify SDK-用于JavaScript的可伸缩web爬行和抓取库/节点.js. 使用headless Chrome和Puppeter可以开发数据提取和web自动化作业
nodejs中exports和module.exports的区别
module.exports 对象是由模块系统创建的。在我们自己写模块的时候,需要在模块最后写好模块接口,声明这个模块对外暴露什么内容,module.exports 提供了暴露接口的方法。
1、返回一个JSON Object
var app = {
name: 'app',
version: '1.0.0',
sayName: function(name){
console.log(this.name);
}
}
module.exports = app;
这种方法可以返回全局共享的变量或者方法。
调用方法:
var app = require('./app.js');
app.sayName('hello');//hello
或者这样用:
var func1 = function() {
console.log("func1");
};
var func2 = function() {
console.log("func2");
};
exports.function1 = func1;
exports.function2 = func2;
调用方法为:
var functions = require("./functions");
functions.function1();
functions.function2();
2、返回一个构造函数
CLASS.js:
var CLASS = function(args){
this.args = args;
}
module.exports = CLASS;
调用:
var CLASS = require('./CLASS.js');
varc = new CLASS('arguments');
3、返回一个实例对象:
//CLASS.js
var CLASS = function(){
this.name = "class";
}
CLASS .prototype.func = function(){
alert(this.name);
}
module.exports = new CLASS();
调用:
var c = require('./CLASS.js');
c.func();//"class"
exports和module.exports
可是这两种使用起来到底有什么区别呢???
看了很多文章,长篇大论,始终没有讲清楚区别,自己也是看了很多,终于搞清楚了,给大家分享一下
根据使用方法来说
通常exports方式使用方法是:
exports.[function name] = [function name]
moudle.exports方式使用方法是:
moudle.exports= [function name]
这样使用两者根本区别是
**exports **返回的是模块函数
**module.exports **返回的是模块对象本身,返回的是一个类
使用上的区别是
exports的方法可以直接调用
module.exports需要new对象之后才可以调用
二话不说,撸代码!
1. exports方式
先创建一个exports_mode.js
var sayHello = function(){ console.log('hello')
}
exports.sayHello = sayHelloconsole.log(exports);
console.log(module.exports);
然后写一个test.js调用下试试看
var exports_mode = require('./exports_mode')
exports_mode.sayHello()
输出:
exports_mode.png
发现此时exports和module.exports对象输出的都是一个sayHello方法,
为什么module.exports也有exports方法了,简单点理解就是
exports是module.exports的一个引用,exports指向的是module.exports
我们来验证下,在exports_mode.js最后一行添加一句代码
var sayHello = function(){ console.log('hello')
}
exports.sayHello = sayHelloconsole.log(exports);
console.log(module.exports);
console.log(exports === module.exports);
结果输出.png
发现console.log(exports === module.exports)返回的是true,
说明exports和module.exports是同一个对象
下来看看
2. module.exports方式
首先创建module_exports_mode.js
var sayHello = function(){ console.log('hello')
}module.exports = sayHelloconsole.log(module.exports);
console.log(exports);
console.log(exports === module.exports);
然后测试一下
var module_export_mode = require('./module_exports_mode')
module_export_mode.sayHello()
控制台输出.png
发现输出报错了!
为什么呢,因为我们的调用方式错了,一开始就说到了
**module.exports **返回的是模块对象本身
正确的调用
var module_export_mode = require('./module_exports_mode')new module_export_mode()
控制台输出.png
同时我们可以看到,输出的module.exports对象内容就是一个[Function],在javascript里面是一个类
使用这样的好处是exports只能对外暴露单个函数,但是module.exports却能暴露一个类
我们把module_exports_mode.js扩展一下
var xiaoming = function(name){ this.name = name this.sayHello = function(){ return 'hello '+this.name
} this.sayGoodBye = function(){ return 'goodbye '+this.name
}
}module.exports = xiaomingconsole.log(module.exports);
console.log(exports);
console.log(exports === module.exports);
然后测试
var xiaoming = require('./module_exports_mode')var xiaoming = new xiaoming('Lucien')console.log(xiaoming.sayHello())console.log(xiaoming.sayGoodBye())
控制台输出.png
使用方法和javascript的类创建对象一毛一样
exports.[function name] = [function name]
moudle.exports= [function name]
以上就是这两种方式的使用区别。
等等,还没完。。。
上面有提到
exports是module.exports的一个引用,exports指向的是module.exports
也就是说exports的方法module.exports也是一定能完成的
exports.[function name] = [function name]
moudle.exports= [function name]
所以,在使用上
** moudle.exports.[function name] = [function name] **
** 是完全和 **
** exports.[function name] = [function name] **
** 相等的 **
但是我们通常还是推荐使用exports.[function name],各司其职,代码逻辑清晰
nodejs 一个 js导出两个类
var DB = require('../DB');
function User(user){
this.name=user.name;
this.password=user.password;
this.email=user.email;
}
module.exports.User=User;
//查询用户信息
User.get=function(name,callback){
DB.select("select * from users where username=$1",[name],function(err,result){
callback(err,result);
}
);
}
//存储用户信息
User.prototype.save=function(callback){
//要存入数据库的用户文档
var user={
name:this.name,
password:this.password,
email:this.email
}
DB.add("insert into users(name,password,email)values($1,$2,$3)",[user.name,user.password,user.email],callback);
}
function hello(Hello){
this.id=Hello.id;
this.name=Hello.name;
this.height=Hello.height;
}
module.exports.hello=hello;
hello.get=function(callback){
DB.select("select * from hello",[],function(err,result){
callback(err,result);
}
);
//使用
var User=require("../../datamodules/User");
function hello(req,res){
//打印函数名
var m_FuncJson=baseCall.GetRouteFuncJson(req,res);
User.User.get('xn ',function(err,result){
console.log(result);
res.send(m_FuncJson.call.name);
});
下一篇:优秀的NodeJS开源