4
头图

1 Overview

I have been developing a vue project for a long time, and the usage of export and import is rather vague. I will just follow the gourd to see what others write. I don’t need to report errors or implement the functions. I don’t understand the principles at all. I’m free today, and I will expose them. Really look!

Historically, JavaScript has no concept of modules, just like it has no concept of classes, even css has @import, so the community has developed CommonJS and AMD specifications to implement module loading. For this reason, ES6 has added export and import commands to achieve module functions, and its implementation is incredibly simple, completely replacing CommonJS and AMD, and has now become a common module solution for browsers and servers.

The ES6 module design idea is static. It determines the dependencies of the module and the input and output variables at compile time. That is to say, it completes the module loading at compile time. We call it'compile time loading' or static loading. , The efficiency is naturally much higher than CommonJS. The module function is mainly composed of two commands: export and import.

  • export command specifies the external interface of the module
  • import Command input functions provided by other modules

2、export

A module is an independent file. All the variables inside the file cannot be obtained from the outside. If you want the outside to be able to read a variable inside the module, you must use the export keyword to export the variable. Therefore, when we usually introduce third-party js files (such as particle animation) into the vue project, we often need to change this file and expose the final variables or functions or classes before they can be imported into the vue file through import.
Export can export variables, functions and classes.

// export.js
// bad
export const name = '飘摇的浅樱';
export const age = 17;
export const gender = '女';
export function foo() {
  console.log('函数foo');
}
export class Person {
  constructor(name, age, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
  }
  getInfo() {
    return `姓名:${this.name},性别:${this.gender},年龄:${this.age}`;
  }
}


// good
const name = '飘摇的浅樱';
const age = 17;
const gender = '女';
function foo() {
  console.log('函数foo');
}
class Person {
  constructor(name, age, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
  }
  getInfo() {
    return `姓名:${this.name},性别:${this.gender},年龄:${this.age}`;
  }
}
export { 
  name, 
  age, 
  gender, 
  foo, 
  Person 
};

The above two writing methods are equivalent, but the following writing method is preferred, because you can see which variables are output at a glance at the end of the file.
Variables exported by export can be renamed using the as keyword.

// export.js
const arr = ['html', 'css', 'js']
export { arr as technologies }

// import.js
import { technologies } from './export.js';

The export command specifies the external interface, so a one-to-one correspondence must be established with the variables inside the module.

// 错误写法一
export 10;

// 错误写法二
var n = 10;
export n;

// 正确写法一
export const n = 10;

// 正确写法二
const n = 10;
export {n};

// 正确写法三
const n = 10;
export {n as m};

In the correct way of writing, the value 10 is obtained through the variable n or m when importing. In the wrong way of writing, only the value is output without variables, and the correspondence is lacking.

3、import

After using the export command to define the external interface, you can use the import command to load this module.

// import.js
import { name, age, gender, foo, Person } from './export.js';
console.log(name, age, gender);
foo();
const p = new Person('飘摇的浅樱', 17, '女')
const info = p.getInfo()
console.log(info)
// import.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="import.js" type="module"></script>
</body>
</html>

The results are as follows:
image.png

As can be seen from the example, the variable in the {} of import must have the same name as the variable exported by export, otherwise it cannot be loaded.

import { name1 } from './export.js';

image.png

The variables entered by the import command are read-only, because it is essentially an input interface, so it is not allowed to rewrite the interface in the script that loads the module.

import { obj } from 'export.js';
obj = {};  // Syntax Error : 'obj' is read-only;

4、export default

In the third point, we already know that the variable name of import must be the same as the name of the variable exported by export. This rule leads us to know what the name of the exported variable is in order to import smoothly, which increases the time for us to read the document. Conducive to get started quickly. The emergence of export default is to allow users to load modules without knowing the variables defined in the module. It specifies the default output for the module.

// export.js
const tellYourName = (name) => name
export default tellYourName;

// import.js
import tellName from './export.js'
const name1 = tellName('飘摇的浅樱')
console.log(name1)  // 飘摇的浅樱

image.png

You can see that the tellName after import does not add curly braces {}, and the name is different from the variable name output in export.js, so we don't need to know what the internal export variable name is when referencing a third-party module.
The export default command can only be used once in a module.

5、import()

The import command cannot do the dynamic loading function of node's require, so the ES2020 proposal introduces the import() function to support dynamic loading of modules.

import(spec)

The parameter spec represents the location of the loaded module. The import command can accept whatever parameters the import() function can accept. The only difference is that the latter is dynamically loaded.
The most common application of import() that I have come across is lazy loading of routing. Because when building an application with packaging, the JavaScript package becomes very large and affects page loading. At this time, we divide the components corresponding to different routes into different code blocks, and then load the corresponding components when the routes are accessed. Written as follows:

// index.js
{
  path: 'home',
  component: () => import('@/views/page/home'),
  name: 'home',
  meta: {
    title: '首页'
  },
}

In the above example, it is a familiar routing file. It means that the home component is loaded when the home route is accessed. Other routes use this method, which can greatly reduce the size of the js package and speed up the page loading speed.

The import() function can be used anywhere;
The import() function does not have any static connection relationship with the loaded module;
The import() function is similar to Node's require method, but it is loaded asynchronously.

6. Summary of key knowledge points

(1) ES6 adds export and import commands to implement module loading;
(2) ES6 modules automatically adopt strict mode, regardless of whether you add'use strict;' to the head of the module;
(3) The export command can output variables, functions and classes;
(4) The variable exported by export is the original name, but it can be renamed with the as keyword, and it is the renamed name when it is quoted;
(5) The export command specifies the external interface, so it must have a one-to-one correspondence with the internal variables, functions or classes of the module;
(6) The interface output by the export command and its corresponding value are dynamically bound, which means that the real-time value inside the module can be obtained through this interface;
(7) Import and export commands can only be at the top level of the module, not in code blocks (for example, in functions or if statements);
(8) The import() function can best reflect its value in routing lazy loading and conditional loading;
(9) Compare the meaning of each wording of import:
import '@/style/index.scss';
Execute the loaded module, but do not enter any value

import HelloWorld from "@/components/HelloWorld.vue";
Reference component (export default)

import Vue from 'vue';
Reference Vue module (export default)

import { uploadOss as alias } from '@/utils/upload';
Quote uploadOss and rename it to alias (export)

import { queryList, addUser } from '@/api/home.js';
Refer to variables or functions or classes in home.js (export)

import * as alias from 'vue-router';
Load the entire module (export), alias.xxx

import _, { each, forEach } from 'lodash';
Introduce default methods and other interfaces

Reference address: https://es6.ruanyifeng.com/#docs/module


浅樱
457 声望9 粉丝

那株不起眼的野生小小草终究会蜕变成盛开的樱花。