Maison  >  Article  >  interface Web  >  Explication détaillée des modules ES6

Explication détaillée des modules ES6

青灯夜游
青灯夜游avant
2019-11-29 17:45:452089parcourir

Explication détaillée des modules ES6

Actuellement, presque tous nos projets sont développés sur la base d'outils de build tels que webpack et rollup, et la modularisation est devenue la norme.

Nous n'y sommes pas étrangers. Aujourd'hui, nous allons systématiquement examiner le mécanisme des modules d'ES6 et résumer les opérations courantes et les meilleures pratiques. Nous espérons que cela vous sera utile.

Quelques arrière-plans simples

Prêt à l'emploi, est un mécanisme que nous espérons tous réaliser.

La même chose est vraie en Javascript. Divisez un grand programme Javascript en différentes parties. Quelle partie doit être utilisée, prenez simplement cette partie.

[Recommandations de cours associées : Tutoriel vidéo JavaScript]

Pendant longtemps, NodeJS avait de telles capacités. Plus tard, de plus en plus de bibliothèques et de frameworks ont également cette capacité. à modulariser, comme CommonJS, ou une implémentation basée sur le modèle AMD (comme RequireJs), ainsi que les Webpack, Babel, etc.

En 2015, un système modulaire standard est né. C'est le protagoniste dont nous allons parler aujourd'hui - le système modèle ES6.

À première vue, il n'est pas difficile de constater que le système de modèles ES6 est très similaire à la syntaxe CommonJS. Après tout, le système de modèles ES6 vient de l'ère CommonJS et est profondément influencé par CommonJS.

Regardez un exemple simple, comme dans CommonJs : (https://flaviocopes.com/commonjs/)

//file.js
module.exports = value;

// 引入value
const value = require('file.js')

Et dans ES6 :

// const.js
export const value = 'xxx';


import { value } from 'const.js'

La syntaxe est Très similaire.

Nous allons maintenant examiner principalement l'importation et l'exportation, ainsi que plusieurs fonctionnalités associées pour en savoir plus sur les modules ES6.

Les avantages de la modularité

Les principaux avantages de la modularité sont deux points :

1. 避免全局变量污染
2. 有效的处理依赖关系

Avec l'évolution des temps , Les navigateurs ont également commencé à prendre en charge nativement la syntaxe d'importation et d'exportation es6.

Explication détaillée des modules ES6

Regardons d'abord un exemple simple :

<script>
  import { addTextToBody } from &#39;/util.js&#39;;

  addTextToBody(&#39;Modules are pretty cool.&#39;);
</script>

// util.js 
export function addTextToBody(text) {
  const p = document.createElement('p');
  p.textContent = text;
  document.body.appendChild(p);
}

Si vous souhaitez gérer des événements, la même chose est vraie :

Regardons d'abord un exemple simple :

<button>Show Message</button>
<script></script>

// showImport.js
import { showMessage } from '/show.js'

document.getElementById('test').onclick = function() {
  showMessage();
}

// show.js
export function showMessage() {
  alert("Hello World!")
}
Si vous souhaitez gérer des événements, la même chose est vraie :

$ http-server
Si vous souhaitez exécuter cette démo, assurez-vous de configurer un service simple :

// Exporting inpidual features
export let name1, name2, …, nameN; // also var, const
export let name1 = …, name2 = …, …, nameN; // also var, const
export function functionName(){...}
export class ClassName {...}

// Export list
export { name1, name2, …, nameN };

// Renaming exports
export { variable1 as name1, variable2 as name2, …, nameN };

// Exporting destructured assignments with renaming
export const { name1, name2: bar } = o;

// Default exports
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };

// Aggregating modules
export * from …; // does not set the default export
export * as name1 from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export { default } from …;
Sinon, vous verrez une erreur CORS. En ce qui concerne les raisons spécifiques de l'erreur et d'autres détails, ce n'est pas l'objet de cet article. Si vous êtes intéressé, vous pouvez lire le lien suivant pour plus de détails. https://jakearchibald.com/2017/es-modules-in-browsers/

Mode strict

Explication détaillée des modules ES6 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

La déclaration 'use strict' nous est familière et nous l'utilisons souvent à l'ère es5, généralement dans Le but de l'ajout de cette instruction en haut du fichier est de désactiver les parties les moins conviviales de Javascript et de nous aider à écrire un code plus rigoureux. 严格模式禁用 Cette fonctionnalité est activée par défaut dans la syntaxe es6. S'il y a du code moins strict dans le code, une erreur sera signalée, par exemple :

  • Variables can’t be left undeclared
  • . ci-dessous, j'ai pris quelques parties qui étaient
  • dans Function parameters de MDN : unique names
  • with
  • read-only properties doivent avoir
  • (ou sont considérées comme des erreurs de syntaxe)
  • Octal numberssyntax errors est interdit
  • Des erreurs sont renvoyées lors de l'affectation à delete undeletable properties
  • delete prop comme 00840 sont
  • evalLes tentatives de
  • lancer une erreur
  • eval
  • est une erreur de syntaxe, au lieu de supposer que delete global[prop]
  • arguments
  • n'introduit pas de nouvelles variables dans sa portée environnante
  • arguments.callee
  • et les arguments ne peuvent pas être liés ou attribués à
  • arguments.caller
  • ne suit pas comme par magie les modifications apportées aux paramètres de la méthode
  • renvoie une TypeError, n'est plus prise en chargefn.caller
  • renvoie une TypeError, qui n'est plus prise en chargeReserved words
  • Le contexte transmis car celui-ci dans les invocations de méthode n'est pas « encadré » (forcé) pour devenir un objet

Ne peut plus utilisez et fn.arguments pour accéder à la pile JavaScript (par exemple protégé, statique, interface, etc.) ne peut pas être lié

Plusieurs utilisations des modules d'exportation

ES6 ne prennent en charge que l'exportation statique. Vous ne pouvez utiliser l'exportation que dans la portée la plus externe du module et ne pouvez pas l'utiliser dans des instructions conditionnelles. portée.

Au niveau de classification, il existe trois principaux types d'exportations :

1. Exportations nommées (zéro exportation ou plus par module)

2. module)

3. Exportations hybridesAperçu des exportations :
//------ lib.js ------
export const sqrt = Math.sqrt;

export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

//------ main.js 使用方式1 ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

//------ main.js 使用方式2 ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
Ci-dessous, je présenterai l'utilisation courante des exportations.

1. Named exports (导出每个函数/变量)

具名导出,这种方式导出多个函数,一般使用场景比如 utils、tools、common 之类的工具类函数集,或者全站统一变量等。

只需要在变量或函数前面加 export 关键字即可。

//------ lib.js ------
export const sqrt = Math.sqrt;

export function square(x) {
    return x * x;
}
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

//------ main.js 使用方式1 ------
import { square, diag } from 'lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

//------ main.js 使用方式2 ------
import * as lib from 'lib';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5

我们也可以直接导出一个列表,例如上面的lib.js可以改写成:

//------ lib.js ------
const sqrt = Math.sqrt;
function square(x) {
    return x * x;
}
function add (x, y) {
    return x + y;
}
export { sqrt, square, add }

2. Default exports (导出一个默认 函数/类)

这种方式比较简单,一般用于一个类文件,或者功能比较单一的函数文件使用。

一个模块中只能有一个export default默认输出。

export default与export的主要区别有两个:

不需要知道导出的具体变量名, 导入(import)时不需要{}.

//------ myFunc.js ------
export default function () {};

//------ main.js ------
import myFunc from 'myFunc';
myFunc();

导出一个类

//------ MyClass.js ------
class MyClass{}

export default MyClass;

//------ Main.js ------
import MyClass from 'MyClass';

注意这里默认导出不需要用{}。

3. Mixed exports (混合导出)

混合导出,也就是 上面第一点和第二点结合在一起的情况。比较常见的比如 Lodash,都是这种组合方式。

//------ lib.js ------
export var myVar = ...;
export let myVar = ...;
export const MY_CONST = ...;

export function myFunc() {
  // ...
}
export function* myGeneratorFunc() {
  // ...
}
export default class MyClass {
  // ...
}

// ------ main.js ------
import MyClass, { myFunc } from 'lib';

再比如lodash例子:

//------ lodash.js ------
export default function (obj) {
  // ...
};
export function each(obj, iterator, context) {
  // ...
}
export { each as forEach };

//------ main.js ------
import _, { forEach } from 'lodash';

4. Re-exporting (别名导出)

一般情况下,export输出的变量就是在原文件中定义的名字,但也可以用 as 关键字来指定别名,这样做一般是为了简化或者语义化export的函数名。

//------ lib.js ------
export function getUserName(){
  // ...
};
export function setName(){
  // ...
};

//输出别名,在import的时候可以同时使用原始函数名和别名
export {
  getName as get, //允许使用不同名字输出两次
  getName as getNameV2,
  setName as set
}

5. Module Redirects (中转模块导出)

有时候为了避免上层模块导入太多的模块,我们可能使用底层模块作为中转,直接导出另一个模块的内容如下:

//------ myFunc.js ------
export default function() {...};
 
//------ lib.js ------
export * from 'myFunc';
export function each() {...};
 
//------ main.js ------
import myFunc, { each } from 'lib';

export 只支持在最外层静态导出、只支持导出变量、函数、类,如下的几种用法都是错误的。

`错误`的export用法:

//直接输出变量的值
export 'Mark';

// 未使用中括号 或 未加default
// 当只有一个导出数,需加default,或者使用中括号
var name = 'Mark';
export name;

//export不要输出块作用域内的变量
function () {
  var name = 'Mark';
  export  { name };
}

import的几种用法

import的用法和export是一一对应的,但是import支持静态导入和动态导入两种方式,动态import支持晚一些,兼容性要差一些。

Explication détaillée des modules ES6

下面我就总结下import的基本用法:

1. Import All things

当export有多个函数或变量时,如文中export的第一点,可以使用 * as 关键字来导出所有函数及变量,同时 as 后面跟着的名称做为 该模块的命名空间。

//导出lib的所有函数及变量
import * as lib from 'lib';

//以 lib 做为命名空间进行调用,类似于object的方式
console.log(lib.square(11)); // 121

2. Import a single/multiple export from a module

从模块文件中导入单个或多个函数,与 * as namepage 方式不同,这个是按需导入。如下例子:

//导入square和 diag 两个函数
import { square, diag } from 'lib';

// 只导入square 一个函数
import { square } from 'lib';

// 导入默认模块
import _ from 'lodash';

// 导入默认模块和单个函数,这样做主要是简化单个函数的调用
import _, { each } from 'lodash';

3. Rename multiple exports during import

和 export 一样,也可以用 as 关键字来设置别名,当import的两个类的名字一样时,可以使用 as 来重设导入模块的名字,也可以用as 来简化名称。
比如:

// 用 as 来 简化函数名称
import {
  reallyReallyLongModuleExportName as shortName,
  anotherLongModuleName as short
} from '/modules/my-module.js';

// 避免重名
import { lib as UserLib} from "alib";
import { lib as GlobalLib } from "blib";

4. Import a module for its side effects only

有时候我们只想import一个模块进来,比如样式,或者一个类库。

// 导入样式
import './index.less';

// 导入类库
import 'lodash';

5. Dynamic Imports

静态import在首次加载时候会把全部模块资源都下载下来.

我们实际开发时候,有时候需要动态import(dynamic import)。

例如点击某个选项卡,才去加载某些新的模块:

// 当动态import时,返回的是一个promise
import('lodash')
  .then((lodash) => {
    // Do something with lodash.
  });

// 上面这句实际等同于
const lodash = await import('lodash');

es7的新用法:

async function run() {
    const myModule = await import('./myModule.js');

    const { export1, export2 } = await import('./myModule.js');

    const [module1, module2, module3] =
        await Promise.all([
            import('./module1.js'),
            import('./module2.js'),
            import('./module3.js'),
        ]);
}

run();

总结

以上, 我总结了ES6 Module 的简单背景和 常见的import , export 用法, 但这远远不是它的全部, 篇幅有限,如果想了解更多, 可以看下面的延伸阅读部分(质量都还不错, 可以看看)。

本文来自 js教程 栏目,欢迎学习!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer