node31-35

//31、任务的区分

//vue的源码nextTick方法 描述了浏览器中常见的宏任务和微任务
//宏任务 script/ui/setTimeout/setInterval/requestFrameAnimation/setImmediate/MessageChannel 异步的 click ajax

//语言的本身提供的 promise.then mutationObserver nextTick


//32、模块的概念

/*
模块化规范:
Node中的模块化规范:
commonjs规范(node自己实现的)
es6Module(import export)
umd统一模块规范(如果浏览器不支持commonjs、requirejs,直接将变量放到window上)
amd规范
cmd规范
seajs
requirejs

commonjs规范(模块的概念)
----可以把复杂的代码拆分成小的模块,方便管理代码和维护;
----每个模块之间的内容都是相互独立的,互不影响的。(解决变量冲突的问题)。  单例模式(不能完全解决  命名空间) 使用自执行函数来解决

var name1={
	a:1
}
var name2 = {
	a:2
}
function (){
	var a=1;
}()

function(){
	var a =2;
}()

规范的定义:
每个文件都是一个模块;
如果你希望模块中的变量被别人使用,可以使用module.exports导出这个变量;
如果另一个模块想使用这个模块导出的结果,需要使用require语法来引用(同步的)

a.js
let a =1;
module.export = a;

useA.js
let r = require('./a')
console.log(r);

模块的分类:
require('fs') 核心模块、内置模块 不是自己写的,也不是安装来的是node中自己提供的,可以直接使用
require('commander');别人写的模块,通过npm install安装过来的,就是第三方模块,不需要有路径
自定义模块 require('./promise.js'); 自定义模块就是自己写的模块,引用时需要增加路径(相对路径,绝对路径)
 
//33.core模块使用

核心模块:
	fs(fileSystem处理文件的)
	path(处理路径)
	vm(虚拟机模块 沙箱环境)

const fs = require('fs');
const path = require('path');

console.log(Object.keys(fs));
console.log(Object.keys(fs.promises)); //只会转换异步的方法
打印结果
[
  'appendFile',       'appendFileSync',    'access',
  'accessSync',       'chown',             'chownSync',
  'chmod',            'chmodSync',         'close',
  'closeSync',        'copyFile',          'copyFileSync',
  'createReadStream', 'createWriteStream', 'exists',
  'existsSync',       'fchown',            'fchownSync',
  'fchmod',           'fchmodSync',        'fdatasync',
  'fdatasyncSync',    'fstat',             'fstatSync',
  'fsync',            'fsyncSync',         'ftruncate',
  'ftruncateSync',    'futimes',           'futimesSync',
  'lchown',           'lchownSync',        'lchmod',
  'lchmodSync',       'link',              'linkSync',
  'lstat',            'lstatSync',         'mkdir',
  'mkdirSync',        'mkdtemp',           'mkdtempSync',
  'open',             'openSync',          'opendir',
  'opendirSync',      'readdir',           'readdirSync',
  'read',             'readSync',          'readv',
  'readvSync',        'readFile',          'readFileSync',
  'readlink',         'readlinkSync',      'realpath',
  'realpathSync',     'rename',            'renameSync',
  'rmdir',            'rmdirSync',         'stat',
  'statSync',         'symlink',           'symlinkSync',
  'truncate',         'truncateSync',      'unwatchFile',
  'unlink',           'unlinkSync',        'utimes',
  'utimesSync',       'watch',             'watchFile',
  'writeFile',        'writeFileSync',     'write',
  'writeSync',        'writev',            'writevSync',
  'Dir',              'Dirent',            'Stats',
  'ReadStream',       'WriteStream',       'FileReadStream',
  'FileWriteStream',  '_toUnixTimestamp',  'F_OK',
  'R_OK',             'W_OK',              'X_OK',
  'constants',        'promises'
]
[
  'access',   'copyFile',  'open',
  'opendir',  'rename',    'truncate',
  'rmdir',    'mkdir',     'readdir',
  'readlink', 'symlink',   'lstat',
  'stat',     'link',      'unlink',
  'chmod',    'lchmod',    'lchown',
  'chown',    'utimes',    'realpath',
  'mkdtemp',  'writeFile', 'appendFile',
  'readFile'
]

所有的方法基本上都是同步方法、异步方法;
同步:如果刚刚运行程序,可以去使用同步的方法;
异步:开启一个服务监听客户端程序,就需要使用异步了,异步是非阻塞的;

操作文件时,尽量使用“绝对路径”来进行操作
获取当前的目录, process.cwd() 可变的 __dirname不可变的


const fs = require('fs');
const path = require('path');
//resolve不能遇到/,遇到/回到C盘的根目录
console.log(path.resolve(__dirname,'name.txt','/'));
//C:\Users\dptech\Desktop\test>node test.js
//C:\

console.log(path.join('name.txt','/'));//拼接name.txt \
//C:\Users\dptech\Desktop\test>node test.js
//name.txt\

console.log(path.join(__dirname,'name.txt','/'));
//C:\Users\dptech\Desktop\test>node test.js
//C:\Users\dptech\Desktop\test\name.txt\

console.log(path.extname('a/b/a.min.js'));//获取当前文件的扩展名 .js
//C:\Users\dptech\Desktop\test>node test.js
//.js

console.log(path.resolve(__dirname,'..','name.txt'));
const r = fs.readFileSync(path.resolve(__dirname,'..','name.txt'),'utf8');
console.log(r);
//C:\Users\dptech\Desktop\test\aa>node test.js
//C:\Users\dptech\Desktop\test\name.txt
//age.txt

fs.exists(path.resolve(__dirname,'..','name1.txt'),function(err,data){
	console.log(err);//false (此方法已废弃)
})
//C:\Users\dptech\Desktop\test\aa>node test.js
//false

1、同步判断文件是否存在
const exists = fs.existsSync(path.resolve(__dirname,'..','name1.txt'));
console.log(exists);//false

2、同步的读取文件
const r = fs.readFileSync(path.resolve(__dirname,'..','name1.txt'));
console.log(r);

<!--
C:\Users\dptech\Desktop\test\aa>node test.js
false
internal/fs/utils.js:259
    throw err;
    ^
Error: ENOENT: no such file or directory, open 'C:\Users\dptech\Desktop\test\name1.txt'
    at Object.openSync (fs.js:461:3)
    at Object.readFileSync (fs.js:364:35)
    at Object.<anonymous> (C:\Users\dptech\Desktop\test\aa\test.js:6:14)
    at Module._compile (internal/modules/cjs/loader.js:1200:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47 {
  errno: -4058,
  syscall: 'open',
  code: 'ENOENT',
  path: 'C:\\Users\\dptech\\Desktop\\test\\name1.txt'
}
-->

__dirname代表的是当前文件所在的文件夹
__dirname并不属于global,每个模块独有的

*/

 /*
//34、基本模板引擎
//虚拟机模块(沙箱) 干净的环境 测试用例
//内部一般情况下操作的都是字符串逻辑,如何让一个字符串来运行`console.log(1)`
//eval 默认会取当前的作用域下的变量,不干净的环境 eval()

const a = 100;
eval(`console.log(a)`);//100

const a = 100;
let fn = new Function(`console.log(a)`);
console.log(fn.toString());
console.log(fn());
//C:\Users\dptech\Desktop\test>node test.js
//function anonymous(
//) {
//console.log(a)
//}
//undefined:3
//console.log(a)          
//ReferenceError: a is not defined

const a = 100;
let fn = new Function('c','b',`console.log(a)`);
console.log(fn.toString());
//function anonymous(c,b
//) {
//console.log(a)
//}

//可以使用new Function来创建一个沙箱环境,让字符串执行
let fn = new Function('c','b','d',`let a=1;console.log(a);`);
console.log(fn());

//模板引擎的实现原理 with语法+字符串拼接+new Function来实现

template.html
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<%= name %>
<%= age %>
</body>
</html>

template.js
//实现自定义的模板引擎
const ejs = require('ejs');//第三方模块 npm init -y ; npm install ejs
const path = require('path');
const fs = require('fs');

//ejs.render();
ejs.renderFile(path.resolve(__dirname,'template.html'),{name:'zf',age:11,arr:[1,2,3]},(err,data)=>{
	console.log(data);
})
结果:
<!--
C:\Users\dptech\Desktop\test>node test.js
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
zf
11
</body>
</html>
 -->

my-template.html
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="with=device-width,initial-scale=1.0">
		<title>Document</title>
	</head>
	<body>
		{{name}}  {{age}}
	</body>
</html>

//arguments[0]就是匹配到的原字符串
//arguments[1]就是第一个括号

const ejs = require('ejs');//第三方模块 npm init -y ; npm install ejs
const path = require('path');
const fs = require('fs');

const renderFile = (filePath,obj,cb)=>{
	fs.readFile(filePath,'utf8',function(err,html){
		console.log(html);
		if(err){
			return cb(err,html);
		}

		html = html.replace(/\{\{([^}]+)\}\}/g,function(){
			//console.log(arguments[1].trim());
			let key = arguments[1].trim();
			return obj[key];
		});
		cb(err,html);
	})
}

renderFile(path.resolve(__dirname,'my-template.html'),{name:'zfpx',age:11,arr:[1,2,3]},function(err,data){
	console.log(data);
})

结果:
/*
C:\Users\dptech\Desktop\test>node test.js
<!DOCTYPE html>
<html lang="en">
        <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="with=device-width,initial-scale=1.0">
                <title>Document</title>
        </head>
        <body>
                {{name}}  {{age}}
        </body>
</html>
<!DOCTYPE html>
<html lang="en">
        <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="with=device-width,initial-scale=1.0">
                <title>Document</title>
        </head>
        <body>
                zfpx  11
        </body>
</html>
 */
/*
//35、模板引擎的实现原理

my-template.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="with=device-width,initial-scale=1.0">
    <title>Document</title>
  </head>
  <body>
    {{name}}  {{age}}
    {% arr.forEach(item=>{  %}
      <li>1</li>
    {%  })   %}
  </body>
</html>

const path = require('path');
const fs = require('fs');

const renderFile=(filePath,obj,cb)=>{
  fs.readFile(filePath,'utf8',function(err,html){
    if(err)
    {
      return cb(err,html);
    }

    //arguments[0]就是匹配到的原字符串
    //arguments[1]就是第一个原来括号

    html = html.replace(/\{\{([^}]+)\}\}/g,function(){
      console.log(arguments[1]);
      let key = arguments[1].trim();
      return obj[key];
    });

    cb(err,html);
  })
}

renderFile(path.resolve(__dirname,'my-template.html'),{name:'zf',age:11,arr:[1,2,3]},function(err,data){
  console.log(data);
})
/*
C:\Users\dptech\Desktop\test>node test.js
name
age
<!DOCTYPE html>
<html lang="en">
        <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="with=device-width,initial-scale=1.0">
                <title>Document</title>
        </head>
        <body>
                zf  11
                {% arr.forEach(item=>{  %}
                        <li>1</li>
                {%  })   %}
        </body>
</html>
 */
/*
test.js
function a(obj){
    let str = '';
    with(obj){
        str += `<!DOCTYPE html>
                <html lang="en">
                  <head>
                    <meta charset="UTF-8">
                    <meta name="viewport" content="with=device-width,initial-scale=1.0">
                    <title>Document</title>
                  </head>
                  <body> `
                 arr.forEach(item=>{  
                    str += `<li>1</li>`
                 })
                 str+=`</body>
                    </html>`;
    } 
    return str;
}  
console.log(a({arr:[1,2,3]}));

//结果
C:\Users\dptech\Desktop\test>node test.js
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="with=device-width,initial-scale=1.0">
    <title>Document</title>
  </head>
  <body> <li>1</li><li>1</li><li>1</li></body>
</html>

//1、需要把字符串{% %}替换掉,并且拼出一个结果的字符串,new Function的方式 with


my-template.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="with=device-width,initial-scale=1.0">
    <title>Document</title>
  </head>
  <body>
    {{name}}  {{age}}
    {% arr.forEach(item=>{  %}
      <li>item</li>
    {%  })   %}
  </body>
</html>

template.js
const path = require('path');
const fs = require('fs');

const renderFile=(filePath,obj,cb)=>{
    fs.readFile(filePath,'utf8',function(err,html){
        if(err)
        {
            return cb(err,html);
        }

        //arguments[0]就是匹配到的原字符串
        //arguments[1]就是第一个原来括号

        html = html.replace(/\{\{([^}]+)\}\}/g,function(){  //RegExp.$1
            console.log(arguments[1]);
            let key = arguments[1].trim();
            return '${'+key+'}' //{{name}}=>${name}
        });

        let head = `let str='';\r\n with(obj){\r\n`;
        head += 'str+=`';
        html = html.replace(/\{\%([^%]+)\%\}/g,function(){
            return '`\r\n'+arguments[1]+'\r\nstr+=`\r\n';
        })

        let tail = '`}\r\n return str;';
        console.log(head+html+tail);
        let fn = new Function('obj',head+html+tail);
        console.log(fn.toString());
        
        cb(err,html);
    })
}

renderFile(path.resolve(__dirname,'my-template.html'),{name:'zf',age:11,arr:[1,2,3]},function(err,data){
    console.log(data);
})

*/

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值