模块化npxEslint

66 阅读5分钟

CommonJS

关键词:

  • 社区标准
  • 使用函数实现
  • 仅node环境支持
  • 动态依赖(需要代码运行后才能确定依赖)
  • 动态依赖是同步执行的

原理:

// require函数的伪代码
function require(path){
  if(该模块有缓存吗){
    return 缓存结果;
  }
  function _run(exports, require, module, __filename, __dirname){
    // 模块代码会放到这里
  }
  
  var module = {
    exports: {}
  }
  
  _run.call(
    module.exports, 
    module.exports, 
    require, 
    module, 
    模块路径, 
    模块所在目录
  );
  
  把 module.exports 加入到缓存;
  return module.exports;
}
//this exports module.exports是相同的值

ES Module

关键词:

  • 官方标准

  • 使用新语法实现

  • 所有环境均支持

  • 同时支持静态依赖(放在代码顶端不能放到判断循环函数里面)和动态依赖(.then())

    静态依赖:在代码运行前就要确定依赖关系

  • 动态依赖是异步的

  • 符号绑定(导入的变量地址和导出的变量是一个地址)

关于符号绑定:

// module a.js
export var a = 1;
export function changeA(){
  a = 2;
}
​
// index.js
// 导入位置的符号和导出的符号并非赋值,它们完全是一个东西
import {a, changeA} from './a.js';
console.log(a); // 1
changeA();
console.log(a); // 2

面试题

  1. commonjs 和 es6 模块的区别是什么?

    参考答案:

    1. CMJ 是社区标准,ESM 是官方标准
    2. CMJ 是使用 API 实现的模块化,ESM 是使用新语法实现的模块化
    3. CMJ 仅在 node 环境中支持,ESM 各种环境均支持
    4. CMJ 是动态的依赖,同步执行。ESM 既支持动态,也支持静态,动态依赖是异步执行的。
    5. ESM 导入时有符号绑定,CMJ 只是普通函数调用和赋值
  2. export 和 export default 的区别是什么?

    参考答案:

    export 为普通导出,又叫做具名导出,顾名思义,它导出的数据必须带有命名,比如变量定义、函数定义这种带有命名的语句。在导出的模块对象中,命名即为模块对象的属性名。在一个模块中可以有多个具名导出

    export default 为默认导出,在模块对象中名称固定为 default,因此无须命名,通常导出一个表达式或字面量。在一个模块中只能有一个默认导出。

  3. 下面的模块导出了什么结果?

    exports.a = 'a';
    module.exports.b = 'b';
    this.c = 'c';
    module.exports = {
      d: 'd'
    }
    

    参考答案:

    { d: 'd' }
    
  4. 下面的代码输入什么结果?

    // module counter
    var count = 1;
    export {count}
    export function increase(){
      count++;
    }
    ​
    // module main
    import { count, increase } from './counter';
    import * as counter from './counter';
    const { count: c } = counter;
    increase();
    console.log(count);
    console.log(counter.count);
    console.log(c);
    

    运行本地命令

使用npx 命令时,它会首先从本地工程的node_modules/.bin目录中寻找是否有对应的命令

例如:

npx webpack

上面这条命令寻找本地工程的node_modules/.bin/webpack

如果将命令配置到package.jsonscripts中,可以省略npx

临时下载执行

当执行某个命令时,如果无法从本地工程中找到对应命令,则会把命令对应的包下载到一个临时目录,下载完成后执行,临时目录中的命令会在适当的时候删除

例如:

npx prettyjson 1.json

npx会下载prettyjson包到临时目录,然后运行该命令

如果命令名称和需要下载的包名不一致时,可以手动指定报名

例如@vue/cli是包名,vue是命令名,两者不一致,可以使用下面的命令

npx -p @vue/cli vue create vue-app

npm init

npm init通常用于初始化工程的package.json文件

除此之外,有时也可以充当npx的作用

npm init 包名 # 等效于 npx create-包名
npm init @命名空间 # 等效于 npx @命名空间/create
npm init @命名空间/包名 # 等效于 npx @命名空间/create-包名

ESLint官网:eslint.org/

ESLint民间中文网:eslint.bootcss.com/

ESLint的由来

JavaScript是一个过于灵活的语言,因此在企业开发中,往往会遇到下面两个问题:

  • 如何让所有员工书写高质量的代码?

    比如使用===替代==

  • 如何让所有员工书写的代码风格保持统一?

    比如字符串统一使用单引号

上面两个问题,一个代表着代码的质量,一个代表着代码的风格。

如果纯依靠人工进行检查,不仅费时费力,而且还容易出错。

ESLint由此诞生,它是一个工具,预先配置好各种规则,通过这些规则来自动化的验证代码,甚至自动修复

ESLint的基本使用

安装

npm i -D eslint

如何验证

# 验证单个文件
npx eslint 文件名
# 验证全部文件
npx eslint src/**

配置规则

eslint会自动寻找根目录中的配置文件,它支持三种配置文件:

  • .eslintrc JSON格式
  • .eslintrc.js JS格式
  • .eslintrc.yml YAML格式

这里以.eslintrc.js为例:

// ESLint 配置
module.exports = {
  // 配置规则
  rules: {
    规则名1: 级别,
    规则名2: 级别,
    ...
  },
};

每条规则由名称和级别组成

规则名称决定了要检查什么

规则级别决定了检查没通过时的处理方式

所有的规则名称看这里:

所有级别如下:

  • 0 或 'off':关闭规则
  • 1 或 'warn':验证不通过提出警告
  • 2 或 'error':验证不通过报错,退出程序

在VSCode中及时发现问题

每次都要输入命令发现问题非常麻烦

可以安装VSCode插件ESLint,只要项目的node_modules中有eslint,它就会按照项目根目录下的规则自动检测

使用继承

ESLint的规则非常庞大,全部自定义过于麻烦

一般我们继承其他企业开源的方案来简化配置

这方面做的比较好的是一家叫Airbnb的公司,他们在开发前端项目的时候自定义了一套开源规则,受到全世界的认可

我们只需要安装它即可

# 为了避免版本问题,不要直接安装eslint,直接安装下面的包,会自动安装相应版本的eslint
npm i -D eslint-config-airbnb

然后稍作配置

module.exports = {
    extends: 'airbnb' # 配置继承自 airbnb
}

在框架中使用

一般我们使用脚手架搭建工程,在搭建工程时通常都可以直接设置eslint

企业开发的实际情况

我们要做什么?

  • 安装好VSCode的ESLint插件
  • 学会查看ESLint错误提示