Skip to content
目录
javascript
使用Node.js V16+版本的话,启用ES6 import的支持很简单,正如上面错误中的提示那样,只需要在package.json里添加下面第二行:"type" : "module",
不用再加–experimental-modules参数来启用了, /从错误信息来看,在不做代码改动的情况下,我们是没法再用require的,  改成.cjs才可以, "type" : "module"适合比较新的项目/
v16.x/package.json 
    "main"指定 CommonJS 入口点 //这使得 Node.js 能够运行 CommonJS 入口点,
    "module"指定 ES 模块入口点 //而构建工具(如webpack)使用 ES 模块入口点
    /Node.js 忽略顶级"module"字段。/

better-npm-run -> 被cross-env替代

node使用使用 babel-node CLI命令,来运行含有 import/export 语法的 js 代码,它不用单独安装,而是随babel-cli一起安装 
    Babel 6 中的babel-node命令是babel-cli包的一部分。
    Babel 7 中,这个命令已经被拆分成它自己的@babel/node包

概念

javascript
OpenAPI规范(以前称为Swagger规范)    
    v2叫做:Swaggerv2
    v3叫做:OpenAPIv3
API规范可以用YAML或JSON编写,
    云上(swaggerhub)可以直接把编写的文件编译成可访问的API
        //还可以导出js客户端sdk,它用superagent(类似axios)封装好了所有的请求,直接可用,就不用自己写前端了。eg: returnData=apiInstance.getUsers(opts, callback);
    本地也可以用swagger-routes-express库直接把编写的文件编译成可访问的API


FAT //工厂验收测试
UAT //User Acceptance Testing 用户验收测试, Beta测试
Browserslist  //是一个前端项目配置工具,功能是在前端工具之间共享目标环境的浏览器信息。
    //被 @babel/preset-env 和 Autoprefixer 用来确定需要转译的 JavaScript 特性和需要添加的 CSS 浏览器前缀。
Jest //单元测试, 开箱即用,无需配置
    //默认测 tests/unit或__tests__目录下 , 的 js|jsx|ts|tsx文件
    //调试方法: node --inspect-brk ./node_modules/@vue/cli-service/bin/vue-cli-service.js test:unit --runInBand
Mocha //单元测试, (配合 mocha-webpack) /vue-cli-service test:unit/通过 mocha-webpack + chai 运行单元测试
    //默认测 tests/unit目录下,  的 ts|js文件
    //注意,测试是在Node.js内运行的,并使用JSDOM模拟了浏览器环境。    
Cypress //来E2E测试(模拟用户的操作去测试) //vue-cli-service test:e2e使用运行e2e测试cypress run

Mock//模拟后台接口 vue.config.js的devServer.before:require('./mock/mock-server.js') -> mock/index.js -> mock/目录下的各种模拟

vue-cli-service lint //没有装eslint则默认使用tslint//if (!api.hasPlugin('eslint'))  require('./lib/tslint')
    vue add @vue/typescript//则默认TSLint
    vue add @vue/eslint//则是用的eslint

EditorConfig //可以帮助开发者在不同的编辑器和IDE 之间定义和维护一致的代码风格
Plop//根据模板生成文件,就不用自己新建了,npm run new-> "new": "plop" -> ./plopfile.js -> ./plop-templates/模板文件目录
Backbone//一种流行的JavaScript库,使通过提供模型,集合和视图来构建Web应用程序的结构。Aurelia是类似库

JSON Web令牌(JWT)//eg:用'0e4253ef-5e4f-4d62-8eeb-c80e36a68c8a'给A用户生成eyJhbGciOiJIUzI1Ni...U0NzcwOTg2NX0.ciS4MqQxxx8eCf2zX

SOLID原则
    1.单一责任//对象做一件事,做好,就行了        
    2.开闭原则//一旦为一个类设计了一个接口,则该接口随时间的变化应该通过继承而不是直接修改该接口来实现
    3.里氏替换原则//使用泛型时谨记,举个不满足的加深理解:基类—人,有个方法—生娃。子类有超人,机器人,蜘蛛人。
                 //看似都具有人的基本特征,但是其中机器人让他生娃,是无法做到的,所以不满足里氏替换
    4.接口隔离//接口做一件事,做好,就行了        
    5.依赖倒置//我们应该依靠在抽象(或接口)上,而不是在具体对象的实例上

VsCode调试配置:launch.json

javascript
"env"{
        "DEBUG": "users:*", //node环境变量
        "PORT": "3333",
        "SEQUE1LIZE_CONNECT": "sequelize-sqlite.yaml",
    },
"runtimeArgs": ["--experimental-modules"],//node的运行参数 
"args": [ "serve" ]//js的运行参数

命令

javascript
node-gyp//使用C或C ++编译器编译以构建相应的  .node 文件(该.node扩展名用于二进制本机代码模块)。
    //libxslt 和  libxmljs 模块是同名C / C ++库的包装
node --v8-options //Node.js是在V8之上构建的;它有自己的options,主要集中在字节码编译或垃圾回收和堆算法的细节上。
util.promisify //我们可以转换任何面向回调的函数,使其返回Promise
process.argv[2] //控制台输入的第二个参数
.mjs //扩展名为Node.js的ES6模块//node --experimental-modules simpledemo.mjs 
EventEmitter //自带的,默认require('events')作为它
    //订阅emitter.on("event1",function(message){ console.log(message);})
    //发布emitter.emit("event1","I'm message");    

cross-env库 //在Windows cmd.exe命令行中设置环境变量
Internet邮件扩展:MIME//MIME类型:multipart/form-data
--max_old_space_size 5000 //解决服务进程内存不足的问题
nodemon index.js //调试必备,支持热更新

变量

javascript
全局对象module://这些对象在所有模块中均可用。以下变量似乎是全局变量,但不是全局变量。它们仅存在于模块范围内,请参阅 模块系统文档:
    __dirname//包含当前正在执行的文件的目录的绝对路径
        console.log(__dirname);// Prints: /Users/mjr
        console.log(path.dirname(__filename));// Prints: /Users/mjr
    __filename
        console.log(__filename);// Prints: /Users/mjr/example.js
        console.log(__dirname);// Prints: /Users/mjr
    exports//module.exports也可以通过exports模块全局访问
    module//module实际上不是全局的,而是每个模块的局部
        module.exports.hello = true; // Exported from require of module
   require()//用于导入模块JSON,和本地文件,会把代码写的路径转为运行时的路径如:require("static/assets/img/admin.png")
   


process    
    process.env//所有环境变量
    process.cwd() 方法返回Node.js 进程的当前工作目录
    
全局对象global//类似于客户端 JavaScript 运行环境中的 window。

全局函数
    setInterval(callback, millisecond)
    clearInterval(timer)
    setTimeout(callback, millisecond)
    clearTimeout(timer)

Node 调试
    最方便也是最简单的调试:console.log()
    Node 原生的调试//网址:https://nodejs.org/api/debugger.html    
    第三方模块提供的调试工具
        $ npm install node-inspector –g   //方式一
        $ npm install devtool -g          //方式二
    开发工具的调试 Visual Studio Code

模块化结构
    1.Node 实现 CommonJS 规范,所以可以使用模块化的方式组织代码结构。    Node 采用的模块化结构是按照 CommonJS 规范。    
        //模块与文件是一一对应关系,即加载一个模块,实际上就是加载对应的一个模块文件。
        exports = function //❌ 把exports等同module.exports给覆盖掉了
        module.exports = function //✔
        CommonJS模块加载ES6模块 2种方法
            1.1.动态导入 import() 异步加载
            1.2.@std/esm 提供了一项require() 异步加载
    2.Node.js 10对ES2015模块支持可通过设置命令行标志来使用
        import'./foo?search';//为了安全,Node.js接收且仅接受file:URL, 所以[ :,?,#,% ]都是有效的
        --harmony-import-meta 启用 import.meta.url 代替 CommonJS 规范的 __dirname
            const __dirname = path.dirname(new URL(import.meta.url/*file:///../app.mjs*/).pathname);

常用内置模块    
    child_process:新建子进程。
        
    util:提供一系列实用小工具。
        util.inspect //功能是一种以易于阅读的方式呈现对象的有用方法
    http:提供 HTTP 服务器功能。
        const server = http.createServer();
        //处理请求
        server.on('request', (req, res) => {//req, res都是一个流
                    var requrl = url.parse(req.url, true);
                    if (requrl.pathname === '/') {
                                res.writeHead(200, {'Content-Type': 'text/html'});
                                res.end(html);//返回内容
                    }
            })
        server.listen(8124);
        //发送请求
        var req = http.request({headerObj}, 
                                res => {res.on('data', chunk => { console.log(`打印响应内容 BODY${chunk}`);});
                              });
            req.end();
    url:用于解析 URL。
    querystring:解析 URL 中的查询字符串。
    crypto:提供加密和解密功能。

文件系统操作相关模块
    fs:基础的文件操作 API //fs-extra更改为返回Promise而不是回调函数
        fs.readdirSync
        fs.statSync(loc).isDirectory() | isFile()
        dirList = fs.readdirSync(target)
        fs.unlink 删除文件
        fs-extra(第三方):https://www.npmjs.com/package/fs-extra
        用流复制文件:
            const img2 = fs.createWriteStream('./img2.png')//只是声明
            const img1 = fs.createReadStream('./img1.png').pipe(ws)//复制到声明
    Buffer://一个用于处理二进制数据的缓冲区对象
    path//:提供和路径相关的操作 API
        path.join('/foo', 'bar', 'baz/asdf','quux');//    '\\foo\\bar\\baz\\asdf\\quux'
        path.join('/foo', 'bar', 'baz/asdf', 'quux', '..','..');//    '\\foo\\bar\\baz' ..表示上一级目录 两次..就是上上一级
        path.resolve() //将返回当前工作目录的绝对路径
        path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');//'C:\\Users\\123\\wwwroot\\static_files\\gif\\image.gif'
        
    readline:用于读取大文本文件,一行一行读

    
技巧:
    const req = require.context(路径,is递归,后缀匹配规则)
    req.keys()//返回路径下所有文件名

express服务器库:

javascript
用户控制 1个express服务器
页面内容 1个express服务器:
var app = express(); 
    模板:
        路径映射:
        <script src="/assets/vendor/jquery/jquery.min.js"></script> //   /assets/vendor/jquery 映射到 node_modules/jquery
        app.use('/assets/vendor/jquery', express.static(path.join(__dirname, 'node_modules', 'jquery'))); 
    中间件(拦截处理):
        app.use(/*[可选匹配url]:'/user/profile/:id'*/,function(req, res, next) {
            req, res //<==> Node.js HTTP的request(WritableStream)和response(EventEmitter)            
                :id //值将落入req.params.id
                res.send({  n: req.params.n,     result: val   }); //返回JSON
            next是回调函数next(new Error('Not found'));则传给带有err参数的中间件, 否则调用next(data)传数据给下一个中间件
            /如果既不调用next也不res.send调用,则请求永远不会得到响应/
         });  
        app.get  匹配GET方法
        app.post 匹配POST方法
        var router = express.Router(); //router等同app
            router.get('/', function(req, res, next) { })//但它的'/'如果放在user.js就相当于'/users'
        //错误处理:  
            app.use(function(err, req, res, next) { //带有err参数的中间件
              res.status(err.status || 500); 
              res.render('error'/*模板名,对应error.hbs*/, {message: err.message, error: {}}/*模板body里可取到的值*/); 
            });   
        passport(国外的验证登录中间件)
        Socket.IO(实时):   
            服务器:
                const io = socketio(server); 
                io.use(passportSocketIo.authorize({ 
                //事件通过路由变动知道实时信息改变后,让Socket.IO通知所有浏览器
                io.of('/home')/*限制作用范围*/.emit('notetitles', { notelist });  
            浏览器网页:
                 var socket = io('/home'); 
                 socket.on('notetitles', function(data) { var notelist = data.notelist;}); 
    数据库:
        普通:
            LevelUP//这是Google开发的LevelDB引擎的Node.js版, 不支持从多个实例同时访问数据库!!
            SQLite3//的主要优点是它不需要服务器;它是一个独立的,无需设置的SQL数据库。
                创建: $ sqlite3 dataBase1.sqlite3 --init beExecute.sql //执行sql文件beExecute.sql创建表到dataBase1数据库
                使用: db = new sqlite3.Database(dataBase1.sqlite3, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE,err => { });
                执行: db.run(sql,替换值,err=>{}})
                      db.get(sql, [替换值], (err,row) => {})
                      db.all  函数检索结果集的所有行
            
        对象关系映射(ORM)(需要先安装数据库): //DB沦为数据服务
            Mongoose: 是MongoDB(http://mongoosejs.com/)上流行的ORM  
                 Schema === (模型/表结构/数据结构)
                 Collection类型 === 整个表
                     Model === 整个表的一部分 //哪一部分? 由Schema约束
                 Document类型 === 一行/一条数据 
                     new Model === 表中的具体一行
                 Field ===//Embedded Documents === 表连接

                 
                 populate() 可以连表查询,即在另外的集合中引用其文档。可以自动替换 document 中的指定字段,替换内容从其他 collection 中获取。
                     通过virtual查询出来的数据,如果不对结果进行操作,那么返回到前端的数据就是"_doc", 但是如果要对查询的结果进行操作,此时操作的数据不是"_doc"
                     而是整个对象, 因此需要过滤一次(const docs = results.map(x => x._doc))
                 aggregate聚合管道可以对集合中的文档进行变换和组合,如多表关联查询、数据的统计
                 Getters与 Setters 修饰符,通过 set 修饰符在增加数据的时候对数据进行格式化
                 
                 mongoose.Schema({   name: { type: String, trim: true }, 
                                     age: Number, 
                                     status: {   type: Number, default: 1                 
                                                 unique: true //唯一索引 index: true//普通索引
                                                 min: [6, 'Too few eggs'],//max: 12 , required: [true, 'Why no bacon?'], enum: ['Coffee', 'Tea'],
                                                 required: function() { return this.status > 3; },
                                                 validate: { validator: function(v) { return /\d{3}-\d{3}-\d{4}/.test(v); }, // 自定义的验证器,如果通过验证返回 true,没有通过则返回 false 
                                                 message: '{VALUE} is not a valid phone number!' },
                                             }
                                  })
                                 
            Sequelize:
                创建:new Sequelize(params.dbname, params.username, params.password
                            , jsyaml.safeLoad(await fs.readFile('config_file.yaml', 'utf8'), 'utf8').params)
                    .define('Note', { notekey: { type: Sequelize.STRING,primaryKey: true, unique: true},title: Sequelize.STRING,body: Sequelize.TEXT}); 
                    .find({ where: { notekey: key } }).notekey 
.findAll({ attributes: ['notekey']}).map(note => note.notekey)
.create({username: username})
                    .close();
                配置:config_file.yaml:
                        dbname: notes 
                        username: .. user name 
                        password: .. password 
                        params: 
                            host: localhost 
                            port: 3306 
                            dialect: mysql  #电脑上安装了mysql //也可以是SQLite3
     身份验证:  
         express-session中间件
         使用Restify,实现REST接口 
                  
     部署:
         linux方式:
             PM2:代替node //它针对Node.js流程进行了优化。它捆绑流程管理并监视到一个应用程序   
                 pm2 start configfile.json //来启动服务
         docker方式(更简单):
             容器间通信:通过docker网桥
             云托管:
     安全:
         certbot: //容器的目的是管理“让我们加密SSL”证书
         Helmet: //用于设置各种安全性 标头
         express-force-ssl: //http重定向到https
         csurf //解决跨站请求伪造
         sql-injection
     测试:
         Puppeteer //前端无头浏览器UI测试
         Mocha单元测试框架和Chai断言库

koa, web框架

//Koa 是一个非常优秀的框架,然而对于企业级应用来说,它还比较基础。

javascript
//Koa 的中间件和 Express 不同,Koa 选择了洋葱圈模型,所有的请求经过一个中间件的时候都会执行两次
//对比 Express 形式的中间件,Koa 的模型可以非常方便的实现后置处理逻辑
//和 Express 只有 Request 和 Response 两个对象不同,Koa 增加了一个 Context 的对象
    const Koa = require('koa');
    const app = new Koa();
    
    const main = ctx => {
      ctx.response.body = 'Hello World'; //上下文,包括HTTP请求和HTTP回复
    };
    
    app.use(main);
    app.listen(3000);

egg.js

javascript
egg.js
    Express 适合个人项目,但框架本身缺少约定,标准的 MVC 模型会有各种千奇百怪的写法。
    Egg     适合团队项目,按照约定进行开发,奉行『约定优于配置』,团队协作成本低
        //Egg 继承于 Koa
        
worker agent 进程 //worker是进程1,2,3,4是集群 agent是特殊用来处理整个集群的公共功能如记录日志

多线程

javascript
var numCPUs = os.cpus().length;
    var cluster = require('cluster');
    cluster.on('exit', (worker, code, signal) => {
        console.log('工作进程 %d 关闭 (%s). 重启中...',  worker.process.pid, signal || code);
    });
//  worker = cluster.fork() //根据numCPUs去fork多个线程

PNPM

JS
pnpm i --shamefully-hoist 出现奇怪的问题时执行它, //创建一个平面node_modules结构,类似于npm or yarn。 警告:这是非常不鼓励的。

NPM

javascript
使用淘宝镜像:
    1.目录下放.npmrc文件,每次npm命令会自动读取它的配置//可设置淘宝镜像等
        // registry=https://registry.npmmirror.com
    w
    2.持久使用:            
            npm config set registry https://registry.npmmirror.com
            npm config set registry https://registry.npmjs.org//恢复默认
            pnpm config set registry https://registry.npmmirror.com

/不要使用cnpm,因为cnpm,是不支持依赖版本锁定的/
    cnpm i xxx@xxx不会更新到package-lock.json中去。
    cnpm i不受package-lock.json影响,只会根据package.json进行下载

当我们使用最新的Node运行‘npm instal --save xxx',的时候,他会优先考虑使用插入符号(^)而不是波浪符号(~)了
    https://docs.npmjs.com/cli/v7/using-npm/config#save-prefix 有说到
    版本号详解(^~区别)
    ^限制第一位3.3.4 // >=3.3.4 <4.0.0
    ~限制第二位1.15.2 // >=1.15.2 <1.16.0     


nvm		node version manager 用来管理node版本,切换node版本 ,nvm install v12.14.1  nvm use v12.14.1


npm config ls 	#查看默认全局路径等

npm i 前删除package-locked.json可以避免npm i后还找不到库的错误

npm cache clean -f //npm清理缓存  清的是 ~/.npm/_cacache 文件夹中的数据

npm config list -l //列出详细配置     

node(主要读取main入口) 和 npm 都使用这个文件
    
dependencies字段,devDependencies字段
    devDependencies是仅在开发期间需要的模块,而dependencies是在运行时也需要的模块
    如果我们只是单纯的做项目,那么我们可简单地认为生产环境和开发环境做为一种友善的提示,实质没有什么区别;
    /但是,如果在发布npm包的时候,两种环境安装方式是有很大区别的!!!/
        'npm i 包名',只有dependencies下会被安装
        平时项目'npm i',则都会被安装
    {
      "devDependencies": {
        "karma-browserify": "~5.0.1"
      }
    }
    "vue3": "npm:vue@3", //别名

peerDependencies
    有时,你的项目和所依赖的模块,都会同时依赖另一个模块,但是所依赖的版本不一样。比如,你的项目依赖A模块和B模块的1.0版,而A模块本身又依赖B模块的2.0版。
    大多数情况下,这不构成问题,B模块的两个版本可以并存,同时运行。但是,有一种情况,会出现问题,就是这种依赖关系将暴露给用户。
    最典型的场景就是插件,比如A模块是B模块的插件。用户安装的B模块是1.0版本,但是A插件只能和2.0版本的B模块一起使用。这时,用户要是将1.0版本的B的实例传给A,就会出现问题。因此,需要一种机制,在模板安装的时候提醒用户,如果A和B一起安装,那么B必须是2.0模块。
    peerDependencies字段,就是用来供插件指定其所需要的主工具的版本。
    {
      "name": "chai-as-promised",
      "peerDependencies": {
        "chai": "1.x"
      }
    }
    上面代码指定,安装chai-as-promised模块时,主程序chai必须一起安装,而且chai的版本必须是1.x。如果你的项目指定的依赖是chai的2.0版本,就会报错。
    注意,从npm 3.0版开始,peerDependencies不再会默认安装了。
本站总访问量 次 本站访客数 人次

1111111111111111111