찾다
웹 프론트엔드JS 튜토리얼JS에서 모듈성은 어떻게 구현됩니까?

JS에서 모듈성은 어떻게 구현됩니까?

Jan 09, 2018 pm 05:01 PM
javascript성취하다모듈식

Js의 초기 포지셔닝으로 인해(처음에는 지나치게 복잡한 시나리오에 사용될 것이라고 기대하지 않았습니다), 애플리케이션이 더욱 복잡해짐에 따라 모듈화는 해결해야 할 문제가 됩니다. Feimai의 심층 원칙에 맞춰 모듈화의 베일을 들어올리는 것이 필요합니다. 이 글에서는 Js에서 모듈화가 어떻게 구현되는지를 주로 소개하고, 특정 참고 가치가 있는 모듈화의 작동을 자세히 소개합니다. 관심 있는 분들은 더 많은 정보를 얻으실 수 있으니, 모두에게 도움이 되기를 바랍니다.

1. 모듈화로 해결해야 할 문제

어떤 것을 심층적으로 분석하려면 목적을 가지고 살펴보는 것이 필요합니다. 모듈화로 해결해야 할 문제는 한 문장으로 요약됩니다

글로벌 오염 없이 프로젝트 코드의 더 나은 구성

간단한 예를 들기 위해 이제 다음 코드가 있습니다.

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

실제 응용 시나리오에서 , doSomething 은 아주 많은 일을 해야 할 수도 있고 추가 기능은 더 복잡하고 재사용될 수 있으므로 추가 기능을 별도의 파일로 분리하기를 바랍니다. 따라서:

// 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 도입 시 전역 오염을 일으키고 싶지 않습니다.

2. 가져온 모듈을 실행하는 방법

위의 예에서는 코드를 두 개의 모듈로 분할했습니다. 파일에서 전역 오염을 일으키지 않고 예제의 코드가 정상적으로 실행될 수 있도록 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 키워드를 내보내야 합니다. 모듈은 외부 세계와 접촉하는 유일한 전달자입니다. 클로저 익명 함수의 매개변수 및 참조자가 전달한 컨텍스트

2) new Function을 사용하여 코드 문자열을 실행하는 것은 일반적으로 new Function에 익숙하지 않은 것으로 추정됩니다. 함수를 정의하려면 Function 클래스를 사용하여 함수를 직접 생성할 수 있다는 것을 알아야 합니다. 구문은 다음과 같습니다.

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

위 형식에서 각 arg는 매개 변수이고 마지막 매개 변수는 함수 본문(실행할 코드)입니다. ). 이러한 매개변수는 문자열이어야 합니다. 즉, eval과 유사하게 문자열 코드를 실행하는데 사용할 수 있고, eval과 비교하여 특정 변수의 값을 문자열 코드에 매개변수 형태로 전달할 수도 있습니다

3) 만약 표준 내보내기 키워드는 내보내기만 하는데 실제 사용에서는 module.exports를 사용해야 하는 이유에 대해 의문을 품은 적이 있습니까(Node 코드를 작성한 사람은 이에 익숙해야 함). 그렇다면 이 코드에서 답을 찾을 수 있습니다. 내보내기를 사용하면 컨텍스트를 다시 할당해도 컨텍스트에 아무런 영향을 미치지 않습니다(매개변수의 주소가 전달됨). 믿을 수 없다면 코드를 다음 형식으로 변경하고 다시 실행하세요.

데모 결과

3. 코드 로딩 방법

코드 실행 문제를 해결하려면 모듈 파일 코드 로딩 문제도 해결해야 합니다. 위의 예에 따르면 우리의 목표는 모듈을 로드하는 것입니다. 문자열 형식의 파일 코드

노드 컨테이너에서는 모든 모듈 파일이 로컬에 있으므로 로컬 디스크에서 모듈 파일을 읽어서 문자열 코드를 로드한 후 위의 프로세스를 따르기만 하면 됩니다. Node의 내장 모듈이 아닌 코어 모듈과 C++ 모듈의 로딩 및 실행 방법이 거의 동일하다는 사실이 입증되었습니다(새로운 기능은 아니지만 비슷한 방법입니다)

RN/Weex 컨테이너에서는 원격 Bundle.js를 로드해야 하는 경우 Native의 기능을 통해 원격 js 파일을 요청한 다음 이를 문자열 코드로 읽어서 로드할 수 있습니다. (이 논리에 따르면 Node는 원격 js 모듈을 읽을 수 있는 것처럼 보입니다. 대부분의 경우에는 이 작업을 수행할 필요가 없습니다.)

브라우저 환경에서는 모든 JS 모듈을 원격으로 읽어야 합니다. 안타깝게도 브라우저에서 제공하는 기능에 따라 원격 JS 파일을 다음 형식으로 직접 읽을 수 없습니다. ajax를 통한 파일 스트림은 문자열 코드입니다. 전제 조건을 충족할 수 없으면 위의 작업 전략이 작동하지 않으며 다른 방법을 찾을 수 밖에 없습니다

이것이 CommonJs 사양이 있는 이유이고, AMD/CMD 사양도 있는 이유

그럼 어떻습니까? 브라우저에서 완료되었나요? 브라우저에서 Js 컨트롤을 통해 원격 Js 모듈 파일을 동적으로 로드하려면 <script> 노드를 동적으로 삽입해야 합니다.<pre class="brush:php;toolbar:false">// 摘抄自 require.js 的一段代码 var node = config.xhtml ? document.createElementNS(&amp;#39;http://www.w3.org/1999/xhtml&amp;#39;, &amp;#39;html:script&amp;#39;) : document.createElement(&amp;#39;script&amp;#39;); node.type = config.scriptType || &amp;#39;text/javascript&amp;#39;; node.charset = &amp;#39;utf-8&amp;#39;; node.async = true; node.setAttribute(&amp;#39;data-requirecontext&amp;#39;, context.contextName); node.setAttribute(&amp;#39;data-requiremodule&amp;#39;, moduleName); node.addEventListener(&amp;#39;load&amp;#39;, context.onScriptLoad, false); node.addEventListener(&amp;#39;error&amp;#39;, context.onScriptError, false);&lt;p&gt;要知道,设置了 &lt;script&gt; 标签的 src 之后,代码一旦下载完成,就会立即执行,根本由不得你再封装成闭包,所以文件模块需要在定义之初就要做文章,这就是我们说熟知的 AMD/CMD 规范中的 define,开篇的 add.js 需要重新改写一下&lt;/script&gt;&lt;/p&gt; &lt;pre class=&quot;brush:php;toolbar:false&quot;&gt;// add.js 文件 define ('add',function () {   function add (a, b) {    return a + b;   }   return add; })</pre> <p>而对于 define 的实现,最重要的就是将 callback 的执行结果注册到 context 的一个模块数组中:</p> <pre class="brush:php;toolbar:false">  context.modules = {}   function define(name, callback) {     context.modules[name] = callback &amp;&amp; callback()   }</pre> <p>于是 require 就可以从 context.modules 中根据模块名载入模块了,是不是有了一种自己去写一个 “requirejs” 的冲动感</p> <p>具体的 AMD 实现当然还会复杂很多,还需要控制模块载入时序、模块依赖等等,但是了解了这其中的灵魂,想必去精读 require.js 的源码也不是一件困难的事情</p> <p>四、Webpack 中的模块化</p> <p>Webpack 也可以配置异步模块,当配置为异步模块的时候,在浏览器环境同样的是基于动态插入 <script> 的方式载入远程模块。在大多数情况下,模块的载入方式都是类似于 Node 的本地磁盘同步载入的方式</script>

嫑忘记,Webpack 除了有模块化的能力,还是一个在辅助完善开发工作流的工具,也就是说,Webpack 的模块化是在开发阶段的完成的,使用 Webpack 构筑的工作环境,在开发阶段虽然是独立的模块文件,但是在运行时,却是一个合并好的文件

所以 Webpack 是一种在非运行时的模块化方案(基于 CommonJs),只有在配置了异步模块的时候对异步模块的加载才是运行时的(基于 AMD)

五、模块化规范

通用的问题在解决的过程中总会形成规范,上文已经多次提到 CommonJs、AMD、CMD,有必要花点篇幅来讲一讲规范

Js 的模块化规范的萌发于将 Js 扩展到后端的想法,要使得 Js 具备类似于 Python、Ruby 和 Java 那样具备开发大型应用的基础能力,模块化规范是必不可少的。CommonJS 规范的提出,为Js 制定了一个美好愿景,希望 Js 能在任何地方运行,包括但不限于:

  • 服务器端 Js 应用

  • 命令行工具

  • 桌面应用

  • 混合应用

CommonJS 对模块的定义并不复杂,主要分为模块引用、模块定义和模块标识

  1. 模块引用:使用 require 方法来引入一个模块

  2. 模块定义:使用 exports 导出模块对象

  3. 模块标识:给 require 方法传入的参数,小驼峰命名的字符串、相对路径或者绝对路径

模块示意

CommonJs 规范在 Node 中大放异彩并且相互促进,但是在浏览器端,鉴于网络的原因,同步的方式加载模块显然不太实用,在经过一段争执之后,AMD 规范最终在前端场景中胜出(全称 Asynchronous Module Definition,即“异步模块定义”)

什么是 AMD,为什么需要 AMD ?在前述模块化实现的推演过程中,你应该能够找到答案

除此之外还有国内玉伯提出的 CMD 规范,AMD 和 CMD 的差异主要是,前者需要在定义之初声明所有的依赖,后者可以在任意时机动态引入模块。CMD 更接近于 CommonJS

两种规范都需要从远程网络中载入模块,不同之处在于,前者是预加载,后者是延迟加载

相关推荐:

javascript高级模块化require.js的具体使用方法实例分享

Laravel 的模块化开发框架 Notadd RC1

JavaScript使用高级模块化require.js的具体方法详解

위 내용은 JS에서 모듈성은 어떻게 구현됩니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
C/C에서 JavaScript까지 : 모든 것이 어떻게 작동하는지C/C에서 JavaScript까지 : 모든 것이 어떻게 작동하는지Apr 14, 2025 am 12:05 AM

C/C에서 JavaScript로 전환하려면 동적 타이핑, 쓰레기 수집 및 비동기 프로그래밍으로 적응해야합니다. 1) C/C는 수동 메모리 관리가 필요한 정적으로 입력 한 언어이며 JavaScript는 동적으로 입력하고 쓰레기 수집이 자동으로 처리됩니다. 2) C/C를 기계 코드로 컴파일 해야하는 반면 JavaScript는 해석 된 언어입니다. 3) JavaScript는 폐쇄, 프로토 타입 체인 및 약속과 같은 개념을 소개하여 유연성과 비동기 프로그래밍 기능을 향상시킵니다.

JavaScript 엔진 : 구현 비교JavaScript 엔진 : 구현 비교Apr 13, 2025 am 12:05 AM

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

브라우저 너머 : 실제 세계의 JavaScript브라우저 너머 : 실제 세계의 JavaScriptApr 12, 2025 am 12:06 AM

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

Next.js (백엔드 통합)로 멀티 테넌트 SAAS 애플리케이션 구축Next.js (백엔드 통합)로 멀티 테넌트 SAAS 애플리케이션 구축Apr 11, 2025 am 08:23 AM

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.

Next.js (Frontend Integration)를 사용하여 멀티 테넌트 SaaS 응용 프로그램을 구축하는 방법Next.js (Frontend Integration)를 사용하여 멀티 테넌트 SaaS 응용 프로그램을 구축하는 방법Apr 11, 2025 am 08:22 AM

이 기사에서는 Contrim에 의해 확보 된 백엔드와의 프론트 엔드 통합을 보여 주며 Next.js를 사용하여 기능적인 Edtech SaaS 응용 프로그램을 구축합니다. Frontend는 UI 가시성을 제어하기 위해 사용자 권한을 가져오고 API가 역할 기반을 준수하도록합니다.

JavaScript : 웹 언어의 다양성 탐색JavaScript : 웹 언어의 다양성 탐색Apr 11, 2025 am 12:01 AM

JavaScript는 현대 웹 개발의 핵심 언어이며 다양성과 유연성에 널리 사용됩니다. 1) 프론트 엔드 개발 : DOM 운영 및 최신 프레임 워크 (예 : React, Vue.js, Angular)를 통해 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축합니다. 2) 서버 측 개발 : Node.js는 비 차단 I/O 모델을 사용하여 높은 동시성 및 실시간 응용 프로그램을 처리합니다. 3) 모바일 및 데스크탑 애플리케이션 개발 : 크로스 플랫폼 개발은 개발 효율을 향상시키기 위해 반응 및 전자를 통해 실현됩니다.

JavaScript의 진화 : 현재 동향과 미래 전망JavaScript의 진화 : 현재 동향과 미래 전망Apr 10, 2025 am 09:33 AM

JavaScript의 최신 트렌드에는 Typescript의 Rise, 현대 프레임 워크 및 라이브러리의 인기 및 WebAssembly의 적용이 포함됩니다. 향후 전망은보다 강력한 유형 시스템, 서버 측 JavaScript 개발, 인공 지능 및 기계 학습의 확장, IoT 및 Edge 컴퓨팅의 잠재력을 포함합니다.

Demystifying JavaScript : 그것이하는 일과 중요한 이유Demystifying JavaScript : 그것이하는 일과 중요한 이유Apr 09, 2025 am 12:07 AM

JavaScript는 현대 웹 개발의 초석이며 주요 기능에는 이벤트 중심 프로그래밍, 동적 컨텐츠 생성 및 비동기 프로그래밍이 포함됩니다. 1) 이벤트 중심 프로그래밍을 사용하면 사용자 작업에 따라 웹 페이지가 동적으로 변경 될 수 있습니다. 2) 동적 컨텐츠 생성을 사용하면 조건에 따라 페이지 컨텐츠를 조정할 수 있습니다. 3) 비동기 프로그래밍은 사용자 인터페이스가 차단되지 않도록합니다. JavaScript는 웹 상호 작용, 단일 페이지 응용 프로그램 및 서버 측 개발에 널리 사용되며 사용자 경험 및 크로스 플랫폼 개발의 유연성을 크게 향상시킵니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
1 몇 달 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경

SublimeText3 Linux 새 버전

SublimeText3 Linux 새 버전

SublimeText3 Linux 최신 버전

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

Microsoft에서 출시한 강력한 무료 IDE 편집기

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구