zoukankan      html  css  js  c++  java
  • 了解Browserify

    Browserify是一个Javascript的库,可以用来把多个Module打包到一个文件中,并且能很好地应对Modules之间的依赖关系。而Module是封装了属性和功能的单元,是一个Javascript对象,Modules之间可以相互依赖。某种程度上来说,Browserify模仿了Node.js加载Module的方式。一个js文件包含一个Module。所以,Browserify通过读取文件来加载该文件内的Module。

    【module的写法】

    'use strict';
    exports.save = function(tasks){};
    exports.load = function(){};
    exports.clear = function(){};
    

    还可以这么写:

    'use strict';
    module.exports = {
    	save: function(tasks){},
    	load: function(){},
    	clear: function(){}
    };
    

    【module的缓存】

    1、单例模式缓存

    module a

    exports.value = "original";
    

    module b

    var a = require('./a');
    a.value = "changed";
    console.log(a.value);//changed
    

    module c

    var a = require('./a');
    console.log(a.value);//original
    

    module c中的a.value值之所以是original,是因为module c对module a有依赖,而且依赖的是缓存。所以,在默认情况下,module是有缓存的,也可以理解成单例模式。

    2、实例模式缓存

    还可以通过构造函数来创建一个module。

    module a

    module.exports = function(){
      this.value = "original value";  
    };
    

    module b

    var A = require('./a');
    var a = new A();
    a.value = "changed";
    console.log(a.value);//changed
    

    module c

    var A = require('./a');
    var a = new A();
    console.log(a.value);//original
    

    【准备工作】

    • 安装Node.js
    • 安装Browserify:npm install -g browserify

    【明确目标】

    • app这个module包含了和视图交互的逻辑,是整个程序的entry point
    • app这个module依赖tasks这个module,tasks这个module用来管理task list
    • taskRender这个module用来渲染页面,taskData这个module用来保存加载有关task list的数据

    【文件结构】

    .....css/
    ..........tasks.css
    .....js/
    ..........data/
    ...............taskData.js
    ..........renderers/
    ...............taskRenderer.js
    ..........tasks.js
    ..........app.js
    .....index.html

    【代码实现】

    文件结构有了,module的写法也搞清楚了,接下来就实现一遍。

    ① taskData.js 是用来处理数据的一个module

    'use strict';
    
    var STORE_NAME = "tasks";
    
    exports.save = function(tasks){
        localStorage.setItem(STORE_NAME, JSON.stringify(tasks));
    };
    
    exports.load = function(){
        var storedTasks = localStorage.getItem(STORE_NAME);
        if(storedTasks){
            return JSON.parse(storedTasks);
        }
        return [];
    };
    
    exports.clear = function(){
        localStorage.removeItem(STORE_NAME);
    };
    

    ② taskRenderer.js 是用来处理页面相关的一个module

    'use strict';
    
    var $ = require('jquery');
    var taskTemplate = '<li class="task"><input class="complete" type="checkbox" /><input class="description" type="text" /></li>';
    
    //返回一段带值的html
    //task是传入的一个object对象
    function _renderTask(task){
        var $task = $(taskTemplate);
        if(task.complete){
            $task.find(".complete").attr("checked", "checked");
        }
        $task.find(".description").val(task.description);
        return $task;
    }
    
    exports.renderTasks = function(tasks){
        
        //遍历任务获得带值html的数组
        var elementArray = $.map(tasks, _renderTask);
        
        $("#task-list")
            .empty()
            .append(elementArray);
    };
    
    exports.renderNew = function(){
        var $taskList = $("#task-list");
        $taskList.prepend(_renderTask({}));
    }
    

    ③ tasks.js 用到了以上2个module

    'use strict';
    
    var $ = require('jquery');
    var taskData = require('./data/taskData');
    var taskRenderer = require('./renderers/taskRenderer');
    
    exports.add = function () {
        taskRenderer.renderNew();
    };
    
    exports.remove = function (clickEvent) {
        var taskElement = clickEvent.target;
        $(taskElement).closest(".task").remove();
    };
    
    exports.clear = function(){
        taskData.clear();
        exports.render();
    };
    
    exports.save = function(){
        var tasks=[];
        $("#task-list .task").each(function(index, task){
            var $task = $(task);
            tasks.push({
                complete: $task.find(".complete").prop('checked'),
                description: $task.find(".description").val()
            });
        });
        taskData.save(tasks);
    };
    
    exports.cancel = function(){
      exports.render();  
    };
    
    exports.render = function(){
      taskRenderer.renderTasks(taskData.load()); 
    };
    

    ④ app.js 只需要和tasks.js打交道就可以

    'use strict';
    
    var $ = require('jquery');
    var tasks =require('./tasks');
    
    function _addTask(){
        tasks.add();
    }
    
    function _deleteAllTasks(){
        tasks.clear();
    }
    
    function _saveChanges(){
        tasks.save();
    }
    
    function _cancelChanges(){
        tasks.cancel();
    }
    
    function _deleteTask(clientEvent){
        tasks.remove(clientEvent);
    }
    
    
    function _registerEventHandlers(){
        $('#new-task-button').on("click", _addTask);
        $('#delete-all-button').on("click", _deleteAllTasks);
        $('#save-button').on("click",_saveChanges);
        $('#cancel-button').on("click", _cancelChanges);
        $('#task-list').on("click", ".delete-button", _deleteTask);
    }
    
    _registerEventHandlers();
    tasks.render();
    

    ⑤ 使用browserify把所有module捆绑到一个js文件中去:

    browserify srcjsapp.js -o srcjsapp.bundle.js

    ⑥ index.html 只需要引用srcjsapp.bundle.js就可以

    <!DOCTYPE html>
    <html>
        <head>
            <title>Task List</title>
            <link rel="stylesheet" href="css/tasks.css">
        </head>
        <body>
            <header>
                <h1>TaskList</h1>
            </header>
            
            <div class="toolbar">
                <button id="new-task-button">New Task</button>
                <button id="delete-all-button">Delete All</button>
            </div>
            
            <div id="content">
                <ul id="task-list">
                    
                </ul>
                
                <ul id="log-list">
                    
                </ul>
            </div>
            
            <div class="toolbar">
                <button id="save-button">Save</button>
                <button id="cancel-button">Cancel</button>
            </div>
            
            <script src="js/app.bundle.js"></script>
        </body>
    </html>
    

    【如果有很多文件,调试时出错】

    当有很多文件的时候,调试出错,使用Source Map可以方便找到出错的文件和出错的地方。

    现在,有了app.bundle.js文件,以及有了app.js, tasks.js, taskRenderer.js, taskData.js文件们,我们可以在app.bundle.js和其它js文件中创建一个Souce Map.

    browserify srcjsapp.js -o srcjsapp.bundle.js --debug

    这样,会在app.bundle.js文件最后面追加上类似//# sourceMappingURL=data:application/json;,这样在调试的时候会很容易找到出错的文件和出错的位置。

    【修改文件】

    如果此时修改某个js文件呢?我们还需要使用browserify把所有的module依赖关系捆绑到一个文件中,执行如下的命令:

    browserify srcjsapp.js -o srcjsapp.bundle.js

    解决思路:Watchify为此而生,当发现有文件变化,自动运行Browserify。

    全局安装Watchify:npm install -g watchify

    在命令行窗口运行Watchify命令:watchify srcjsapp.js -o srcjsapp.bundle.js --debug -v

    此时保持命令窗口打开着。

    修改某个文件,并保存,发现命令窗口会自动运行:watchify srcjsapp.js -o srcjsapp.bundle.js --debug -v

    【Grunt Browserify】

    Grunt是Javascript Task Runner,也是运行在Node.js之上。

    如何安装Grunt?

    1. npm install -g grunt-cli
    2. npm install grunt --save-dev

    检测版本?

    grunt --version

    在哪个文件中配置?

    一般在根目录下的Gruntfile.js

    Grunt与Browserify的结合?

    npm install grunt-browserify --save-dev

    在根目录下的Gruntfile.js文件:

    module.exports=function(grunt){
        
        //配置
        grunt.initConfig({
            browserify: {
                app: {
                    src: 'templates/src/js/app.js',
                    dest: 'templates/src/js/app.bundle.js',
                    options: {
                        browserifyOptions:{
                            debug: true
                        }
                    }
                }
            }
        });
        
        //加载其它module/plugins
        grunt.loadNpmTasks('grunt-browserify');
        
        //定义task
        grunt.registerTask('default',['browserify']);
    }
    

    【Grunt Watch】

    使用了Grunt以及用Gruntfile.js进行配置之后,每次有文件变化,我们需要在命令行窗口输入gulp命令。能不能自动为我们运行gulp命令呢?

    Grunt Watch出场。

    如何安装Grunt Watch?

    npm install grunt-contrib-watch --save-dev

    修改Gruntfile.js文件

    module.exports=function(grunt){
        
        //配置
        grunt.initConfig({
            browserify: {
                app: {
                    src: 'templates/src/js/app.js',
                    dest: 'templates/src/js/app.bundle.js',
                    options: {
                        browserifyOptions:{
                            debug: true
                        }
                    }
                }
            },
            watch: {
                app: {
                    files: ['templates/src/js/*/*.js'],
                    tasks: ['browserify']
                }
            }
        });
        
        //加载其它module/plugins
        grunt.loadNpmTasks('grunt-browserify');
        grunt.loadNpmTasks('grunt-contrib-watch');
        
        //定义task
        grunt.registerTask('default',['browserify']);
    }
    

    在命令行窗口输入:grunt watch

    现在,修改templates/src/js中的任何js文件,会自动运行browserify命令。

    【Grunt Connect】

    Grunt Connect可以让我们搭建一个web server。

    如何安装?

    npm install grunt-contrib-connect --save-dev

    修改Gruntfile.js文件

    module.exports=function(grunt){
        
        //配置
        grunt.initConfig({
            browserify: {
                app: {
                    src: 'templates/src/js/app.js',
                    dest: 'templates/src/js/app.bundle.js',
                    options: {
                        browserifyOptions:{
                            debug: true
                        }
                    }
                }
            },
            watch: {
                app: {
                    files: ['templates/src/js/*/*.js'],
                    tasks: ['browserify']
                }
            },
            connect: {
                app: {
                    options: {
                        port: 9001,
                        base: 'templates/src'
                    }
                }
            }
        });
        
        //加载其它module/plugins
        grunt.loadNpmTasks('grunt-browserify');
        grunt.loadNpmTasks('grunt-contrib-watch');
        grunt.loadNpmTasks('grunt-contrib-connect');
        
        //定义task
        grunt.registerTask('default',['browserify']);
        grunt.registerTask('serve',['browserify:app', 'connect:app', 'watch:app']);
    }
    

    在命令行窗口输入:grunt serve

    在浏览器窗口输入:localhost:9001

    【Connect Live Reload】

    现在,可以在浏览器中输入localhost:9001浏览到网页内容,此时,如果某个文件有变化,我们需要重新刷新浏览器。web server可以有自动刷新的功能吗?

    Connect Live Reload就是解决这个问题的。

    如何安装?

    npm install connect-livereload --save-dev

    修改Gruntfile.js文件

    module.exports=function(grunt){

        //配置
        grunt.initConfig({
            browserify: {
                app: {
                    src: 'templates/src/js/app.js',
                    dest: 'templates/src/js/app.bundle.js',
                    options: {
                        browserifyOptions:{
                            debug: true
                        }
                    }
                }
            },
            watch: {
                app: {
                    files: ['templates/src/js/*/*.js'],
                    tasks: ['browserify'],
                    options: { //为保持web server 的自动刷新而设置
                        livereload: true
                    }
                }
            },
            connect: {
                app: {
                    options: {
                        port: 9001,
                        base: 'templates/src',
                        middleware: function(connect, options, middlewares){//为保持web server 的自动刷新而设置
                            middlewares.unshift(require('connect-livereload')());
                            return middlewares;
                        }
                    }
                }
            }
        });
        
        //加载其它module/plugins
        grunt.loadNpmTasks('grunt-browserify');
        grunt.loadNpmTasks('grunt-contrib-watch');
        grunt.loadNpmTasks('grunt-contrib-connect');
        
        //定义task
        grunt.registerTask('default',['browserify']);
        grunt.registerTask('serve',['browserify:app', 'connect:app', 'watch:app']);
    }
    

    在命令行窗口输入:grunt serve

    在浏览器中打开:http://localhost:9001/

    修改某个文件,浏览器中自动有变化。

  • 相关阅读:
    C# 从服务器下载文件
    不能使用联机NuGet 程序包
    NPOI之Excel——合并单元格、设置样式、输入公式
    jquery hover事件中 fadeIn和fadeOut 效果不能及时停止
    UVA 10519 !! Really Strange !!
    UVA 10359 Tiling
    UVA 10940 Throwing cards away II
    UVA 10079 Pizze Cutting
    UVA 763 Fibinary Numbers
    UVA 10229 Modular Fibonacci
  • 原文地址:https://www.cnblogs.com/darrenji/p/5492028.html
Copyright © 2011-2022 走看看