(Day27) ESM 模组化拆档

前言

随者前端需求越来越多,前端工程师在管理程序码上的需求也越来越重,幸好 ES6 引入时 JavaScript 有引入的 ESM 的拆档功能,以方便开发者管理程序码,而目前大多数的 JavaScript 套件也有都使用到 ESM 的方法来做开发以及管理,算是前端工程师必学的方法之一了,而 ESM 他的全名是「ES6 Modules or JavaScript Modules」。

ESM 基本介绍

如果要使用 ESM 的模组化,首先必需在 <script> 标签添加 type="module" 这样 JavaScript 变能使用模组化的功能,而这个就模组功能,简单来说就是使用 export 来做汇出动作 、 import 来做汇入动作,而汇出和汇入大致可分成:

  • 预设汇出、预设汇入
  • 具名汇出、具名汇入

由於 预设汇出 一定会搭配 预设汇入 ,具名汇出 一定会搭配 具名汇入 因此接下来就来讲讲这两种状况:

具名汇出、具名汇入

具名汇出

故名思义具名汇出,就会是以有名称的方式将资料汇出,具名汇出在同一个 JS 档案上,并没有限制,可以同一个 JavaScript 档案汇出多此,具名汇出则大致可分为以下几种:

  1. export 後使用 letconst 宣告:
export let str = 'test'
export const array = [1,2,3]
  1. export 後使用函式陈述式:
export function fn() {
  console.log('具名汇出')
}
  1. 将变数资料整合起来使用以物件缩写方式,统一汇出:
let str = 'test'
const array = [1,2,3]
function fn() {
  console.log('具名汇出')
}
export const obj = {
str, array, fn
}

具名汇入

由於具名汇出以经带有名称了,因此当我们使用 具名汇入 时,汇入的名称,会是 和具名汇出 时相同的名称来做汇入动作,而具名汇入一般状况会是 import { ... } form './app.js' 的方式汇入。

/*  具名汇出档案 app.js */
let str = 'test'
const array = [1,2,3]
function fn() {
  console.log('具名汇出')
}
export const obj = {
str, array, fn
}
export const number = 123

// 具名汇入档案
<script type="module">
    import { obj , number } from './app.js' 
    console.log(obj, number)  // obj: { str: "test", array:[1,2,3] , fn: fn() } , 123
 </script>

而具名汇入後其实可以更改名称的,会使用 as 来将具名汇入的档案更改名称:

<script type="module">
    import { obj ,  number as num } from './app.js' // 将 number 改为 num
    console.log(obj, num )  // obj: { str: "test", array:[1,2,3] , fn: fn() } , 123
 </script>

同时具名汇入也可以一口气汇入所有资料,会使用 * 字号时,搭配 as 将汇入的资料,赋予到一个新的变数叫做 app 上,不过实做中这种一口气汇入写法通常较少用到:

<script type="module">
    import  * as app  from './app.js'
    console.log(app.obj, app.number )  // obj: { str: "test", array:[1,2,3] , fn: fn() } , 123
 </script>

预设汇出、预设汇入

预设汇出

当汇出部分使用 export default 就可以知道这组是使用 预设汇出 与 预设汇入,预设汇出同样可以汇出任何资料,字串、阵列、函式,最常见的就会是汇出一个物件,但是无法使用 变数/常数 的形式来汇出,而每个一个 JS 档,只能使用一次预设汇出。

/* app.js */

export default {
  str : 'test',
  array : [1,2,3],
  fn() {
  console.log('预设汇出')
  }
}

预设汇入

由於预设汇出时,并没有使用任何名称,因此汇入时并需使用一个名称来接收资料

import app from './app.js'
console.log(app.str) // test
console.log(app.array) // [1,2,3]
app.fn() // 预设汇出

同时汇入预设、具名

汇出时可同时使用预设汇出、具名汇出,而汇入部分要同时使用两种汇入方法也是 OK 的,不过要使用这种方法,使用上会有个固定的格式。
需要同时使用两种引入方式时,import 会先写入预设汇入部分,设定好後,自定义名称後方会用上逗号将 预设汇入 、具名汇入的名称分开,而逗号後方会是 * as xxx 来将具名汇入一口气汇入进来。

/*  汇出档案 app.js */
let str = 'test'
const array = [1,2,3]
function fn() {
  console.log('具名汇出')
}
export const obj = {
str, array, fn
}
export default   123

// 汇入档案
<script type="module">
    import number , * as obj  from './app.js' // number 是预设汇入, obj 则是具名汇入。 
    console.log(obj, number)  // obj: { str: "test", array:[1,2,3] , fn: fn() } , 123
 </script>

使用 type= module 後的变化

而最後也在补充一下,当我们在 <script> 标签添加 type= module 後其实 JavaScript 会发生一些变化,如下:

  • 各个 Script 作用域独立:
    在原本 JavaScript 中是可以跨 <script> 标签来做资料存取动作,比如:
<script>
  const name = 'Ryder';
 </script>
  
<script>
  console.log(name); // Ryder
</script>

如果在 <script> 标签添加 type= module<script> 标签的作用域都会被独立,是无法在取得另一个 <script> 标签的资料,比如:

<script>
  const name = 'Ryder';
 </script>
  
<script>
  console.log(name); // ReferenceError: name is not defined
</script>
  • 开启严格模式

在 this 章节有提到 简易呼叫 的 this 会指向 window,但当我们在 <script> 标签添加 type= module 後,因为严格模式开启 简易呼叫的 this 会从 window 变为 undefined

使用前:

<script>
function fn() {
  console.log(this) // window
}
fn() 
</script>

使用後:

<script type="module">
function fn() {
  console.log(this) // undefined
}
fn() 
</script>

参考文献


<<:  [Day12] 建立订单交易API_5

>>:  Day12 iPhone捷径-媒体Part2

测试iT邦帮忙,记录学习历程

##测试文,透过iT邦帮忙记录学习历程 Console.Write("Hello iT邦帮...

【没钱买ps,PyQt自己写】Day 14 - 使用 QSlider 制作可拖曳的滑条

看完这篇文章你会得到的成果图 前言 我们接下来的讨论,会基於读者已经先读过我 day5 文章 的架构...

Eloquent ORM - 多型态关联

通常关联都是两两张资料表之间的关系,而多型态关联则是打破这个限制让一张表可以同时关连到两张以上的资料...

【设计+切版30天实作】|Day15 - 来个完美的简约风Footer结束这回合

设计大纲 Landing Page的主要色都偏深色,另外CTA也有用主要色作为背景颜色了,所以这边的...

D-18. SQL & NoSQL、SQL injection、primary key & foreign key

SQL && NoSQL SQL Structured Query Language...