js的模块化可以怎么做_jscript和javascript的区别

js的模块化可以怎么做_jscript和javascript的区别写了十年JS却不知道模块化为何物?

大家好,又见面了,我是你们的朋友全栈君。

模块化这个问题并非一开始就存在,WWW刚刚问世的时候,html,JavaScript,CSS(JS和CSS都是后来在网景被引进浏览器的)都是极其简单的存在,不需要模块化。

模块化的需求是规模的产物,当web page进化到web application,浏览器端处理的逻辑越来越复杂,展现的样式和动画越来多,对于工程的要求也就越来越高。于是模块化的需求也就产生了。模块化的意义:

  • 组件的复用,降低开发成本和维护成本
  • 组件单独开发,方便分工合作
  • 模块化遵循标准,方便自动化依赖管理,代码优化,部署

JavaScript长久以来被认为是简单的脚本语言,实际上情况早就发生来变化,在最新版的JavaScript是通用编程语言而不是脚本语言。脚本语言,比如shell并不是用来完成复杂功能的,只是用来做一些自动化控制,是不需要模块化的。而用于构建复杂系统通用编程语言(比如Java)一般都有模块的实现。

1.模块化标准

ES6之前,JavaScript并没有原生的模块机制,好在JavaScript非常灵活,有很多种写法可以将代码天然隔离,起到模块化的功能:

//define

var  modules  =  {}  

modules.mod1  =  {  

  foo  :  function(){...},

  bar  :  function(){...}

  ...

}     //欢迎加入前端全栈开发交流圈一起学习交流:1007317281

//call

modules.mod1.foo()

复制代码

在客户端这种方式基本是够用的,然而问题依然存在:你无法管理依赖,所有的代码都必须load到内存中,需要哪些模块必须由人工处理。分模块是工程化的产物,也是自然发展的结果,自然有很多尝试。很显然,模块之间互相依赖需要编写模块的时候遵循一定的规范。现存的规范还真不少,不知道ES6 能否终结这场混战:

  • AMD
  • CMD
  • closure
  • CommonJS
  • ES6

AMD和CMD分别是requireJS和seaJS定义的标准。使用纯原生的ES5语法意味者其只能使用闭包,书写和阅读都很怪异。值得一提的是AngularJS也使用类似的方式,以至于Angular的作者们都受不了,决定在AngularJS 2 使用新的语言AtScript,前端轮子太多,又造了一个,好在这个轮子造的比较好,兼容ES6 TypeScript规范,扯的远了,看看AMD长得啥样:

AMD:

define(['./a',  './b'],  function(a,  b)  {  

  ...

})
复制代码

Closure是google出品的前端工具,Closure提供了一系列工具和库,谷歌自己的多个项目都是使用Closure开发的。closure compiler通过模块间依赖的声明把所有被依赖的文件打包到一起,而且Closure的一大优势是如果采用破坏性压缩(ADVANCED)压缩率极高。

//文件A

goog.provide('module1')  

com.foo.bar  =  {  

 ...

}     //欢迎加入前端全栈开发交流圈一起学习交流:1007317281

//文件B

goog.require('module1')  

var  a  =  com.foo.bar;
复制代码

然而Closure并不完美,不同的文件共享同一个全局对象,所以你不得不这样写 a.b.c=…。

CommonJS是Node.js使用的模块化标准。Node.js对于前端开发者来说不仅仅可以提供一个Server,还是一个完美的开发平台,在Node上使用Grunt/gulp构建web项目是件很爽的事情。Node的模块化声明的方式与Closure类似,只是更进一步,天然隔离了命名空间。上面的代码如果使用CommonJS的模块化规范可以这么写

//文件A

module.exports  =  {...}  

//文件B

var  a  =  require('./foo/bar')

复制代码

browserify让使用CommonJS模块化规范的代码可以运行在客户端上。

2.静态加载与动态加载

在看ES6之前我们先看模块加载的两种方式:

  • 静态加载:在编译阶段进行,把所有需要的依赖打包到一个文件中
  • 动态加载:在运行时加载依赖

AMD标准是动态加载的代表,而CommonJS是静态加载的代表。AMD的目的是用在浏览器上,所以是异步加载的。而NodeJS是运行在服务器上的,同步加载的方式显然更容易被人接收,所以使用了CommonJS。同样的道理,如果静态加载,那就使用同步的加载方式,如果动态加载就必须用异步的加载方式。

那么ES6采用何种加载机制?

ES6既希望用简单的声明方式来完成静态加载,又不愿放弃动态加载的特性,而这两种方式几乎不可能简单的同时实现,所以ES6提供了两种独立的模块加载方法。

2.1 声明的方式

import  {foo}  from module1
复制代码

2.2 通过System.import API的方式

System.import('some_module')  

    .then(some_module  =>  {

        // Use some_module

    })

    .catch(error  =>  {

        ...

    });           //欢迎加入前端全栈开发交流圈一起学习交流:1007317281
复制代码

再看下export的语法,与CommonJS很像,只不过没有了module这个对象,而直接调用export。 可以export任何一个 函数,变量,对象

//expt.js

export function  abc(){}//export 一个命名的function  

export default  function(){}  //export default function  

export num=123  //export 一个数值  

export obj={}  

export  {  obj as  default  };

//import

import expt from  'expt'//default export  

import  {default  as  myModule}  from  'expt'  //rename  

import  {abc,num,obj}  from  'expt'
复制代码

目前来看,使用预编译的方式显然要好于使用动态加载,浏览器对ES6语法支持还很差,如果使用动态加载ES6,在浏览器端要做ES6到ES5的翻译工作,这个显然是重复低效的。但是随着浏览器对ES6支持增强,尤其是浏览器实现了动态加载API后,动态加载的优势就会展现:

  • 更流畅的用户体验,动态加载可以实现类似lazyload的加载方式,将download的时间分散
  • 更简洁的项目,无需预编译,项目可以少配置很多工具
  • HTTP/2的普及更倾向于使用多个小的请求,适合动态加载

3.实践

如果现在使用ES6,可以选择动态加载模块system.js 或者browserify的预编译方法。

使用system.js+babel动态加载依赖。system.js 是ES6动态模块加载的一个实现。写了一个小DEMO:

项目初始化

bower install babel system.js  --save
index.html
    <script src="/bower_components/system.js/dist/system.js"></script>

    <script>

      System.config({

          baseURL  :  "/scripts",

          transpiler  :  'babel',

          map  :  {

            babel:'/bower_components/babel/browser.js'

          }

        }             //欢迎加入前端全栈开发交流圈一起学习交流:1007317281

      )

      System.import('main.js').then(function(m){

        m.default.sayHello()

      })

    </script>
main.js

export  default  {  

  sayHello  :  function(){

    console.log('hello')

  }

}

复制代码

使用gulp+browserify+babel预编译。gulp是一个Node.js平台上的任务管理平台。预编译要做很多配置,非常繁琐,推荐使用yeoman来生成项目骨架。比如使用generator-es6-webapp。

生成非常简单,在项目目录中执行

yo es6-webapp
复制代码

缺少依赖的化安装依赖就好。

4.其他,关于前端化趋势

ES6模块化意味着什么?

更强大的前端,Web技术整体前移。HTML5的发展和某些优秀浏览器的支持让web技术整体前移,以前像渲染这种工作在后端进行是由于浏览器薄弱,且有老IE这种拖后腿捣乱的选手。

简化编程模型,人工管理JS依赖和将多个JS打包这种工作可以不需要了,而配合WebComponents标准,开发Web将不再借助模板引擎和预编译引擎。

前端化还有更深远的影响–在过去浏览器是个工具,现在浏览器是个重要的工具,在未来浏览器就是用户唯一的操作系统。

感谢您的观看,如有不足之处,欢迎批评指正。 获取资料??? 本次给大家推荐一个免费的学习群,里面概括移动应用网站开发,css,html,webpack,vue node angular以及面试资源等。 对web开发技术感兴趣的同学,欢迎加入Q群:???1007317281???,不管你是小白还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天更新视频资料。 最后,祝大家早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。

转载于:https://juejin.im/post/5ccff4d7f265da03973ac1f4

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/106838.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • git提交空目录的方法

    git提交空目录的方法

    2021年10月17日
  • c语言&是什么符号_c语言逗号运算符举例

    c语言&是什么符号_c语言逗号运算符举例C语言中的按位运算符&|^~>分别要怎么用?哪位大虾能详细讲解一下!!.1、按位运算符就是直接对整数在内存中的二进制位进行操作运算。比如,&&运算本来是一个逻辑运算符,但整数与整数之间可以用&进行运算。举个例子,6的二进制是.C语言运算符都有那些!各个运算符表示什么,怎么排列麻烦各位老师下,谢。运算符的种类C语言的运算符可分为以下几类:1.算术运…

  • 论文DepthTrack: Unveiling the Power of RGBD Tracking阅读及代码讲解[通俗易懂]

    论文DepthTrack: Unveiling the Power of RGBD Tracking阅读及代码讲解[通俗易懂]最近终于有了一篇的顶会像样的RGBDtracking的论文了:ICCV2021:DepthTrack:UnveilingthePowerofRGBDTrackingGithub:https://github.com/xiaozai/DeT数据集简介这边看完就随手记录一下关键的部分:主要是创建了个大规模的RGBDtrackingbenchmark:DepthTrack(有数据集之后才能促进算法的研究),当然随之也搞了个baselinetracker—DeT,这也是现在搞d

  • altium designer绘制51单片机最小系统

    altium designer绘制51单片机最小系统一、绘制51单片机原理图库新建原理图库,并ctrl+s保存起来2、画出方框,并放置引脚,如下图。注意:画出第一个引脚后,可以双击修改它的编号为1,之后再次放置引脚时,编号会自动从1开始自加。3、在方框的左右两边放置引脚注意:新拖出来的引脚,带x号的一端,为将来要与导线连接的一端,所以,这一端要朝芯片的外部。按下空格键,可以实时修改引脚的方向4、编辑引脚定义。点击右下角的SCH,打开库浏览器,双击我们刚才建立好的这个原理图库文件(默认名称为Component_1…

  • 安装VS2005 SP1之后无法更改或卸载VS2005的处理方法

    安装VS2005 SP1之后无法更改或卸载VS2005的处理方法经历千辛万苦装上VS2005之后,一直相安无事,但今天想调整一下VS2005的安装项,于是麻利的调出控制面板–>添加删除程序,选中VS2005点“更改/删除”按钮,发现在加载安装控件的时候爆出一个错误,说是VS_Setup.MSI文件找不到,我按照提示所说的路径,即本机的安装位置,发现确实没有,于是又拿出安装盘来点Setup,结果还是说VS_Setup.MSI文件找不到,这次提示的位置是安装

  • java清除session_退出页面自动清除java session方法

    java清除session_退出页面自动清除java session方法在关闭页面时自动清除Sessioncookie,页面缓存。在默认情况下,session对象在关闭浏览器后并不是立刻被销毁,因此,为了考虑系统的安全性,在用户退出时,需要即刻清除session对象,防止他人盗用session对象中的信息。清除session对象内容的主要方法如下:(1)、removeAttribute()方法。该方法是用来删除session对象中保存的指定属性信息。例如:sessi…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号