前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【模块化】:ES6 模块化

【模块化】:ES6 模块化

作者头像
WEBJ2EE
发布2022-03-30 21:05:24
5840
发布2022-03-30 21:05:24
举报
文章被收录于专栏:WebJ2EE
代码语言:javascript
复制
目录
1. ES6 规范 
  1.1. 导出和导入
    1.1.1. Default Exports(默认导出)
    1.1.2. Named Exports(命名导出)
    1.1.3. Import All The Things(导入所有)
    1.1.4. Export All The Things(导出所有)
    1.1.5. Dynamic Import(动态导入)
    1.1.6. import.meta
  1.2. Mutable Bindings
  1.3. Imported Variables Are Read-only
2. classic scripts 和 modules 的差别
3. 新提案:import-maps
  2.1. "bare" import specifiers
  2.2. Import maps

1. ES6 规范

1.1. 导出和导入

1.1.1. Default Exports(默认导出)

代码语言:javascript
复制
// hello-world.js
export default function() {}

// main.js
import helloWorld from './hello-world';
import anotherFunction from './hello-world';

helloWorld();
console.log(helloWorld === anotherFunction);

JavaScript 的值也可以被默认导出

代码语言:javascript
复制
export default 3.14;
export default {foo: 'bar'};
export default 'hello world';

1.1.2. Named Exports(命名导出)

代码语言:javascript
复制
const PI = 3.14;
const value = 42;
export function helloWorld() {}
export {PI, value};

导出的时候还可以重命名

代码语言:javascript
复制
const value = 42;
export {value as THE_ANSWER};

导入变量的时候也可以重命名

代码语言:javascript
复制
import {value as THE_ANSWER} from './module';

1.1.3. Import All The Things(导入所有)

代码语言:javascript
复制
// module.js
export default 3.14;
export const table = {foo: 'bar'};
export function hello() {};

// main.js
import * as module from './module';
console.log(module.default);
console.log(module.table);
console.log(module.hello());

1.1.4. Export All The Things(导出所有)

代码语言:javascript
复制
// module.js
const PI = 3.14;
const value = 42;
export const table = {foo: 'bar'};
export function hello() {};

// main.js
export * from './module';
export {hello} from './module';
export {hello as foo} from './module';

1.1.5. Dynamic Import(动态导入)

代码语言:javascript
复制
import('/modules/my-module.js')
  .then((module) => {
    // Do something with the module.
  });

1.1.6. import.meta

import.meta 是一个给 JavaScript 模块暴露特定上下文的元数据属性的对象。它包含了这个模块的信息,比如说这个模块的URL。

代码语言:javascript
复制
import.meta

1.2. Mutable Bindings

Imported bindings refer to variables inside a module’s body. This causes an interesting sideeffect when you import “by value” variable such as Number, Boolean, or String. It’s possible that the value of that variable will be changed by an operation outside of the importing module.

1.3. Imported Variables Are Read-only

No matter what kind of declaration is being exported from a module, imported variables are always readonly. You can, however, change an imported object’s properties.

代码语言:javascript
复制
// module.js
export let count = 0;
export const table = {foo: 'bar'};

// main.js
import {count, table} from './module;

table.foo = 'Bar'; // OK
count++; // read-only error

2. classic scripts 和 modules 的差别

除了上面这些差异,还有:

  • module 被引入多次,只会执行一次;但 script 会执行多次;
代码语言:javascript
复制
<script src="classic.js"></script>
<script src="classic.js"></script>
<!-- classic.js executes multiple times. -->

<script type="module" src="module.mjs"></script>
<script type="module" src="module.mjs"></script>
<script type="module">import './module.mjs';</script>
<!-- module.mjs executes only once. -->
  • modules 默认是 deferred。classic scripts 则会阻塞 HTML 的解析。

3. 新提案:import-maps

3.1. "bare" import specifiers

首先

在 ES6 的 import 语句中

我们称呼下图红框中的部分为

“module specifier”

When importing modules, the string that specifies the location of the module is called the “module specifier” or the “import specifier”.

在 “module specifier” 中

有些并不是以 "/"、“./”、"../" 开头

我们称呼这些为

“bare import module specifier”

但是HTML官方规范中表示

但凡不是以 "/"、“./”、"../" 开头的

不会被当做相对路径处理

会报错

可是我们的确一直都在写

import {useState} from "react"

import {ref, reactive} from "vue"

没见报错啊?为什么?

代码语言:javascript
复制
import Vue from 'vue'
import _ from 'lodash'
import axios from "axios"

那是因为像 Webpack、Vite 这样的打包工具

已经给你把路径转换工作干了

这有什么问题么?

Today, many web developers are even using JavaScript's native module syntax, but combining it with bare import specifiers, thus making their code unable to run on the web without per-application, ahead-of-time modification. We'd like to solve that, and bring these benefits to the web.

问题就是

原生开发时(不依赖打包工具)你会遇到很多麻烦

1. npm 上多数都是 CJS 的包,需要单独找 ES6 版的包

2. 路径问题太复杂,需要根据运行环境写不同的代码

3.2. Import maps

Importmaps 提案

就是让浏览器原生支持

“bare import specifier”

看一个例子

浏览器兼容性怎么样?

参考:

resolve a module specifier: https://html.spec.whatwg.org/multipage/webappapis.html#integration-with-the-javascript-module-system import-maps: https://github.com/WICG/import-maps Using ES modules in browsers with import-maps: https://blog.logrocket.com/es-modules-in-browsers-with-import-maps/ An Introduction To JavaScript ES6 Modules https://strongloop.com/strongblog/an-introduction-to-javascript-es6-modules/ exploringjs:modules https://exploringjs.com/es6/ch_modules.html#sec_overview-modules JavaScript modules: https://v8.dev/features/modules

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebJ2EE 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档