Spring 2019 。 Ric Huang
Web Programming 的學習一但開始走到後端,就會逐漸脫離只是「學習程式語言」的範疇,而開始要學習許多網路服務相關的知識、架構、工具、甚至是生態、歷史等等。
Again, 這部分非常的多且雜,但網路上的學習資源也非常的多,所以重點是各位要有求知的企圖心,才能自我從找資料、動手實驗、挑戰專題… 這個循環中獲得真正的成長。
Usage: npm <command>
where <command> is one of:
access, adduser, audit, bin, bugs, c, cache, ci, cit,
clean-install, clean-install-test, completion, config,
create, ddp, dedupe, deprecate, dist-tag, docs, doctor,
edit, explore, get, help, help-search, hook, i, init,
install, install-ci-test, install-test, it, link, list, ln,
login, logout, ls, org, outdated, owner, pack, ping, prefix,
profile, prune, publish, rb, rebuild, repo, restart, root,
run, run-script, s, se, search, set, shrinkwrap, star,
stars, start, stop, t, team, test, token, tst, un,
uninstall, unpublish, unstar, up, update, v, version, view,
whoami
create a package.json file
Generate a plain old package.json using legacy init:
$ mkdir my-npm-pkg && cd my-npm-pkg
$ git init
$ npm init
# If you want to skip questions, use "npm init -y"
$ npm init react-app ./my-react-app
mkdir webpack-test1 && cd webpack-test1 git init npm init -y ls -al
# alias 'npm i'
npm install (with no args, in package dir)
npm install [<@scope>/]<name>
npm install [<@scope>/]<name>@<tag>
npm install [<@scope>/]<name>@<version>
npm install [<@scope>/]<name>@<version range>
npm install <git-host>:<git-user>/<repo-name>
npm install <git repo url>
npm install <tarball file>
npm install <tarball url>
npm install <folder>
npm install webpack webpack-cli --save-dev ls -al
-P, --save-prod: Package will appear in your dependencies. This is the default unless -D or -O are
-D, --save-dev: Package will appear in your devDependencies.
-O, --save-optional: Package will appear in your optionalDependencies.
--no-save: Prevents saving to dependencies
-S, --save(deprecated after npm 5.0): Saved to dependencies
Note, npm install installs the package as specified in package.json or package-lock.json
npm install <packageName> installs <packageName> in the local directory
$ npm audit fix
cd ~/projects/package-dir # go into the package directory
npm link # creates global link
cd ~/projects/linked-dir # go into some other package directory.
npm link packageName # link-install the package
# packageName is what specifed in 'package.json: name'
cd ~/projects/link-dir
npm link ../packageName
$ npm ls # list installed packages
$ npm publish # Publishes a package to the registry so that it can be installed by name
$ npm uninstall # uninstall package
$ npm unpublish # Remove a package from the registry
$ npm update # Update a package
$ npm version # Bump a package version
nvm –- Simple bash script to manage multiple active node.js versions
Alternatively, there is an interactive node.js version manager: n // created by 'tj' 大神
mkdir simple-node-example && cd simple-node-example git init npm init -y
# edit 'src/index.js'; put a console.log() node src/index.js # edit 'package.json'; add "start": "nodemon src/index.js" npm start # Try to modify 'src/index.js' to see what happens
npm install @babel/core @babel/node @babel/preset-env --save-dev # # Modify 'package.json' with: # "start": "nodemon --exec babel-node src/index.js", # # edit a file '.babelrc'; add the following: # { # "presets": [ # "@babel/preset-env" # ] # } # npm start # Nothing changes, but now you run node.js with babel #
npm install dotenv
# Create a file '.env'; add this line
MY_SECRET=mysupersecretpassword
// In 'src/index.js', change it to:
import 'dotenv/config';
import saySomething from './my-other-file.js';
// Create a file 'src/my-other-file.js'. Add
console.log("Hello Ric");
console.log(process.env.MY_SECRET);
npm install bcrypt
const bcrypt = require('bcrypt');
const saltRounds = 10;
const myPassword = 'password1';
const testPassword = 'password2';
const myHash ='$2a$10$fok18OT0R/cWoR0a.VsjjuuYZV.XrfdYd5CpDWrYkhi1F0i8ABp6e'; // for test purpose
bcrypt.hash(myPassword, saltRounds).then(function (hash) {
console.log(hash); });
// Verify password
bcrypt.compare(myPassword, myHash).then(function (res) {
console.log(res); });
bcrypt.compare(testPassword, myHash).then(function (res) {
console.log(res); });
...render() {
return ...<Form onSubmit={handleSubmit}>...
}
=> We will cover this later
import express from 'express';
const app = express();
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(3000, () =>
console.log('Example app listening on port 3000!'),
);
# Add this line to .env
PORT=3000
// Modify index.js
const port = process.env.PORT;
app.listen(port, () =>
console.log('Example app listening on port ' + port + '!')
);
# for Mac user, install cURL by:
brew install curl
/getDevice
/getDeviceList
/getDevices
/getMyDevice
/getOtherDevice
/updateDeviceList
/addNewDevice
GET /devices
POST /devices/
GET /devices/123
PUT /devices/123
DELETE /devices/123
GET http://stackoverflow.com/questions
POST http://stackoverflow.com/questions/389169
GET http://stackoverflow.com/tags
PUT http://stackoverflow.com/users
DELETE http://stackoverflow.com/users/3012290
GET /tickets?q=return&state=open&sort=-prority,created_at
取得資源清單 -> GET /resources
新增資源 -> POST /resources
取得單一資源 -> GET /resources/:id
修改單一資源 -> PUT /resources/:id
刪除單一資源 -> DELETE /resources/:id
更新資源部份內容 -> PATCH /resources
只回傳HTTP header -> HEAD /resources/:id
200 OK
--
301 Moved Permanently
302 Found
304 Not Modified
--
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
405 Method Not Allowed
408 Request Timeout
--
500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
# 用 Accept 跟 Server 溝通格式
接收 純文字 -> Accept: text/plain
接收 HTML -> Accept: text/html
接收 JSON -> Accept: application/json
var express = require('express');
var app = express();
app.use([path,] callback [, callback...]);
app.METHOD(path, callback [, callback ...]);
// METHOD can be:
// checkout copy delete get head lock
// merge mkactivity mkcol move m-search
// notify options patch post purge put
// report search subscribe trace unlock
// unsubscribe
app.get('/', (req, res) => {
return res.send('Received a GET HTTP method');
});
app.post('/', (req, res) => {
return res.send('Received a POST HTTP method');
});
app.put('/', (req, res) => {
return res.send('Received a PUT HTTP method');
});
app.delete('/', (req, res) => {
return res.send('Received a DELETE HTTP method');
});
curl http://localhost:3000
curl -X POST http://localhost:3000
curl -X PUT http://localhost:3000
curl -X DELETE http://localhost:3000
app.post('/users', (req, res) => {
return res.send('POST HTTP method on users resource');
});
app.put('/users/:userId', (req, res) => {
return res.send(
`PUT HTTP method on users/${req.params.userId} resource`,
);
});
curl -X POST http://localhost:3000/users
curl -X PUT http://localhost:3000/users/12
let users = {
1: {
id: '1',
username: 'Robin Wieruch',
},
2: {
id: '2',
username: 'Dave Davids',
},
};
let messages = {
1: {
id: '1',
text: 'Hello World',
userId: '1',
},
2: {
id: '2',
text: 'By World',
userId: '2',
},
};
app.get('/users', (req, res) => {
return res.send(Object.values(users));
});
app.get('/users/:userId', (req, res) => {
return res.send(users[req.params.userId]);
});
app.get('/messages', (req, res) => {
return res.send(Object.values(messages));
});
app.get('/messages/:messageId', (req, res) => {
return res.send(messages[req.params.messageId]);
});
npm install body-parser
npm install uuid
import bodyParser from 'body-parser';
import uuidv4 from 'uuid/v4';
...
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
...
app.post('/messages', (req, res) => {
const id = uuidv4();
const message = {
id,
text: req.body.text,
};
messages[id] = message;
return res.send(message);
});
* bodyParser.json(): Parses the text as JSON and exposes the resulting object on req.body.curl -X POST -H "Content-Type:application/json" http://localhost:3000/messages -d '{"text":"Hi again, World"}'
curl http://localhost:3000/messages
app.use((req, res, next) => {
req.me = users[1];
next(); // Why "next()"?
});
app.post('/messages', (req, res) => {
const id = uuidv4();
const message = {
id,
text: req.body.text,
userId: req.me.id
};
messages[id] = message;
return res.send(message);
});