Node.js初学者指南 第三部分





朋友们,美好的一天!



我将继续发布此Node.js教程的翻译



其他部分:



第1

部分第2

部分第3

部分第4部分



在Node.js中获取用户输入的数据



如何使Node.js程序具有交互性?



为此,Node.js的版本7引入了readline模块:它用于从流中获取数据以进行读取,例如process.stdin在执行Node.js程序期间的命令行。



const readline = require('readline').createInterface({
    input: process.stdin,
    output: process.stdout
})

readline.question(`What is your name?`, name => {
    console.log(`Hi ${name}!`)
    readline.close()
})


此代码要求用户名,在用户键入并单击后enter,将显示问候语。



该方法question()将第一个参数(问题)打印到控制台并等待用户的响应。当按下时enter,将执行回调函数。



在此回调中,我们关闭interface readline



readline包含其他方法,您可以在文档中阅读这些方法。



如果需要提示输入密码,最好使用符号而不是显式地返回它*



一种方法是使用readline-sync软件包,该软件包易于理解且易于配置。



Inquirer.js 软件包提供了更完整和抽象的解决方案



我们在帮助下进行安装npm install inquirer并按以下方式使用它:



const inquirer = require('inquirer')

const questions = [
    {
        type: 'input',
        name: 'name',
        message: `What's your name?`
    }
]

inquirer.prompt(questions).then(answers => {
    console.log(`Hi ${answers['name']}!`)
})


Inquirer.js允许您做很多很酷的事情,例如建议多项选择,提供单选按钮,要求确认等。



众所周知,它是内置解决方案的替代方法,但是如果您打算将用户体验提升到一个新水平,那么Inquirer.js是最好的解决方案。



使用导出扩展Node.js文件功能



Node.js具有内置的模块化系统。



Node.js文件可以从其他Node.js文件导入功能。



当您要导入某些内容时,可以使用const library = require('./library')

导入功能导出library.js到当前目录中的文件中。



在此文件中,必须先导出功能,然后才能将其导入另一个文件。



默认情况下,文件中定义的任何其他对象或变量都是私有的(私有),不能在其他文件中使用。



这就是模块化系统module.exports提供的接口允许我们执行的操作 当您分配对象或功能作为对象的新属性时



exports,将它们导出,然后可以将它们导入应用程序中或其他应用程序中的其他位置。



这可以通过两种方式完成。



第一种方法是分配一个值module.exports,它是模块化系统提供的默认对象。此方法仅允许您导出此对象:



const car = {
    brand: 'Ford',
    model: 'Fiesta'
}

module.exports = car 

//   
const car = require('./car')


第二种方法是将导出的对象添加为对象的属性exports此方法使您可以导出许多对象,函数或数据:



const car = {
    brand: 'Ford',
    model: 'Fiesta'
}

exports.car = car


或者



exports.car = {
    brand: 'Ford',
    model: 'Fiesta'
}


要在另一个文件中使用该对象,必须链接到导入:



const items = require('./items')
items.car 


要么



const car = require('./items').car 


module.exports 之间有什么区别exports



第一个导出引用的对象,第二个导出对象的属性。



npm软件包管理器简介



npm简介


npm是默认的Node.js程序包管理器。



截至2017年1月,npm拥有超过350,000个程序包,使其成为地球上单一编程语言中最大的代码存储库,您可以放心,几乎所有程序包都可以执行。



一切都始于在Node.js中下载和管理依赖项,但是很快该工具开始在开发应用程序客户端方面被积极使用。



npm做几件事。



npm的替代方法是yarn



载入中


npm管理项目依赖项的加载。



如果项目中存在文件,则package.json启动npm install会将项目所需的所有内容安装到node_modules创建的目录中(如果该目录不存在)。



可以使用安装特定的软件包npm install <package-name>



通常,软件包的安装带有标志:



  • --save-安装该软件包并将有关它的条目添加到文件的依赖项部分 package.json
  • --save-dev-安装该软件包并将有关它的条目添加到文件的devDependencies部分 package.json


主要的区别是devDependencies用于开发目的(例如测试),而依赖关系在生产中使用(构建项目时)。



更新包


使用进行更新很容易npm update



npm将检查所有软件包中是否有符合规定限制的新版本。



您还可以更新特定的软件包:npm update <package-name>



版本控制


除了标准下载外,npm还支持版本控制,因此您可以指定软件包的任何特定版本,或请求更新或较旧的版本。



您通常会发现一个库仅与另一个库的某个(主要)版本兼容。



并且还包含了很长时间未修复的最新版本的错误。



版本控制还有助于团队开发,因为每个团队成员都知道在更新文件之前要使用哪个版本package.json



在所有这些情况下,版本控制都是有用的;在这方面,npm它遵循公认的标准。



执行任务


package.json支持使用格式指定要在终端中执行的命令的格式npm run <task-name>



例如:



{
    "scripts": {
        "start-dev": "node lib/server-development",
        "start": "node lib/server-production"
    },
}


使用此功能运行Webpack的常见做法是:

{
    "scripts": {
        "watch": "webpack --watch --progress --colors --config webpack.conf.js",
        "dev": "webpack --progress --colors --config webpack.conf.js",
        "prod": "NODE_ENV=production webpack -p --config webpack.conf.js"
    },
}


这可以代替以下一系列容易忘记或容易出错的长命令:



npm run watch 
npm run dev 
npm run prod 




npm在哪里安装软件包?



使用安装软件包时,npm可以在两种安装类型之间进行选择:



  • 本地
  • 全球


默认情况下,当您输入npm install例如:



npm install lodash 


程序包将安装到node_modules当前目录中的文件夹中。



安装后,npm将o记录添加lodash当前目录中dependenciesfile 部分package.json



对于全局安装,请使用标志-g



npm install -g lodash 


在全局安装中,该软件包不是安装在当前目录中,而是安装在全局目录中。



但是到底在哪里?



要确定这一点,您需要运行命令npm root -g



在macOS或Linux上,此目录可以是 /usr/local/lib/node_modules在Windows上C:\Users\YOU\AppData\Roaming\npm\node_modules



当用于nvmNode.js版本控制时,此目录可能不同。



如何使用已安装的软件包?



如何使用安装在文件夹中node_modules或全局安装的软件包。



假设您使用安装了lodash流行的JavaScript帮助器库npm install lodash



此命令将安装lodash到本地目录node_modules



要使用该程序,您需要使用require以下命令导入软件包



const _ = require('lodash')


如果包是可执行文件(文件)怎么办?



在这种情况下,可执行文件将放置在目录中node_modules/.bin/



使用Cowsay库可以很容易地证明这一点



该程序包提供了一个命令行程序,当执行时,母牛(和其他动物)“说话”。



通过安装软件包时npm install cowsay,将安装软件包本身及其一些依赖项:







该文件夹.bin被隐藏,并包含指向二进制数据的符号链接:







如何执行它们?



您当然可以键入./node_modules/.bin/cowsay并且它应该可以工作,但是npm中包含的npx(从5.2开始)是最好的选择。你只是做npx cowsay然后npx会自动找到该文件:





母牛说“带我离开这里”。



Package.json手册



在使用JavaScript时,在与JavaScript项目,Node.js或应用程序的前端进行交互时,您可能会遇到package.json



这是什么?你应该对他有什么了解?那你能做什么呢?



package.json是一种项目宣言。他可以做很多彼此无关的事情。例如,它可以是所用工具设置的主文件。它还存储所有已安装软件包的名称和版本(此信息用于npmyarn)。



档案结构


这是一个例子package.json



{}


如您所见,它是空的。package.json内容没有要求。唯一的要求是其格式(JSON),否则程序将无法访问它。



如果您正在创建计划通过其分发的Node.js程序包npm,则情况会发生巨大变化,您需要添加属性以帮助其他人使用该程序包。我们待会再看。



这是另一个例子package.json



"name": "test-project"


在这里,我们定义了与相同目录中的包或应用程序的名称package.json



这是package.json从Vue.js应用程序中借来的一个更复杂的示例



{
  "name": "test-project",
  "version": "1.0.0",
  "description": "A Vue.js project",
  "main": "src/main.js",
  "private": true,
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "unit": "jest --config test/unit/jest.conf.js --coverage",
    "test": "npm run unit",
    "lint": "eslint --ext .js,.vue src test/unit",
    "build": "node build/build.js"
  },
  "dependencies": {
    "vue": "^2.5.2"
  },
  "devDependencies": {
    "autoprefixer": "^7.1.2",
    "babel-core": "^6.22.1",
    "babel-eslint": "^8.2.1",
    "babel-helper-vue-jsx-merge-props": "^2.0.3",
    "babel-jest": "^21.0.2",
    "babel-loader": "^7.1.1",
    "babel-plugin-dynamic-import-node": "^1.2.0",
    "babel-plugin-syntax-jsx": "^6.18.0",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-plugin-transform-vue-jsx": "^3.5.0",
    "babel-preset-env": "^1.3.2",
    "babel-preset-stage-2": "^6.22.0",
    "chalk": "^2.0.1",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.28.0",
    "eslint": "^4.15.0",
    "eslint-config-airbnb-base": "^11.3.0",
    "eslint-friendly-formatter": "^3.0.0",
    "eslint-import-resolver-webpack": "^0.8.3",
    "eslint-loader": "^1.7.1",
    "eslint-plugin-import": "^2.7.0",
    "eslint-plugin-vue": "^4.0.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "file-loader": "^1.1.4",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "html-webpack-plugin": "^2.30.1",
    "jest": "^22.0.4",
    "jest-serializer-vue": "^0.3.0",
    "node-notifier": "^5.1.2",
    "optimize-css-assets-webpack-plugin": "^3.2.0",
    "ora": "^1.2.0",
    "portfinder": "^1.0.13",
    "postcss-import": "^11.0.0",
    "postcss-loader": "^2.0.8",
    "postcss-url": "^7.2.1",
    "rimraf": "^2.6.0",
    "semver": "^5.3.0",
    "shelljs": "^0.7.6",
    "uglifyjs-webpack-plugin": "^1.1.1",
    "url-loader": "^0.5.8",
    "vue-jest": "^1.0.2",
    "vue-loader": "^13.3.0",
    "vue-style-loader": "^3.0.1",
    "vue-template-compiler": "^2.5.2",
    "webpack": "^3.6.0",
    "webpack-bundle-analyzer": "^2.9.0",
    "webpack-dev-server": "^2.9.1",
    "webpack-merge": "^4.1.0"
  },
  "engines": {
    "node": ">= 6.0.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": ["> 1%", "last 2 versions", "not ie <= 8"]
}


这里有很多:



  • name -应用程序/程序包名称
  • version -应用程序/软件包版本
  • description -应用程序/程序包的简短描述
  • main -应用程序的主文件(入口点)
  • private-该值true可防止将应用程序意外发布到npm
  • scripts -一组可以运行(执行)的脚本(命令)
  • dependencies -项目依赖
  • devDependencies -仅在开发期间使用的项目依赖项
  • engines -运行应用程序/程序包的版本
  • browserlist -支持的浏览器(及其版本)


使用所有这些属性npm



物产


在本节中,我们将讨论您可以使用的一些属性。我们将使用“程序包”一词,但是对于应用程序来说,大部分内容也是正确的。



需要大多数属性才能将程序包发布到npm,有些属性需要与程序包进行交互。



名称(名称)


指定包的名称。



例如:



"name": "test-project"


名称不能超过214个字符,不能包含空格,并且只能由小写字母(小写),连字符(-)和下划线(_)组成。



这是因为在发布npm时会根据其名称分配一个URL。



如果该软件包在GitHub上发布,则优良作法是链接到存储库。



作者


标识软件包的作者。



例如:



{
    "author": "Joe <joe@whatever.com> (https://whatever.com)"
}


或像这样:



{
  "author": {
    "name": "Joe",
    "email": "joe@whatever.com",
    "url": "https://whatever.com"
  }
}


合作者


指定软件包的一个或多个贡献者。此属性是字符串数组。



例如:



{
  "contributors": ["Joe <joe@whatever.com> (https://whatever.com)"]
}


或像这样:



{
  "contributors": [
    {
      "name": "Joe",
      "email": "joe@whatever.com",
      "url": "https://whatever.com"
    }
  ]
}


失误


定义到问题跟踪器的链接,通常是GitHub上的问题跟踪器。



例如:



{
  "bugs": "https://github.com/whatever/package/issues"
}


主页


定义主页的地址。



例如:



{
  "homepage": "https://whatever.com/package"
}




确定软件包的当前版本。



例如:



"version": "1.0.0"


此属性遵循语义版本控制标准。这意味着它必须始终由点号分隔的三个数字组成x.x.x



第一个数字是主要版本,第二个是次要版本,第三个是补丁。



每个数字都有特定的含义:修复错误的更新是一个修补程序,向后兼容更改的发布是次要版本,而主要版本可能意味着与先前版本不兼容的更改。



执照


指定软件包的许可证。



例如:



"license": "MIT"


关键词


此属性是与包相关联的一组关键字。



例如:



"keywords": [
  "email",
  "machine learning",
  "ai"
]


他们帮助人们找到包裹。



描述


定义包装的简短描述。



例如:



"description": "A package to work with strings"


将包发布到npm给定的属性时,它可以帮助人们了解其用途。



资料库


确定软件包源代码的位置。



例如:



"repository": "github:whatever/testing",


注意前缀github还有其他类似的服务:



"repository": "gitlab:whatever/testing",


"repository": "bitbucket:whatever/testing",


您还可以定义版本控制系统:



"repository": {
  "type": "git",
  "url": "https://github.com/whatever/testing.git"
}


您可以指定多个版本控制系统:



"repository": {
  "type": "svn",
  "url": "..."
}


主要


定义包的主文件(入口点)。



将包导入应用程序时,应用程序将在此文件中查找导出的模块。



例如:



"main": "src/main.js"


私人的


将此属性设置为值true可以防止程序包意外发布到npm



例如:



"private": true 


剧本


定义可以执行(运行)的命令(脚本)列表。



例如:



"scripts": {
  "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
  "start": "npm run dev",
  "unit": "jest --config test/unit/jest.conf.js --coverage",
  "test": "npm run unit",
  "lint": "eslint --ext .js,.vue src test/unit",
  "build": "node build/build.js"
}


这些脚本是命令行应用程序。您可以使用npm run XXXX来运行它们yarn run XXXX,其中XXXX命令名是。例如:npm run dev



您可以使用任何名称作为命令名称,脚本将执行您在其中指定的任何操作。



依存关系


定义软件包依赖关系列表。



使用npm或yarn安装软件包时:



npm install <PACKAGENAME>
yarn add <PACKAGENAME>


该软件包的记录将自动添加到相关属性中。



例如:



"dependencies": {
  "vue": "^2.5.2"
}


devDependencies


为开发目的定义依赖项列表。



它们与有所不同dependencies,因为它们仅安装在开发人员的计算机上,无法投入生产。



使用npm或yarn安装软件包时:



npm install --save-dev <PACKAGENAME>
yarn add --save-dev <PACKAGENAME>


关于它的记录将自动添加到考虑的属性中。



例如:



"devDependencies": {
  "autoprefixer": "^7.1.2",
  "babel-core": "^6.22.1"
}


引擎


确定程序包/应用程序在哪个版本的Node.js或其他工具上运行。



例如:



"engines": {
  "node": ">= 6.0.0",
  "npm": ">= 3.0.0",
  "yarn": "^0.13.0"
}  


浏览器清单


定义受支持的浏览器(及其版本)的列表。Babel,Autoprefixer和其他工具使用此信息来创建polyfill,并确保与指定的浏览器兼容。



例如:



"browserslist": [
  "> 1%",
  "last 2 versions",
  "not ie <= 8"
]    


此设置意味着您要支持CanIUse统计信息中超过1%的人使用的所有浏览器的两个最新版本,但IE8和更早的版本除外。



特殊性质


package.json可以包含Babel,ESLint等工具的特殊属性。



每个工具都有其自己的属性,例如eslintConfigbabel等等。有关特殊属性的详细信息,请参见相应的文档。



套件版本


在上面的示例中,您可能已经注意到以下条目:~3.0.0^0.13.0他们的意思是什么?我还可以使用其他哪些版本说明符?



这些说明符用于定义更新条件。



规则如下:



  • ~-写~0.13.0意味着只允许补丁更新,即 发布0.13.1有效,但发布0.14.0无效
  • ^-写^0.13.0意味着允许补丁和较小的更新
  • *-记录*表示允许任何更新
  • > -允许任何新版本
  • >= -允许类似或更新的版本
  • <= -可接受类似或较旧的版本
  • < -允许使用任何旧版本


以下是一些其他规则:



  • 没有主角-只允许指定的版本
  • latest -仅允许使用最新版本


这些字符可以通过多种方式组合,例如:1.0.0 || >=1.1.0 <1.2.0



感谢您的关注。



未完待续…



All Articles