首页 > requirejs 打包重复问题

requirejs 打包重复问题

通常情况下,使用rquirejs打包的场景,页面都是一个公用的文件,一个私有的页面启动文件。

requirejs只能判断当前文件打包是否重复,却无法来判断页面引入的不同文件之间的重复问题。

当页面引用文件为两个的情况下,可以人工避免文件打包重复的问题(直接在公用文件中合并);但是,页面文件引用数在2-3个时候,这个就比较头疼了。

比如:global.js全局公用,column.js是某个栏目文件,app.js是当前页面私有js。
column.jsapp.js都涉及了某个组件dialog.js时,为了防止重复打包该文件,我可以在column.js中做对dialog.jsrquire操作,而app.js中就不需要该步骤了。但是,某天,我要去掉column.jsdialog.js的依赖,而app.js依然有此依赖,怎么办?

又得一个个地手工改app.js代码?

----------------------更新----------------

实践了下,可以针对global.js,column.js涉及到的插件进行过滤配置。

比如:

var gbExcludeArr = ['dialog','datepicker'];
var columnExcludeArr = ['validator'].concat(gbExcludeArr);

//打包配置
modules: [{
    name: 'global'
}, {
    name: 'column'
}, {
    name: 'app1',//app1.js并不丛属于某个栏目页面
    exclude: gbExcludeArr 
}, {
    name: 'app2',//app2.js丛属于某个栏目页面
    exclude: columnExcludeArr
}]

app.js当然需要require dialog

模块是需要输出自己的接口引用的,app.js里如果不去require,就应当拿不到关于dialog.js的任何信息。如果你在用全局变量传递信息,那要做的就是先去除所有这类传递方式。重新读一遍官网的文档,大量的篇幅都在教你如何封装模块和暴露模块的功能

一句话:因为你根本没有用requireJS管理依赖,自然会陷入和不用requireJS的时候一样的依赖地狱


回答关于重复的问题:解决重复问题不能靠全局变量和『我知道X引用了Y,所以Z里虽然用Y,但我就是不require』,这种做法相当于又没用requireJS。

我这里提供2个解决方案,可以沿着这两种方案的思路,随项目需求来简化/细化。

方案一

你的全站一共有多少JS代码?很多时候所有JS代码一共也不超过200K~500K这个量级,很多时候网站的主要用户是连着宽带的桌面浏览器。这时候,根本没必要做任何拆分,直接全部打包在一起就解决问题了,每个页面都引用全部的JS,然后用类似require(['all'], function(all) { all.页面名字() })之类的方式区分不同页面就好。全站只有一个JS文件,第一页后每一页的JS都完全命中缓存,速度飞快。

方案二

当然你可以举出很多理由来说方案一太过粗暴了。当然我们可以做的细一些,这时候就像题主已经在做的一样,可能会有一个global的概念。那么要做的事情大概是

先说第一件事

global负责申明全局依赖项并且导出所有依赖(并且只做这件事)

直接伪代码(coffee)

#global.coffee
define 'global', ['jquery', 'dialog', 'column'], (jQuery, Dialog, Column)->
    {
        $: jQuery
        Dialog: Dialog
        Column: Column
    }

#dialog.coffee
define 'dialog', ['jquery'], ($)->
    (msg)->
        #随便写写
        $('<p>').text(msg).appendTo(document.body);

#page1.coffee
define 'page1', ['global', '很少用的另一个组件'], (Global, Another)->
    $ = Global.$
    Dialog = Global.Dialog
    #页面逻辑,比如Hello 5秒钟吧
    $dialog = Dialog('hello')
    setTimeout ->
        $dialog.remove();
    , 5000

一句话说的话就是:把希望跨页面公用的组件收束在global中

第二件事

页面脚本依赖global,并且编译时排除global

参考官方的例子

modules: [
    {name: "global"},
    {
        name: "page1",
        exclude: ["global"]
    },
    {
        name: "page2",
        exclude: ["global"]
    },
    ....
]

最后

每个页面加载require/almond、global、page 三个JS(也可以合并require和global)

应该无需解释了

对你的项目我并不了解,但上面两个方案可以支持到最小的到相当大的项目了,总之,如果还在用全局变量传值,真的不如不用requireJS了


确实是个大问题,脚本的引入管理
我现在download了百度的js库
自己改写了一个,却导致重复了,能用百度的产品,自己的产品就不能用了,因为同样的依赖
清了缓存,自己的产品能用了,百度的产品却有指向自己的服务器了
暂时还没法区分2个require

【热门文章】
【热门文章】