import

首先我们需要知道的一个常识是,每一个文件都是一个单独的模块。

通过import指令,可以在当前模块中引入其他模块。

观察项目中index.js中的代码

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

我们发现文件中大量使用了import指令。如果把index.js看做是项目的入口文件的话,那么这些由import指令加载的模块,则都是项目所需要的模块。

import React from 'react'为例分析一下具体的使用规则。

  • import表示引入/加载一个模块
  • React可以理解为这个模块的名字。它时react模块在创建时对外提供的所有接口组合成的对象,因此我们在代码中可以使用它来访问react模块提供的接口。例如React.Component。正因为此处是一个对象,因此我们可以使用解析结构的形式来直接获取某个特定的接口。如下:

    import React, { Component } from 'react';
    

    大括号中接口的名字,必须与对外提供的接口名字相同,在某些必要的场合,当我们想要给接口的名字换一个名字时,可以通过as来搞定。

    // 通常修改名字是为了避免冲突
    import React, { Component as OtherName } from 'react';
    
  • from表示模块来自于哪里

  • react 此处的react表示模块的出处。通常情况下应该使用路径的形式表示,例如下面的./index.css,此处这样表示是因为构建工具能够自动识别安装在node_modules中的模块,而不用具体显示真实的路径,此处可以理解为一个简写。

如果观察比较仔细的同学应该已经在index.js的代码中发现了一些奇怪的地方。居然有一个css文件被当成模块加载进来了!

这正是我们所使用的构建工具(webpack)的强大之处,它可以把所有的文件都当做一个模块,css可以是一个模块,图片也可以是一个模块。这样强大的机制让我们能够顺利的把模块化开发的思维往前再推进一步,那就是组件化思维。当然组件化思维不是本书学习的重点,大家可以先行了解,等待基础足够需要进一步学习react时再做深入了解。

除此之外,还有一个比较小的细节,当我们引入.js文件时,可以省略文件后缀名。

import App from './App.js';
// 通常都会省略
import App from './App';

引入的模块都会自行执行一次,因此当我们期望引入的模块仅仅只是执行,但是不必在当前模块使用时,我们就可以直接简单写成:

import './test';
import './style.css';

export

我们知道一个模块需要有向外提供接口的能力。在之前的例子中我们还没有学会模块化语法时,简单粗暴的将对外的接口放在了window对象上。而在ES6的语法中,则是借助export命令来提供对外接口。

我们可以在同一个模块中多次使用export命令对外提供多个接口。

在项目的src目录下创建一个module01.js文件,代码如下:

// src/module01.js
export const name1 = 'TOM';
export const name2 = 'Jake';

当我们在其他模块(index.js)引入该模块时,如果我们仅仅只是引入其中的某一个接口,那么可以这样做。

import { name1 } from './module01';

但是如果我们需要引入该模块中所有的对外接口,一种方式是在大括号中将所有的名称都列出来,另外一种方式就是使用通配符与as配合。

import { name1, name2 } from './module01';

// or 利用别名的方式
import * as module01 from './module01';
// 那么就有
name1 = module01.name1
name2 = module01.name2

我们还可以通过export default来对外提供接口,这种情况下,对外的接口通常都是一个对象。

// 修改module01.js
const name1 = 'TOM';
const name2 = 'Jake';

export default {
    name1,
    name2
}
// ES6对象的简写语法

那么,在引入模块时的写法我们需要相应的做一些调整。当模块中有export default命令抛出接口时,那么引入模块时就可以直接这样写:

import module01 from './module01';

此时的module01就是export default抛出的对象。

我们接着看一个新的例子,在src目录下创建一个新的文件module02.js。代码如下:

// src/module02.js
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    getName() {
        return this.name
    }
}

export default Person;

在其他模块中使用时:

// src/index.js
import Person from './module02';

const p1 = new Person('Tom', 20);
console.log(p1.getName());

需要注意的是,一个模块中只允许出现一次export default命令。不过可以同时拥有多个export与一个export default.创建一个新模块module03.js

// src/module03.js
export function fn() {
    console.log('this is a function named fn.');
}

export function bar() {
    console.log('hello everybody.');
}

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    getName() {
        return this.name
    }
}

export default Person;

那么当我们引入时,则可以这样写:

import Person, { fn } from './module03';

// 当然也可以全部引用,实践中通常不会这样做
import * as module03 from './module03';

// module03的内容如下
module03 = {
    fn: fn,
    bar: bar,
    default: Person
}

results matching ""

    No results matching ""