美文网首页我爱编程
js模块化构建方案

js模块化构建方案

作者: 大雨_60kg | 来源:发表于2016-12-27 16:39 被阅读0次

    html与js模块化解决方案##

    html 模块以预编译的方式模块编写,例:界面包含三部分(head body footJS同一套项目里面必然会涉及到通用的部分(head footJs),各个界面不同主要在body体。

    js 以模块预加载的方式通过特定的方式去加载模块js代码。模块化js主要以sea.js方式去加载。

    项目初始化

    1. 执行以下命令
    $ npm install
    

    注:可以通过cnpm安装

    1. 构建项目
    $ gulp
    

    目录结构

    /project/
        /dist       # 最终输出和使用的代码目录
            /js     # 最终输出编译后的js文件
            /css    # 最终输出的样式文件
            x.html  # 输出html文件
        /src        # 源文件目录
            /scss   # scss源文件目录
            /js     # js源文件目录
            /html   # html源文件目录
    

    模块讲解

    1.html模块

    html构建方式:

    gulp.task("html", function() {
        var distPath = './dist';
    
        return gulp.src('src/html/*.html')
                   .pipe(includer({ debug : true}))
                   .pipe(replace("{{version}}", dateFormat('YmdHis')))
                   .pipe(htmlmin( { collapseWhitespace : true, minifyCSS : true, minifyJS : true }))
                   .pipe(gulp.dest(distPath))
                   .pipe(notify({ message: "HTML task complete!" }))
    });
    

    配置的解决方案:html模板之间主要以include的方式加载所需模块。类似于tmodJS(artTemplate),压缩html代码最终输出到dist文件中。模块加载方式(例):

    <!-- include "./components/html_head.html" -->
            <title>架手架编译html</title>
        </head>
        <body>
            <div id="layout">
                <!-- include "./components/header.html" -->
                <div id="main">
                    中间内容层
                </div>
                <!-- include "./components/footer.html" -->
            </div>
            <div id="load-module" data-main="p.index"></div>
            <!-- include "./components/global_js.html" -->
        </body>
    </html>
    
    2. js模块化

    在申明之前,先简单了解下html 模块中footJs模块的定义:

            <script type="text/javascript" src="js/sea.js"></script>
            <script>
                var VERSION = "{{version}}";
    
                seajs.config({
                    base  : "./js/",
                    alias : {
                        "jquery" : (!window.addEventListener) ? "jquery-1.11.3.min.js" : "jquery-2.2.4.min.js"
                    },
                    preload: ['jquery'], //使用use之前确保模块已经加载好
                    'map': [
                        [ /^(.*\/js\/(.*)(js|css))(.*)$/i, "$1?v=" + VERSION]
                    ]
                });
                
                seajs.use('app.min', function() {
                    seajs.use('app');
                });
            </script>
    

    VERSION主要配置版本号,做文件加载禁止缓存处理,map中的映射主要是为了加载模块时,添加文件后缀禁止缓存。加载编译后的app.min.js。界面的入口函数都在app.js模块中去控制。那么,如何控制每个界面加载不同的js模块?先看app.js模块定义:

    /**
     * 初始化脚本模块文件
     */
    define(function(require, exports, module) {
        var $  = require("jquery"),
            WD = require("widget");
    
        $(function(){
            var $loadModule = $('#load-module'),
                loadModule  = $loadModule.attr('data-main');
        
            console.log('app.js 初始化脚本模块文件');
    
            if (loadModule) {
                require(loadModule); // 动态加载页面模块文件
            }
        });
    });
    

    所有界面的入口执行函数都在app.js中通过获取html每个界面body模板中定义的data-main中的参数动态加载相应的界面以来文件。例如上述例子中定义的data-main="p.index" 在界面开始执行入口主函数app.js后,会加载p.index.js模块。再看p.index模块定义:

    /**
     * 首页脚本模块文件
     */
    define(function(require, exports, module) {
        var $  = require('jquery');
        var WD = require('widget');
      
        console.log('p.index', WD);
        console.log($);
        ....
        var dialog = new WD.dialog();
    });
    

    在界面js模块中引入组件模块,业务模块,视图模块,控制模块。执行主函数。其中,每个模块都可以以模块化的方式定义,具体情景看具体的业务定义,以组件模块定义为例:
    定义dialog组件

    /**
     * 一个对话框组件模块
     */
    define(function(require, exports, module) {
        function Dialog() {
            console.log('Dialog');
        }
        
        module.exports = Dialog;
    });
    

    再接着定义全局模块引入所以定义好的组件模块

    /**
     * 公共组件模块文件的模块集合
     */
    define(function(require, exports, module) {
        var dialog = require('./mt.dialog'); // 例:引入一个对话框组件模块
        
        exports.dialog = dialog;
        //....        其它组件模块
        exports.func1 = function() {
            alert('方法1');
        };
    });
    

    在这个组件模块集合中,将所有模块暴露出去。具体调用方式,上述p.index.js模块中有定义。

    构建亮点介绍

    1. 动态的js,css版本控制VERISON
    2. html模板模块划分。
    3. 模块化js脚本,更简洁明了的管理js代码

    缺陷与不足

    1. 图片资源文件没有做处理。
    2. 低版本兼容性没处理(后期再做介绍)
    3. 将sea升级为es6语法

    总结

    此篇与前面两篇scss构建相呼应,可以将scss编译集成到项目里面。其中每个界面的执行脚本,主要通过界面核心(body)模板中声明的data-mian控制加载。以及编译后,动态修改界面引入的js与css文件的版本。有效解决在开发时,重复编译造成的缓存问题。至于此方案中优化的问题(兼容性控制,子模块定义方式,通用模块定义),文章另做详解

    相关文章

      网友评论

        本文标题:js模块化构建方案

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