cari
Rumahhujung hadapan webtutorial jsJs中的模块化是如何实现的

Js中的模块化是如何实现的

Jan 09, 2018 pm 05:01 PM
javascriptcapaiModular

由于 Js 起初定位的原因(刚开始没想到会应用在过于复杂的场景),所以它本身并没有提供模块系统,随着应用的复杂化,模块化成为了一个必须解决的问题。本着菲麦深入原理的原则,很有必要来揭开模块化的面纱,本文主要介绍了详解Js中的模块化是如何实现的,详细的介绍了模块化的运行,具有一定的参考价值,有兴趣的可以了解下,希望能帮助到大家。

一、模块化需要解决的问题

要对一个东西进行深入的剖析,有必要带着目的去看。模块化所要解决的问题可以用一句话概括

在没有全局污染的情况下,更好的组织项目代码

举一个简单的栗子,我们现在有如下的代码:

function doSomething () {
 const a = 10;
 const b = 11;
 const add = function (a + b) {
  return a + b
 }
 add (a + b)
}

在现实的应用场景中,doSomething 可能需要做很多很多的事情,add 函数可能也更为复杂,并且可以复用,那么我们希望可以将 add 函数独立到一个单独的文件中,于是:

// doSomething.js 文件
const add = require('add.js');
const a = 10;
const b = 11;
add(a+ b);
// add.js 文件
function add (a, b) {
 return a + b;
}
module.exports = add;

这样做的目的显而易见,更好的组织项目代码,注意到两个文件中的 require 和 module.exports,从现在的上帝视角来看,这出自 CommonJS 规范(后文会有一个章节来专门讲规范)中的关键字,分别代表导入和导出,抛开规范而言,这其实是我们模块化之路上需要解决的问题。另外,虽然 add 模块需要得到复用,但是我们并不希望在引入 add 的时候造成全局污染

二、引入的模块如何运行

在上述的例子中,我们已经将代码拆分到了两个模块文件当中,在不造成全局污染的情况下,如何实现 require,才能使得例子中的代码做到正常运行呢?

先不考虑模块文件代码的载入过程,假设 require 已经可以从模块文件中读取到代码字符串,那么 require 可以这样实现

function require (path) {
  // lode 方法读取 path 对应的文件模块的代码字符串
  // let code = load(path);
  // 不考虑 load 的过程,直接获得模块 add 代码字符串
  let code = 'function add(a, b) {return a+b}; module.exports = add';
  // 封装成闭包
  code = `(function(module) {$[code]})(context)`
  // 相当于 exports,用于导出对象
  let context = {};
  // 运行代码,使得结果影响到 context
  const run = new Function('context', code);
  run(context, code);
  //返回导出的结果
  return context.exports;
}

这有几个要点:

1) 为了不造成全局污染,需要将代码字符串封装成闭包的形式,并且导出关键字 module.exports ,module 是与外界联系的唯一载体,需要作为闭包匿名函数的入参,与引用方传入的上下文 context 进行关联

2) 使用 new Function 来执行代码字符串,估计大部分同学对 new Function 是不熟悉的,因为一般情况下定义一个函数无需如此,要知道,用 Function 类可以直接创建函数,语法如下:

var function_name = new function(arg1, arg2, ..., argN, function_body)

在上面的形式中,每个 arg 都是一个参数,最后一个参数是函数主体(要执行的代码)。这些参数必须是字符串。也就是说,可以使用它来执行字符串代码,类似于 eval,并且相比 eval, 还可以通过参数的形式传入字符串代码中的某些变量的值

3)如果曾经你有疑惑过为什么规范的导出关键字只有 exports 而我们实际使用过程中却要使用module.exports(写过 Node 代码的应该不会陌生),那在这段代码中就可以找到答案了,如果只用 exports 来接收 context,那么对 exports 的重新赋值对 context 不会有任何影响(参数的地址传递),不信将代码改成如下形式再跑一跑:

演示结果

三、代码载入方式

解决了代码的运行问题,还需要解决模块文件代码的载入问题,根据上述实例,我们的目标是将模块文件代码以字符串的形式载入

在 Node 容器,所有的模块文件都在本地,只需要从本地磁盘读取模块文件载入字符串代码,再走上述的流程就可以了。事实证明,Node 非内建、核心、c++ 模块的载入执行方式大体如此(虽然使用的不是 new Function,但也是一个类似的方法)

在 RN/Weex 容器,要载入一个远程 bundle.js,可以通过 Native 的能力请求一个远程的 js 文件,再读取成字符串代码载入即可(按照这个逻辑,Node 读取一个远程的 js 模块好像也无不可,虽然大多数情况下我们不需要这么做)

在浏览器环境,所有的 Js 模块都需要远程读取,尴尬的是,受限于浏览器提供的能力,并不能通过 ajax 以文件流的形式将远程的 js 文件直接读取为字符串代码。前提条件无法达成,上述运行策略便行不通,只能另辟蹊径

这就是为什么有了 CommonJs 规范了,为什么还会出现 AMD/CMD 规范的原因

那么浏览器上是怎么做的呢?在浏览器中通过 Js 控制动态的载入一个远程的 Js 模块文件,需要动态的插入一个

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
4 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

mPDF

mPDF

mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

SecLists

SecLists

SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

EditPlus versi Cina retak

EditPlus versi Cina retak

Saiz kecil, penyerlahan sintaks, tidak menyokong fungsi gesaan kod

SublimeText3 Linux versi baharu

SublimeText3 Linux versi baharu

SublimeText3 Linux versi terkini

Dreamweaver Mac版

Dreamweaver Mac版

Alat pembangunan web visual