您的位置:首页 > 移动开发 > 微信开发

微信小程序学习之路——模块化

2019-03-28 09:46 405 查看

模块化简介

最早前端JavaScript代码量不大,统一放在一个文件夹内,如下面一段代码:

[code]var name ='weixin',
age=12;
function getName(){
//实现代码
}
function getAge(){
//实现代码
}

 

后来前端代码越来越多,为了便于管理和工作拆分,我们不得不把代码拆分为多个文件,这时将上述代码封装到user.js文件中,需要用时引入页面(或打包到一个文件)就行。初期团队成员少,一切都运行正常,直到团队越来越大,开始有人抱怨:我想定义一name变量但user.js中已经存在,我不得不定义为myName;为什么我在自己代码中定了getAge方法就导致别人代码出问题了呢?通过这种文件拆分的工作我们只是对代码做了物理上的分离,能初步实现多人开发和简单的代码管理,但并没有真正做到作用域的隔离,由于不知道其他文件内已存在的变量名,甚至让全局冲突问题变得更容易、更严重。
再后来为了避免这种全局冲突,大家决定参考Java的方式,引入命名空间和闭包来解决变量冲突问题。于是user.js里的代码变成了如下这样:

[code]Page({
function(){
myProject = myProject || {};//定义全局命名空间
myProject.user ={};
myProject.user.name='weixin';
var age=12;//闭包内变量,外部不能访问
myProject.user.getName = function(){
//实现代码
}
myProject.user.getAge = function(){
//实现代码
}
}
});

 

这样别的同事可以通过myProject.user获取name,调用getName和getAge方法,通过命名空间,的确能缓解大部分冲突,但是为此我们不得不记住很长一串命名空间,同时当我使用user这个空间后,别人就不能使用,这也不能完美地解决问题。同时更可怕的是如果user.js依赖另外一个utils.js,别的同事必须通过阅读user.js源码搞懂这层依赖关系,按顺序引入utils.js、user.js,直接引入user.js将会导致他代码出错,如果utils还依赖别的资源他还得必须搞懂相关的所有依赖,而他仅仅是想调用我的getName方法,这对调用的同事来说无疑是个噩梦。这时我们需要一种新的组织方式,于是诞生了模块化:

  • 模块是一段JavaScript代码,具有统一的基本书写格式。
  • 模块之间通过基本交互规则,能彼此引用,协同工作。

目前模块化的规范不统一,大致可分为CommonJS和ES6两种规范,大家有兴趣可以参考网上相关资料,小程序模块化机制比较接近CommonJS规范,无论哪种规范,学习起来都十分简单。

文件作用域

小程序中一个JavaScript文件就是一个模块,在中国文件中声明的变量和函数只在该文件中有效,不同文件中的相同变量名和函数名是不会相互影响的。模块中可以调用一些全局的方法,如下例中通过调用getApp()获取小程序实例:

[code]App({
myGlobalData:{
/**定义全局属性 */
name:'weixin'
}
});
var myPrivateData ="value1";/**myPrivateData只能在a.js中使用 */
var appData = getApp();
appData.myGlobalData.name+='app';
var myPrivateData= "value2";/**myPrivateData不会和a.js中同名变量冲突 */
var appData = getApp();
/**当a.js在b.js前执行后,这里会输出"weixin app value2" */
cnsole.log(appData.myGlobalData.name+" "+myPrivateData);

模块的使用

模块接口的暴露和引入十分简单:

  • 通过exports暴露接口
  • 通过require(path)引入依赖,path是需要引入的模块文件的相对路径

实例代码如下:

[code]var privateData = 'weixin';
function run(who){
console.log(who+'run');
}
function walk(who){
console.log(who+'walk');
}
module.exports.run=run;
exports.walk = walk;
/**
* 也可以如下写法:
* module.exports={
* run:run,
* walk:walk
* };
*/
var otherMod = require('mod.js');
Page({
onShow:function(){
/**这里会打印出sombody run */
otherMod.run('somebody');
/**这里会打印出sombody walk */
otherMod.walk('somebody');
}
});

需要注意的是:

  • exports是module.exports的一个引用,因此在模块里面随意更改exports的只想会造成未知错误。所以我们更推荐开发者采用module.exports来暴露模块接口,触发你已经很清晰的知道这两者的关系
  • 小程序目前不支持直接引入node_modules,开发者需要使用node_modules时建议拷贝相关代码到小程序目录中

通过模块化我们能实现代码真正的隔离,可以多人并行开发,降低大项目管理难度,对前端工程化具有很大促进作用。

其他

1.JavaScript运行环境

微信小程序逻辑代码运行在三端:iOS、Android和用于调试的开发者工具,这三端是各自不同的三个解析引擎:

  • 在iOS上,小程序的JavaScript代码是运行在JavaScriptCore中。
  • 在Android上,小程序的JavaScript代码是通过X5内核来解析。
  • 在开发工具上,小程序的JavaScript代码是运行在nwjs(chrome内核)中。

虽然尽管三端的环境十分相似,但是至少在目前对一些语法、特性的支持还是有一些区别,在开发过程中要尽可能地在三端进行测试。

2.ES6语法以及API支持
在小程序中,开发者可以使用ES6语法进行编码,在0.10.101000以及之后版本的开发工具中,会默认使用babel将开发者ES6代码转换为三端都能很好支持的ES5的代码,帮助开发者解决环境不同所带来的开发问题。如果没有使用ES6语法,开发者可以在项目设置中关闭这个功能。
转化过程中需要注意:

  • 这种转换只会帮助开发者处理语法上问题,新的ES6的API,例如Promise等需要开发者自行引入Polyfill或者别的类库。
  • 为了提高代码质量,在开启ES6转换功能的情况下,默认启用JavaScript严格模式,请参考“use strict”。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: