最近要把一个seajs项目用grunt构建,使用了grunt-cmd-transport和grunt-cmd-concat。详细的构建说明见:用grunt构建seajs项目
其中有2个要点:
1、源码目录和构建目录,目录结构要保持一致,这个是最重要的。这样require()无论在开发环境还是生产环境,都能加载到需要的模块。至于require()是用相对标识还是用顶级标识,倒是无所谓
require("path/to/module"); require("../module/file");
2、用grunt-cmd-transport提取module_id时,idleading一定要写对,因为seajs要求路径和模块标识要一致
参考这个帖子:grunt-cmd-transport的alias参数
如果用spm构建,可以自动修改require()里的参数,比如:
require("utils/src/utils");
"spm": { "alias":{ "utils/src/utils":"planx/utils/1.0.0/utils" } }
require("planx/utils/1.0.0/utils")
但是使用grunt构建,就没有这个能力,虽然在transport task里也可以配置alias参数,但是效果和spm里的alias完全不同(这句话说错了,见下面的评论)
var utils = require("utils");
options: { alias: { "utils": "utils/src/utils" } }
var utils = require("utils/src/utils");
其实grunt-cmd-transport里的alias参数,作用就相当于seajs.config(),只是模块顶级标识的缩写,和spm中的alias完全不同
虽然这样,alias参数还是有用的,作用就跟seajs.config()里的alias一样
一般中型的项目,目录结构都会比较深,比如:
require("framework/static/util/date");
写起来就会很费劲,写成下面这样显然简单多了:
require("date");
seajs.config({ alias: { 'date': 'frame/static/util/date' } });
但是用grunt构建时,并没有seajs base存在,因此就需要配置:
options: { alias: { "date": "frame/static/util/date" } }
另外,构建后的require(),已经是完整的顶级标识,不是alias缩写,所以构建后的html里,就不需要再次配置seajs.config()了
不过上面的做法还是不太理想,主要有2个问题:
1、每次增加或者减少alias,都需要到Gruntfile.js和html里修改,很不方便
2、Gruntfile.js和html里的alias配置是重复的,如果漏改一处就会有问题
所以更好的办法,是把alias配置单独放到一个配置文件里,Gruntfile和html一起去读取,这样就没问题了:
// alias_info.json { "utils": "uiframework/static/utils/utils", "dialog": "uiframework/static/widgets/dialog/dialog", "datas": "uiframework/static/utils/datas", "keyHandler": "uiframework/static/utils/keyHandler", "errorHandler":"uiframework/static/utils/errorHandler" }
var aliasInfo = grunt.file.readJSON('alias_info.json'); grunt.initConfig({ transport: { options: { alias: aliasInfo }, // 省略……