npm——web前端的maven
web前端技术目前非常火,web前端已经远远不是我们之前认为的只是做个html页面,搞搞样式美化一下,写写js解决下交互。从我这几周的了解情况来看,web前端的有如下应用场景:
1. 全栈开发
由于node.js的存在,前端除了完成以前人们认知的前端领域外,还可以做后台的工作。但不代表它能替代一些后台语言如Java、PHP、Python等
2. 跨端应用
由于现在移动互联网应用的流行,往往做一个app ,同时需要对Android、IOS、PC端都需要做展示和交互,而且还有小程序端,小程序端现在也是除了微信,还有支付宝、百度等等,这样一来一套前端展示需要适配多种设备和平台,在以前没有好的解决方案的时候,公司就需要有Android、IOS、H5三方面的人,得写三套程序才可以。现在因为有了象uni-app 这类的框架技术,只需写一套就可跨平台(多个小程序平台),跨端(Android、IOS、H5) 。
3. 小程序应用
随着微信平台的发展,现在通常我们做app的时候都需要做微信小程序, 以方便推广。微信小程序开发,官方是提供了框架和开发工具的,但是官方提供的原生框架就犹如JavaEE中的Servlet ,用起来不是很方便,所以就产生了一些第三方框架,主要有增强型的小程序框架如滴滴开源的MPX等,转译型的小程序框架如uni-app等。
前端之所以所以如此繁荣,我觉得离不开Node.js. ,离不开NPM。正是NPM的存在,使得前端具备了代码插件化的能力,NPM已经是世界上最大的JavaScript的包管理器的软件注册表, 在里面我们能找到各类应用的组件和框架。NPM官方提供了一个网站 https://www.npmjs.com.cn/ 用于存放这些组件和框架,又称NPM注册中心,类似Maven的中心仓库。可以通过这个网址在上面查找组件
https://www.npmjs.com/package/package
上面啰嗦了一大堆,下面写点干货,想了下,主要写这么几点:
1. 介绍下npm是如何管理组件的
2. 通过一个小demo演示如何编写一个node.js的组件(或称module) ,并将组件上传至npm 的仓库
3. 如何通过仓库下载依赖,并应用到自己的项目中
1. npm是如何管理组件的
npm最早是用来为node.js来服务的,在node中有模块的概念也称module ,具体可见我之前博文 (Node的模块系统),我还是以Maven做参照来大致介绍下npm , 我们知道java中的maven项目会有一个pom配置文件,上面会有该项目依赖的组件(如组件的id 、所属组织、版本号等信息), 我们称之为dependency 。并且dependency还有传递性,就是一个dependency可能还会用到其他的dependency。那么在npm中对应的这个pom文件就是package.json文件 。下面看看这个package.json文件的结构,看一个例子:
{ "name": "test1", //组件名称,在npm仓库中,name+vesion必须要唯一,要不然没有区分组件 "version": "1.0.0", "description": "test npm ", "main": "index.js", //组件执行的入口,相当于java的main方法 "dependencies": { //依赖的第三方组件 "_huxin_demo1@1.0.0@huxin_demo1": "^1.0.0", "huxin_demo1": "^1.0.0" }, "devDependencies": {}, //表示在开发时依赖的组件,这个有点象maven依赖中的scope=test的情况 "scripts": { "test": "echo hello world" //这个是npm用于测试组件的,比如组件下载下来,可以通过 npm run test 来简单测下看组件是否可调用 }, "repository": { "type": "git", "url": "https://gitee.com/huxinstudy_admin/npm-test.git" //当前组件对应的git仓库地址,只是一个描述性属性 }, "keywords": [ //这应该只是用于搜索组件用 "npm", "run", "test" ], "author": "huxin", "license": "ISC" //组件的开源方式 }
更详细的内容,可参照https://www.npmjs.cn/files/package.json/
2. 通过一个小demo演示如何编写一个node.js的组件(或称module) ,并将组件上传至npm 的仓库
首先明确这个demo是为了写一个组件即module,这样以后其他项目可以依赖这个组件达到代码复用的效果,具体是以下几个步骤:
(1) 新建一个目录,并cd进入这个目录
(2) npm init
命令创建 package.json
文件
{ "name": "com.dxww", "version": "1.0.0", "description": "npm 测试", "main": "index.js", "scripts": { "test": "node index.js" }, "repository": { "type": "git", "url": "https://gitee.com/huxinstudy_admin/npm-test.git" }, "keywords": [ "npm", "test" ], "author": "huxin", "license": "ISC" }
(3) 编写组件逻辑代码
创建一个index.js文件, 并且代码中引用了http组件 , 并且这个index.js 文件在package.json中配置为入口执行文件,即别的项目引用了组件,就会执行这个文件的代码, 这个代码逻辑就是利用node中的http组件创建一个web服务,监听4000端口,访问 http://{主机ip}:4000 会在页面上输出: Hello World
const http = require('http'); const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World \n'); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`);
});
(4) 到 npm 官网 注册个帐号 , 这是我个人在官方仓库的页面,可以看到我2018年就尝试传过一个demo
(5) 发布组件到 npm官方仓库
先执行 npm login 完成登录验证, 再执行 npm publish 即可
发布完,在个人页面上就能看到组件了:
3. 如何通过仓库下载依赖,并应用到自己的项目中
如何使用涉及到 npm对模块的全局安装和本地安装的问题,即要先要把模块下载到本地才能使用,分四种方式:
npm install moduleName # 安装模块到项目目录下 npm install -g moduleName # -g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看 npm config prefix 的位置。 npm install --save moduleName # --save 的意思是将模块安装到项目目录下,并在package文件的dependencies节点写入依赖。 npm install --save-dev moduleName # --save-dev 的意思是将模块安装到项目目录下,并在package文件的devDependencies节点写入依赖。
使用 npm uninstall -g 可以删除以前的下载 。本地全局仓库可通过 npm root -g 命令进行查看 , 例如我机器上是:
/usr/local/Cellar/nvm/0.37.2/versions/node/v14.17.0/lib/node_modules
(1) 还是需要用 npm init 来完成项目的创建,也就是在项目根目录下生成package.json文件
(2) 如果npm install不加 -g参数,那么组件只会下载到当前目录,会在当前目录下生成 node_modules 目录, 这里为了把组件加入到package.json的dependencies中,我们执行
npm install --save com.dxww
这时会发现目录下package.json文件发生变化了,多了标红的这一行,
{ "name": "test1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "huxin", "license": "ISC", "dependencies": { "com.dxww": "^1.0.0" }
并且还多了个 package-lock.json文件 ,这个文件的作用在这顺便也提一下:
package.json
里面定义的是版本范围(比如^1.0.0
),具体跑npm install
的时候安的什么版本,要解析后才能决定,这里面定义的依赖关系树,可以称之为逻辑树(logical tree)。
node_modules
文件夹下才是npm实际安装的确定版本的东西,这里面的文件夹结构我们可以称之为物理树(physical tree)。
安装过程中有一些去重算法,所以你会发现逻辑树结构和物理树结构不完全一样。
package-lock.json
可以理解成对结合了逻辑树和物理树的一个快照(snapshot),里面有明确的各依赖版本号,实际安装的结构,也有逻辑树的结构。
(3) 对组件进行调用
创建一个新的目录test1,在tes1目录下执行 npm install -g com.dxww 或者 npm install com.dxww , 然后在该上录下编写一个test.js文件
var demo1 = require("dxww.com") //require 大致相当于java的import
然后在命令行下执行 node test.js , 会发现本地起了个服务并监听3000端口 ,控制台输出:
Server running at http://127.0.0.1:3000/
用浏览器访问:
这里有个点要注意下:如果是全局安装module时, 用node执行时会出现找不到module的问题,这个其实跟node 查找依赖的规则有关,一般会先找地目录,然后去本地全局仓库去找,但有时候和node的安装方式有关,它会找不到,解决的办法就设置一个全局变量就可以了,如果是mac ,就在修改用户目录下的 .bash_profile 文件 ,增加
export NODE_PATH={npm root -g的输出目录名}
也就是要设置 NODE_PATH环境变量指向npm 的本地全局仓库目录