模块化本身就是一个面试的问题
知识点#####
- 不使用模块化的情况
函数
//util.js getFormatDate函数
function getFormatDate(date,type){
//type===1返回2017-07-17
//type===2返回2017年7月17日
//...
}
//a-util.js aGetFormatDate函数 使用getFormatDate
function aGetFormatDate(date){
//要求返回 2017年7月17日
return getFormatDate(date,2)
}
//a.js
var dt=new Date()
console.log(aGetFormatDate(dt));
调用
<script type="text/javascript" src="util.js"></script>
<script type="text/javascript" src="a-util.js"></script>
<script type="text/javascript" src="a.js"></script>
1.js文件引入顺序必须遵循函数层级引用的顺序,最先引入util.js,然后a-util.js,以此类推
2.这些代码中的函数必须是全局变量,才能暴露给使用方,会有全局变量污染的问题
3.a.js知道要引用a-util.js,但是它并不知道还依赖于util.js,代码逻辑并不清晰,所以要使用模块化
- 使用模块化
//util.js
export{
getFormatDate:function(date,type){
//type===1返回2017-07-17
//type===2返回2017年7月17日
//...
}
}
//a-util.js
var getFormatDate=require('util.js')
export{
aGetFormatDate:function(date){
//要求返回 2017年7月17日
return getFormatDate(date,2)
}
}
//a.js
var aGetFormatDate=require('a-util.js')
var dt=new Date()
console.log(aGetFormatDate(dt));
1.直接使用<script type="text/javascript" src="a.js"></script>
即可,其它会根据依赖关系自动引用
2.在util.js和a-util.js中没有使用全局变量,不会带来污染和覆盖
3.以上代码只是理想中的效果,用于描述模块化的思想,和实际语法相比略有出入
- AMD
- A:异步 M:模块 D:定义
- require.js <a>requirejs.org</a>
- 全局define函数
- 全局require函数
- 依赖JS会自动异步加载
- 使用requirejs完成刚才的例子
//util.js
define(function(){
var util={
getFormatDate:function(date,type){
if(type===1){
var month=date.getMonth()+1
var day=date.getDate()
if(month<10){
month='0'+month
}
if(day<10){
day='0'+day
}
return date.getFullYear()+'-'+month+'-'+day
}
if(type===2){
return date.getFullYear()+'年'+(date.getMonth()+1)+'月'+date.getDate()+'日'
}
}
}
return util
})
//a-util.js
define(['./util.js'],function(util){
var aUtil={
aGetFormatDate:function(date){
return util.getFormatDate(date,2)
}
}
return aUtil
})
//a.js
define(['./a-util.js'],function(aUtil){
var a={
printDate:function(date){
console.log(aUtil.aGetFormatDate(date))
}
}
return a
})
//main.js
require(['./js/a.js'],function(a){
var date=new Date()
a.printDate(date)
})
//html
<script data-main="./js/main.js" src="https://cdn.bootcss.com/require.js/2.3.3/require.min.js"></script>
-
CommonJS
CommonJS是Nodejs模块化规范,现在被大量用前端
前端开发依赖的插件和库,都可以从npm获取
构建工具高度自动化,使npm成本非常低
CommonJS本身不会异步加载JS,而是一次性同步加载出来
module.exports={aaa:...,bbb:...}
输出模块,require(xxx.js)
引用模块-
使用CommonJS
// util.js
module.exports={
getFormatDate:function(date,type){
if(type===1){
var month=date.getMonth()+1
var day=date.getDate()
if(month<10){
month='0'+month
}
if(day<10){
day='0'+day
}
return date.getFullYear()+'-'+month+'-'+day
}
if(type===2){
return date.getFullYear()+'年'+(date.getMonth()+1)+'月'+date.getDate()+'日'
}
}
}//a-tuil var util=require('util.js') module.exports={ aGetFormatDate:function(date){ return util.getFormatDate(date,2) } }
-
AMD和CommonJS的使用场景
- 需要异步加载,使用AMD
- 使用npm后建议使用CommonJS
-
webpack
安装
npm install webpack --save-dev
使用//webpack.config.js var path=require('path') var webpack=require('webpack') module.exports={ context:path.resolve(__dirname,'./src'), //找到src目录 entry:{ //入口,在src下 app:'./app.js' }, output:{ path:path.resolve(__dirname,'./dist'), //输出至dist目录 filename:'bundle.js' //输出文件名 }, plugins:[ new webpack.optimize.UglifyJsPlugin() //代码压缩 ] } //index.html <body> <div id="root"></div> <script src="dist/bundle.js"></script> </body> //hello.js module.exports={ print:function(){ console.log('hello'); } } //app.js var $=require('jquery') //调用npm安装的jQuery var hello=require('./hello.js') var $root=$('#root') $root.html('<p>这是jquery插入的文字</p>') hello.print()