path.join() && path.resolve() && url.resolve() .&&& 几个常用的 ejs 语法 &&& 模块化规范@stage3

path.join() && path.resolve() && url.resolve()

path.join()和 path.resolve()的区别

现在写代码的时候有时候使用 path.join(**dirname,‘dist’)有时候用 path.resolve(**dirname,‘dist’),都是能拼接出来一个绝对路径,但是具体有什么区别呢? ###  path.join()方法是将多个参数字符串合并成一个路径字符串

console.log(path.join(__dirname,'a','b'));   假如当前文件的路径是E:/node/1,那么拼接出来就是E:/node/1/a/b。
console.log(path.join(__dirname,'/a','/b','..'));  路径开头的/不会影响拼接,..代表上一级文件,拼接出来的结果是:E:/node/1/a
console.log(path.join(__dirname,'a',{},'b'));   而且path.join()还会帮我们做路径字符串的校验,当字符串不合法时,会抛出错误:Path must be a string.

path.resolve()方法是以程序为根目录,作为起点,根据参数解析出一个绝对路径

* 以应用程序为根目录
 * 普通字符串代表子目录
 * /代表绝对路径根目录
 >  console.log(path.resolve()); 得到应用程序启动文件的目录(得到当前执行文件绝对路径) E:\zf\webpack\1\src
 >  console.log(path.resolve(‘a’,’/c’)); E:/c ,因为/斜杠代表根目录,所以得到的就是 E:/c
所以我们一般拼接的时候需要小心点使用/斜杠

console.log(path.resolve(__dirname,‘img/so’)); E:\zf\webpack\1\src\img\so 这个就是将文件路径拼接,并不管这个路径是否真实存在。
console.log(path.resolve(‘wwwroot’, ‘static_files/png/’, ‘…/gif/image.gif’)) E:\zf\webpack\1\src\wwwroot\static_files\gif\image.gif
这个是用当前应用程序启动文件绝对路径与后面的所有字符串拼接,因为最开始的字符串不是以/开头的。
  …也是代表上一级目录。

path.resolve() 案例

var path = require("path"); //引入node的path模块

path.resolve("/foo/bar", "./baz"); // returns '/foo/bar/baz'
path.resolve("/foo/bar", "baz"); // returns '/foo/bar/baz'
path.resolve("/foo/bar", "/baz"); // returns '/baz'
path.resolve("/foo/bar", "../baz"); // returns '/foo/baz'
path.resolve("home", "/foo/bar", "../baz"); // returns '/foo/baz'
path.resolve("home", "./foo/bar", "../baz"); // returns '/home/foo/baz'
path.resolve("home", "foo/bar", "../baz"); // returns '/home/foo/baz'

url.resolve()

const url = require("url");
url.resolve("/one/two/three", "four"); // 'one/two/three/four'
url.resolve("/one/two/three", "/four"); // 'one/two/four'
url.resolve("/one/two/", "four"); // 'one/two/four'

几个常用的 ejs 语法

1.转义输出

<%= 变量名 %>
//这个是转义输出,可以把变量名替换成自己需要的东西.
// js文件
ejs.renderFile("./views/test.ejs", { name: "wzz" }, function(err, data) {
  if (err) {
    console.log(err);
  } else {
    console.log(data);
  }
});
<!-- ejs文件 -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <%=name%>
  </body>
</html>

最后我们可以发现 name 变量,在控制台被替换成了 wzz.



2.不转义输出

<%- 变量名%>

不转义输出可以把定义的字符串不转义的输出.
我们可以这么用,这边我们省略了第二个不使用的 json 数据

<!-- ejs文件 -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <% var str='<div><div>'; %>
  <%-str %>
  <%=str %>
</body>
</html>

输出结果如下

<div><div>
  &lt;div&gt;&lt;div&gt;

3.js 代码

//这里面可以写javascript的代码.我们可以这么使用
<% Javascript代码 %>

案例

<!-- ejs文件 -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <%for(var i=0;i<json.arr.length;i++){%>
    <div>user:<%=json.arr[i].user%> pass:<%=json.arr[i].pass%><div>
  <%}%>
</body>
</html>


4.使用 include 引入外部的文件

<% include 文件的地址 %>

案例

<!-- ejs文件 -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <% include ../content.txt %>
  </body>
</html>

模块化规范

在 ES6 之前 js 没有提供模块化的相关功能 , 社区给出了相关的解决方案

AMD Asynchronous Module Definition 异步模块定义

提供异步加载模块的机制
异步加载提前执行,出现错误可以提前发现,但容易产生资源浪费
代表作:require.js

$ sudo cnpm install requirejs -S

  • 模块导出 define([依赖注入],(¥)=>{ return { 自定义模块内容 } })
  • 模块的导入 require.config({}) 进行配置, 通过 require([依赖注入],($$)=> { 独立作用域 })
///定义模块
//第一个参数 依赖列表
define(["jquery"], function() {
  return {
    sayHi: function() {
      console.log("hi");
    },
    max: function() {
      return Math.max.apply(null, arguments);
    }
  };
});
// 配置require
require.config({
  // baseUrl: "../../node_modules",
  paths: {
    // 文件列表
    // 属性是 模块名
    // 属性值 模块路径  不写文件后缀名
    jquery: "../node_modules/jquery/dist/jquery.min",
    index: "./index"
  }
});

require(["jquery"], function($$) {
  $$("#btn").on("click", function() {
    $$("div").hide(2000);
  });
});

require(["jquery"], function($) {
  console.log($);
  console.log(123);
});

require(["index"], function(obj) {
  console.log(obj.max(63, 173, 73, 77, 185, 12));
  console.log($);
});

// require(['index', 'jquery'], function(obj) {
//     console.log(obj.max(63, 173, 73, 77, 185, 12));
//     console.log($);
// })

CMD Common Module Definition 同步模块定义

模块按需加载
将延迟加载,需要时动态加载,可以减少资源浪费,但等待时间长,出错 时间延后,
代表作:sea.js

$ sudo cnpm i seajs -S

经常使用的 API 只有 define, require, require.async, exports,module.exports 这五个

define(function(require, exports) {
  // 获取模块 a 的接口
  var a = require("./a");

  // 调用模块 a 的方法
  a.doSomething();
  require.async(["./c", "./d"], function(c, d) {
    c.doSomething();
    d.doSomething();
  });
  console.log(require.resolve("./b"));
  // ==> http://example.com/path/to/b.js

  // 对外提供 foo 属性
  exports.foo = "bar";

  // 对外提供 doSomething 方法
  exports.doSomething = function() {};

  module.exports = {
    foo: "bar",
    doSomething: function() {}
  };
});

Common.js 后台模块化规范

代表作 node.js

  • 导出 module.exports = XXX
  • 模块导入 const XXX = require(‘相对路径’)
var express = require("express");
var router = express.Router();

/* GET home page. */
router.get("/", function(req, res, next) {
  // res.render 渲染一个模板
  // render的第一个函数 指的是模板文件的名字
  // 第二个参数 是传给模板的数据 对象

  // 路由在渲染页面时,将数据传递给模板引擎
  res.render("index", {
    title: "Express",
    username: "小明"
  });
});

module.exports = router; //定位
// 引入路由
var indexRouter = require("./routes/index");
var usersRouter = require("./routes/users");

ES6 的 module 模块化解决方案

服务器运行
ES6 模块不是对象 , 而是通过 export 命令来指定输出代码, 再 通过import 命令输入
每一个模块内声明的变量都是局部变量, 不会污染全局作用域;
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。

// CommonJS模块
let { stat, exists, readFile } = require('fs');

// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

上面代码的实质是整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。

ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。

// ES6模块
import { stat, exists, readFile } from 'fs';

上面代码的实质是从fs模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。

ES6 的模块自动采用严格模式,不管你有没有在模块头部加上"use strict";。

严格模式主要有以下限制。

* 变量必须声明后再使用
* 函数的参数不能有同名属性,否则报错
* 不能使用with语句
* 不能对只读属性赋值,否则报错
* 不能使用前缀 0 表示八进制数,否则报错
* 不能删除不可删除的属性,否则报错
* 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
* eval不会在它的外层作用域引入变量
* eval和arguments不能被重新赋值
* arguments不会自动反映函数参数的变化
* 不能使用arguments.callee
* 不能使用arguments.caller
* 禁止this指向全局对象
* 不能使用fn.caller和fn.arguments获取函数调用的堆栈
* 增加了保留字(比如protected、static和interface)

其中,尤其需要注意this的限制。ES6 模块之中,顶层的this指向undefined,即不应该在顶层代码使用this。

案例

// export class Student {
//     constructor(name) {
//         this.name = name;
//     }
// }

// export var a = 10;

// export function fn(){
//     console.log('ok');
// }

export { Student, a, fn };

class Student {
  constructor(name) {
    this.name = name;
  }
}

var a = 10;

function fn() {
  console.log("ok");
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <script>
      import { Student } from "./DemoClass.js";
      var s = new Student("zhangsan");
      console.log(s);
      import { a } from "./DemoClass.js";
      console.log(a);
      import { fn } from "./DemoClass.js";
      fn();
    </script>
    <script type="module">
      import { Student as s, a, fn } from "./DemoClass.js";
      var s1 = new s("zhangsan");
      console.log(s1);
      console.log(a);
      fn();
    </script>
  </head>

  <body></body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值