js模块化之commonjs
前言
我曾经在写前端代码的时候,老是喜欢一个js对应一个页面或者几个js对应一个前端页面,并且感觉不到像后端那样的规范化和高复用度。伴随着这段时间对于前端的学习,自己开始了解到了对象,iife模式,闭包等等。对于js有了新的理解,曾经使用的layui框架会有下面类似的代码,当时真的只能是一脸懵逼。但是当我看了关于js模块化的视频之后,开始渐渐懂得了,那么让我分享一下吧。
//第一种:主动加载jquery模块
layui.use(['jquery', 'layer'], function(){
var $ = layui.$ //重点处
,layer = layui.layer;
//后面就跟你平时使用jQuery一样
$('body').append('hello jquery');
});
//第二种:如果内置的模块本身是依赖jquery,你无需去use jquery,所以上面的写法其实可以是:
layui.use('layer', function(){
var $ = layui.$ //由于layer弹层依赖jQuery,所以可以直接得到
,layer = layui.layer;
//……
});
commonjs
服务器端实现使用node.js
项目目录
image.png
子模块
module1.js
//暴露一个对象
module.exports = {
msg:'yyh',
foo: function (){
console.log('msg',this.msg);
}
}
module2.js
//暴露一个函数
module.exports = function() {
console.log('foo()');
}
module2.js
//exports.xxx
exports.foo = function () {
console.log('foo()');
}
exports.bar = function () {
console.log('bar()');
}
//这里是为测试引入第三方的模块
exports.arr = [11,11,1,2,2,3,4];
app.js
//引入模块到主模块
let module1 = require('./modules/module1');
let module2 = require('./modules/module2');
let module3 = require('./modules/module3');
module1.foo();
module2();
module3.bar();
module3.foo();
我们这里还是用了第三方的模块uniq
所以我们还需要node.js。项目的根路径下面输入。输入之后还会创建package.json
npm init
然后我们输入
npm install uniq
它就会下载模块到项目里面,并且在package.json里面添加依赖。如果里面没有的话说明你的npm是低于5版本所以在后面需要加入--save
才可以。
测试
image.png浏览器端实现使用node.js
创建目录
image.png还是需要使用npm去下载browserify。创建package.json。(当然自己创建也是可以的)
npm init
安装browerserify
都是要输入的~~~
全局:
npm install browserify -g
局部:(开发环境使用,这个模块只是打个包,在运行时不使用。)
npm install browserify --save-dev
代码内容
module1,module2,module3,app里面的内容不变。但是我们知道require这个方法js是认不到的。所以我们需要使用browserify打包处理才行。
在控制台输入
browserify modules/app.js -o js/bundle.js
在js目录下面就会创建bundle.js文件
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
//引入模块到主模块
let module1 = require('./module1');
let module2 = require('./module2');
let module3 = require('./module3');
module1.foo();
module2();
module3.bar();
module3.foo();
},{"./module1":2,"./module2":3,"./module3":4}],2:[function(require,module,exports){
//暴露一个对象
module.exports = {
msg:'yyh',
foo: function (){
console.log('msg',this.msg);
}
}
},{}],3:[function(require,module,exports){
//exports.xxx=value
module.exports = function() {
console.log('foo()');
}
},{}],4:[function(require,module,exports){
//exports.xxx
exports.foo = function () {
console.log('foo()');
}
exports.bar = function () {
console.log('bar()');
}
exports.arr = [11,11,1,2,2,3,4];
},{}]},{},[1]);
参数解释:
bowserify 关键字
-o左边是输入文件,就是我们写的文件。
-o右边是输出文件,输出文件。我们需要在html里面引入的文件
创建html文件,引入的是输出文件bundle.js!!!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/bundle.js"></script>
</head>
<body>
</body>
</html>
测试结果
image.png使用总结
这种方法个人感觉十分简单。需要注意的是exports关键字会和后面的es6的关键字很相似exports。modules.exports和exports.XX最后都是exports对象。然后就是exports.XXX这种可以同时加入多个对象和函数以及属性变量。使用的时候需要注意,是一个对象还是一个方法,执行的时候还是有很大区别的。其次是在引入的时候需要注意浏览器端需要使用browserify打包处理,将输出文件引入html文件可用。
amd和es6明天再讲。因为amd的东西比较绕~~·