美文网首页webpack学习Web前端之路让前端飞
《前端JavaScript面试技巧》学习笔记(11) 模块化

《前端JavaScript面试技巧》学习笔记(11) 模块化

作者: 一杯浊酒 | 来源:发表于2017-09-25 13:14 被阅读58次

知识点

1: 不使用模块化的情况
2:使用模块化
3: AMD
4: CommonJS


  • 不使用模块化的情况
    有三个文件util.js, a-util.js , a.js ; util.js 是最底层封装的, a-util.js是基于util.js进一步, a.js 直接调用 a-util.js
//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: 这些代码中的函数必须是全局变量,才能暴露给对方使用. 全局变量污染-->
<!--2: 知道要 a.js 引用 a-util.js,但是其他人知道还需要依赖于 util.js吗? -->

不使用模块化的问题:
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.jsa-util.js中没有使用全局变量,不会带来污染和覆盖
3.以上代码只是理想中的效果,用于描述模块化的思想,和实际语法相比略有出入


  • AMD (异步模块定义)
    • A:异步 M:模块 D:定义
    • require.js requirejs.org
    • 全局define函数
    • 全局require函数 (只有 define 过的函数才能被 require)
    • 被依赖 JS会自动异步加载

使用requirejs完成刚才的例子

//util.js
define(function() {
    var util = {

        getFormatDate: function(date, type) {
            var date = new Date();
            var add = function(s) {
                if (s.toString().length === 1) {
                    s = "0" + s;
                }
                return s;
            }
            var year = date.getFullYear();
            var mounth = date.getMonth() + 1;
            var day = date.getDate();

            if (type === 1) {
                var time = add(year) + '-' + add(mounth) + '-' + add(day);
                return time
            }
            if (type === 2) {
                var time = year + '年' + mounth + '月' + day + '日';
                return time
            }
        }
    }
    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(['a.js'], function(a) {
    var date = new Date()
    a.printDate(date)
})
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <p>AMD Test</p>
        <script src="require.js" data-main="main.js"></script>
    </body>
</html>

  • CommonJS
  • CommonJS是 Nodejs模块化规范,现在被大量用前端
  • 前端开发依赖的插件和库,都可以从npm获取
    构建工具高度自动化,使npm成本非常低
  • CommonJS本身不会异步加载JS,而是一次性同步加载出来
  • module.exports = {aaa: ..., bbb: ...} 输出模块,require (xxx.js) 引用模块
    使用CommonJS
//util.js
//需要吐出的内容,直接exports
module.exports = {
    getFormatDate: function(date,type) {
        if (type === 1) {
            return '2017-09-23'
        }
        if (type === 2) {
            return '2017年9月23日'
        }
    }
}

//a-util.js
//需要获取什么东西,直接var一个变量赋值成require('xx.js')
var util = require('util.js')
module.exports = {
    aGetFormatDate: function(date) {
        return util.getFormatDate(date,2)
    }
}
  • AMD 和 CommonJS 的使用场景
  • 需要异步加载 JS, 使用 AMD
  • 使用了 npm 之后,建议使用 CommonJS

  • 用 Webpack 演示构建工具

  • 前提: 首先需要安装node.js, npm

  • npm介绍
    npm(node package manager)nodejs的包管理器,用于node插件管理(包括安装、卸载、管理依赖等)

使用npm安装插件:命令提示符执行`npm install <name> [-g] [--save-dev]`
-g:全局安装 ,全局安装可以通过命令行在任何地方调用它
--save:将保存配置信息至package.json;
-dev:保存至package.json的devDependencies节点,只在开发环境下依赖这个包,不指定-dev将保存至dependencies节点;dependence:依赖
为什么要保存至package.json?因为node插件包相对来说非常庞大,所以不加入版本管理,将配置信息写入package.json并将其加入版本管理,其他开发者对应下载即可(命令提示符执行npm install,则会根据package.json下载所有需要的包,npm install --production只下载dependencies节点的包)
使用npm卸载插件:npm uninstall <name> [-g] [--save-dev]  PS:不要直接删除本地插件包
使用npm更新插件:npm update <name> [-g] [--save-dev]
更新全部插件:npm update [--save-dev]
当前目录已安装插件:npm list
选装cnpm:由于访问国外服务器不稳定,可使用淘宝 npm 镜像,命令提示符执行`npm install cnpm -g --registry=https://registry.npm.taobao.org`
注:cnpm跟npm用法完全一致,只是在执行命令时将npm改为cnpm 即可

步骤:

1: 初始化包的配置

npm init  //把目录当成一个包
package name: (webpack) webpack-test
version: (1.0.0)
description: it's webpack test item
entry point: (index.js)
test command:
git repository:
keywords:
author: tangshuo24@163.com
license: (ISC)
//根据需求填写内容

2:安装 webpack:

  • npm install webpack --save-dev

3: 配置webpack
思路: 通过module.exports 输出一个东西,然后同过 require 去获取,获取之后再将它返回给一个变量,通过这个变量去执行函数

  • package.json文件(配置信息)
{
  "name": "webpack-test",
  "version": "1.0.0",
  "description": "it's webpack test item",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack"
  },
  "author": "tangshuo24@163.com",
  "license": "ISC",
  "dependencies": {
    "jquery": "^3.2.1"
  },
  "devDependencies": {
    "webpack": "^3.6.0"
  }
}
  • webpack.config.js
var path = require('path') //获取node.js 的path对象,不用理解它
var webpack = require('webpack') //获取刚才安装的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()
    ]
}
  • app.js
//app.js //调用npm安装的jQuery
var $ = require('jquery')
var $root = $('#root')
$root.html('<p>这是通过 jQuery 创建的文本</p>')

  • html
<body>
    <div>test</div>
    <div id="root"></div>
    <script src='dist/bundle.js'></script>
</body>

相关文章

网友评论

    本文标题: 《前端JavaScript面试技巧》学习笔记(11) 模块化

    本文链接:https://www.haomeiwen.com/subject/lmorextx.html