server.js
//常规的书写框架
// const http = require('http')
// const app = http.createServer((req, res) => {
// })
// app.listen(8080, () => {
// console.log('server at http://localhost:8080')
// })
//简写
const fs = require('fs')
require('http')
.createServer((req, res) => {
const urlStr = req.url
console.log(urlStr)
//简单的路由,理论上就是对每一个请求进行拦截并且判断
switch (urlStr) {
case '/':
res.end('hello')
break
case '/home':
fs.readFile('./home.html', (err, content) => {
res.end(content)
})
break
case '/app.js':
res.end('app.js')
break
case '/p1.png':
fs.readFile('../p1.png', (err, content) => {
res.end(content)
})
break
default:
res.end('error')
}
}).listen(8080, () => {
console.log('server at http://localhost:8080')
})
home.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
home.html
<img src="../p1.png" alt="">
<script src="../app.js">script>
body>
html>
app.js
console.log('hello')
server.js
const fs = require('fs')
require('http')
.createServer((req, res) => {
const urlStr = req.url
console.log(urlStr)
const file = fs.readFileSync(`.${urlStr}`)
res.end(file)
}).listen(8080, () => {
console.log('server at http://localhost:8080')
})
npm i mime
)const mime = require('mime')
const fs = require('fs')
require('http')
.createServer((req, res) => {
const urlStr = req.url
//使用mime的方法
const type = mime.getType(urlStr.split('.'[1]))
console.log(type)
//书写请求头
res.writeHead(200, {
'content-type': type
})
const file = fs.readFileSync(`.${urlStr}`)
res.end(file)
}).listen(8080, () => {
console.log('server at http://localhost:8080')
})
server.js
const http = require('http')
const readStaticFile = require('./readStaticFile')
const path = require('path')
//这里必须使用异步
const server = http.createServer(async (req, res) => {
let urlStr = req.url
//__dirname表示当前代码所在的物理路径,从根目录开始,然后追加后面的路径
let filePathName = path.join(__dirname, '/public', urlStr)
console.log(filePathName)
//必须等待异步函数传值
let { data, mimeType } = await readStaticFile(filePathName)
res.writeHead(200, {
'content-type': `${mimeType};charset=utf-8`
})
res.write(data)
res.end()
})
server.listen(8080, () => {
console.log('server at http://localhost:8080...')
})
readStaticFile.js
const path = require('path')
const mime = require('mime')
const fs = require('fs')
//封装一个读取文件的方法
function myReadFile(fileName) {
console.log(fileName)
//防止异步出错,这里自己封装一个Promise函数,如果成功就会自己调用里面的回调函数
return new Promise((resolve, reject) => {
fs.readFile(fileName, (err, data) => {
//如果读取错误,返回提示
if (err) {
// reject('您访问的是是一个文件夹')
resolve('您访问的是一个文件夹')
} else {
resolve(data)
}
})
})
}
async function readStaticFile(filePathName) {
//获取拓展名
let ext = path.parse(filePathName).ext
//获取文件类型
let mimeType = mime.getType(ext) || 'text/html'
let data
//判断某个文件或者文件夹是否存在
if (fs.existsSync(filePathName)) {
if (ext) {
// await myReadFile(filePathName)
// .then(result => data = result)
// .catch(err => data = err)
data = await myReadFile(filePathName)
} else {
// await myReadFile(filePathName)
// .then(result => data = result)
// .catch(err => data = err)
data = await myReadFile(path.join(filePathName, '/index.html'))
//这里有数据说明获取到了
// console.log(data)
}
} else {
console.log('file not found')
}
return { mimeType, data }
}
module.exports = readStaticFile
Yarn 对你的代码来说是一个包管理器。它可以让你使用并分享全世界开发者的(例如 JavaScript)代码。 Yarn 能够快速、安全、并可靠地完成这些工作,所以你不用有任何担心。
通过Yarn你可以使用其他开发者针对不同问题的解决方案,使自己的开发过程更简单。
代码通过包(package) (或者称为 模块(module)) 的方式来共享。 一个包里包含所有需要共享的代码,以及描述包信息的文件,称为 package.json。
npm i -g yarn
yarn --version
yarn init -y
yarn add [package]
yarn add [package]@[version]
yarn add[package]@[tag]
分别添加到 devDependencies、peerDependencies 和 optionalDependencies 类别中:
yarn add [package] --dev
yarn add [package] --peer
yarn add [package] --optional
devDependencies、peerDependencies 和 optionalDependencies区别
在一个Node.js项目中,package.json几乎是一个必须的文件,它的主要作用就是管理项目中所使用到的外部依赖包,同时它也是npm命令的入口文件。
npm 目前支持以下几类依赖包管理:
dependencies
应用依赖,或者叫做业务依赖,这是我们最常用的依赖包管理对象!它用于指定应用依赖的外部包,这些依赖是应用发布后正常执行时所需要的,但不包含测试时或者本地打包时所使用的包。
devDependencies
开发环境依赖,仅次于dependencies的使用频率!它的对象定义和dependencies一样,只不过它里面的包只用于开发环境,不用于生产环境,这些包通常是单元测试或者打包工具等,例如gulp, grunt, webpack, moca, coffee等。
peerDependencies
同等依赖,或者叫同伴依赖,用于指定当前包(也就是你写的包)兼容的宿主版本。如何理解呢? 试想一下,我们编写一个gulp的插件,而gulp却有多个主版本,我们只想兼容最新的版本,此时就可以用同等依赖(peerDependencies)来指定。
{
"name": "gulp-my-plugin",
"version": "0.0.1",
"peerDependencies": {
"gulp": "3.x"
}
}
optionalDependencies
可选依赖,如果有一些依赖包即使安装失败,项目仍然能够运行或者希望npm继续运行,就可以使用optionalDependencies。另外optionalDependencies会覆盖dependencies中的同名依赖包,所以不要在两个地方都写。
bundledDependencies / bundleDependencies
打包依赖,bundledDependencies是一个包含依赖包名的数组对象,在发布时会将这个对象中的包打包到最终的发布包里。
yarn upgrade [package]
yarn upgrade [package]@[version]
yarn upgrade [package]@[tag]
yarn remove [package]
yarn
或者
yarn install
yarn config get registry
const express = require('express')
//express框架的基本使用
const app = express()
//使用use解析是从上到下,如果之前匹配了就不会往下匹配
//回调函数又被称之为中间件,中间件可以挂载多个,但是多个中间件需要前面的中间件使用next函数
//上面有关中间件的描述被称之为中间件栈
app.use('/api', (req, res, next) => {
res.send('world')
next()
}, (req, res) => {
console.log(1)
})
//中间件栈
const middlewares = [
(req, res, next) => {
console.log(0)
next()
}, (req, res, next) => {
console.log(1)
next()
}
]
//使用中间件栈
app.use('/list', middlewares)
app.use('/', (req, res) => {
console.log(0)
//send取代了write和end函数
res.send('hello')
})
app.listen(8080, () => {
console.log('server at http://localhost:8080...')
})
server.js
const express = require('express')
const router = require('./router/index')
var bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
//app.use如果不写路径而直接使用中间件,表示接受所有路径?
app.use('/', router)
app.listen(8080, () => {
console.log('server at http://localhost:8080...')
})
router/index.js
const express = require('express')
//express路由中间件
const router = express.Router()
//注意这个不是从上往下解析,而是按照规则解析
router.get('/', (req, res, next) => {
res.send('hello')
})
router.get('/index', (req, res, next) => {
//获取前端数据--GET--query对象,是以json类型
const query = req.query
console.log(query)
// res.send(query)
//表示返回json数据类型
res.json(query)
})
router.post('/index', (req, res, next) => {
//获取前端数据--POST--body
//为了解析POST方式请求的数据,我们使用一个第三方插件--body-parser
//yarn add body-parser -S
const data = req.body
console.log(data)
res.send(data)
})
//除了get和put,还有其他几种重要的语义化请求
//解析这些方式主要还是req.body
//get--请求数据,put--覆盖式修改,post--添加数据,patch--增量式修改,delete--删除
router.put('/index', (req, res, next) => {
})
router.patch('/index', (req, res, next) => {
})
router.delete('/index', (req, res, next) => {
})
module.exports = router
controller/index.js
const list = (req, res, next) => {
res.send('hello')
}
//暴露方法
exports.list = list
router/index.js
const express = require('express')
const { list } = require('../controller')
const router = express.Router()
router.get('/', list)
module.exports = router
server.js
const express = require('express')
const router = require('./router/index')
var bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
//app.use如果不写路径而直接使用中间件,表示接受所有路径?
app.use('/', router)
app.listen(8080, () => {
console.log('server at http://localhost:8080...')
})
页面渲染(render)
项目准备,使用express中间件托管静态资源:
server.js
const express = require('express')
const router = require('./router/index')
var bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
//利用 Express 托管静态文件
app.use(express.static('./public'))
//app.use如果不写路径而直接使用中间件,表示接受所有路径?
app.use('/', router)
app.listen(8080, () => {
console.log('server at http://localhost:8080...')
})
const list = (req, res, next) => {
//渲染数据相当于服务端渲染
let data = ''
for (var i = 0; i < 100; i++) {
data += ` ${i}`
}
data += ''
res.send(data)
}
//暴露方法
exports.list = list
common.js
$.ajax({
url: 'api/list',
success(result) {
//相当于在前端渲染
let html = ''
$.each(result.data, (index, value) => {
html += '' + value + ''
})
html += ""
$('#list').html(html)
}
})
list.js
const list = (req, res, next) => {
//服务端提供数据
// let data = '{"ret":true,"data":'
let dataObj = {
ret: true,
data: []
}
for (var i = 0; i < 100; i++) {
dataObj.data.push('line' + i)
}
res.send(dataObj)
}
//暴露方法
exports.list = list
官网:http://aui.github.io/art-template/zh-cn/index.html
文档:http://aui.github.io/art-template/zh-cn/docs/
npm i art-template express-art-template -S
server.js
const express = require('express')
const router = require('./router/index')
var bodyParser = require('body-parser')
const path = require('path')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
//利用 Express 托管静态文件
app.use(express.static('./public'))
// view engine setup
app.engine('art', require('express-art-template'));
app.set('view options', {
debug: process.env.NODE_ENV !== 'production',
// 是否开启对模板输出语句自动编码功能。为 false 则关闭编码输出功能
// escape 可以防范 XSS 攻击
escape: true,
});
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'art');
//app.use如果不写路径而直接使用中间件,表示接受所有路径
app.use('/', router)
app.listen(8080, () => {
console.log('server at http://localhost:8080...')
})
views/list.art
{
"ret":true,
"data":{{dataArray}}
}
controller/index.js
const list = (req, res, next) => {
let dataArray = []
for (var i = 0; i < 100; i++) {
dataArray.push('line' + i)
}
//使用art-template渲染,注意不要去写.art
res.render('list', {
//下面两种写法都可以解构
// data: dataArray
dataArray
})
}
//暴露方法
exports.list = list
①html需要引入这个实时编译
<script src="./js/template-web.js">script>
③server.js要做简单修改
app.set('view options', {
debug: process.env.NODE_ENV !== 'production',
// 是否开启对模板输出语句自动编码功能。为 false 则关闭编码输出功能
// escape 可以防范 XSS 攻击
escape: false,//这里是一个坑
});
④修改list.art
{
"ret":true,
"data":{{data}}
}
⑤controller/index.js
const list = (req, res, next) => {
let dataArray = []
for (var i = 0; i < 100; i++) {
dataArray.push('line' + i)
}
//使用art-template渲染,注意不要去写.art
res.set('content-type', 'application/json;charset=utf-8')
res.render('list', {
data: JSON.stringify(dataArray)
})
}
//暴露方法
exports.list = list
common.js
$.ajax({
url: 'api/list',
success(result) {
//这里用到art-template语法
let templateStr =
`
{{each data}}
-
{{ $value }}
{{/each}}
{{x}}
`
//在浏览器端实时渲染
let str = template.render(templateStr, { data: result.data, x: 'hello' })
$('#list').html(str)
}
})
controller/index.js
var template = require('art-template');
const fs = require('fs');
const path = require('path')
const list = (req, res, next) => {
let dataArray = []
for (var i = 0; i < 100; i++) {
dataArray.push('line' + i)
}
var html = template(path.join(__dirname, '../views/list-html.art'), {
data: dataArray
});
// console.log(html)
fs.writeFile(path.join(__dirname, '../public/list.html'), html, (err) => { })
res.send('pages has been compiled')
}
//暴露方法
exports.list = list
list-html.art
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
<ul>
{{each data}}
<li>{{$value}}li>
{{/each}}
ul>
body>
html>
list.js
let dataArray = []
for (var i = 0; i < 100; i++) {
dataArray.push('line' + i)
}
module.exports = {
dataArray
}