- 源码构建前期准备jQuery组织方式构建步骤gruntfile.js文件Running “build:all:*” (build) task参考资料
源码构建
jQuery的代码是分模块书写的,最后通过一系列build的过程,才生产我们日常使用的版本。熟悉它的构建过程,有利于我们了解个各模块,以及组织的方式,便于我们后续自己开发。
前期准备
通过git更新下jquery的最新源码,进入对应的目录,执行npm install,确保本地安装过grunt,如果没有,执行npm install -g grunt-cli。
jQuery组织方式
jQuery的源码是按照AMD的模式组织的,在构建的时候,去掉define结构,形成一个单独的文件。
构建步骤
执行grunt,默认会执行一系列任务,我们可以通过终端查看到其中的具体任务,我在这里再分条列一下:
- Running “build*” (build) task
- Running “jsonlint:pkg” (jsonlint) task
- Running “jsonlint:bower” (jsonlint) task
- Running “jshint:all” (jshint) task
- Running “jshint:dist” (jshint) task
- Running “jscs:src” (jscs) task
- Running “jscs:gruntfile” (jscs) task
- Running “jscs:test” (jscs) task
- Running “jscs:release” (jscs) task
- Running “jscs:tasks” (jscs) task
- Running “uglify:all” (uglify) task
- Running “remove_map_comment” task
- Running “dist:*” (dist) task
- Running “node_smoke_test” task
- Running “compare_size:files” (compare_size) task可以看到,构建任务确实不少。下面我们就依次来分析一下具体的任务负责了什么。具体的任务配置,我们需要查看gruntfile.js文件。
gruntfile.js文件
这是构建工具的入口,我们在这个文件的最后部分可以看到:
// Load grunt tasks from NPM packagesrequire( "load-grunt-tasks" )( grunt );// Integrate jQuery specific tasksgrunt.loadTasks( "build/tasks" );grunt.registerTask( "lint", [ "jsonlint", "jshint", "jscs" ] );grunt.registerTask( "test_fast", [ "node_smoke_test" ] );grunt.registerTask( "test", [ "test_fast", "promises-aplus-tests" ] );// Short list as a high frequency watch taskgrunt.registerTask( "dev", [ "build:*:*", "lint", "uglify", "remove_map_comment", "dist:*" ] );grunt.registerTask( "default", [ "dev", "test_fast", "compare_size" ] );
这里注册了grunt的插件,以及默认的构建任务,比如我们将要看到的grunt其实,就是grunt default,是一系列任务的组合。这里还加载了build/tasks下的构建任务。
Running “build*” (build) task
这个就是构建出开发版本的过程,我们先来看一下默认的build/task/build.js文件。这个文件确切定义了build任务,在文件的尾部,我们可以看到:
// Trace dependencies and concatenate filesrequirejs.optimize( config, function( response ) { grunt.verbose.writeln( response ); grunt.log.ok( "File '" + name + "' created." ); done();}, function( err ) { done( err );});
这里通过requireJS的压缩,达到build的效果。主要的参数是通过config传入的,查看这个参数,我们会发现一个onBuildWrite选项,这会在构建的时候,帮我们执行去除define的效果,达到合并文件的目的。我们在convert中打印一下参数,可以查看到jQuery到底合并了哪些模块以及其对应的路径,默认情况下是依赖config下定义的src+name文件形成依赖关系:
====convert: var/arr /Users/leohxj/workspaces/github/jquery/src/var/arr.js====convert: var/document /Users/leohxj/workspaces/github/jquery/src/var/document.js====convert: var/slice /Users/leohxj/workspaces/github/jquery/src/var/slice.js====convert: var/concat /Users/leohxj/workspaces/github/jquery/src/var/concat.js====convert: var/push /Users/leohxj/workspaces/github/jquery/src/var/push.js====convert: var/indexOf /Users/leohxj/workspaces/github/jquery/src/var/indexOf.js====convert: var/class2type /Users/leohxj/workspaces/github/jquery/src/var/class2type.js====convert: var/toString /Users/leohxj/workspaces/github/jquery/src/var/toString.js====convert: var/hasOwn /Users/leohxj/workspaces/github/jquery/src/var/hasOwn.js====convert: var/support /Users/leohxj/workspaces/github/jquery/src/var/support.js====convert: core /Users/leohxj/workspaces/github/jquery/src/core.js====convert: sizzle /Users/leohxj/workspaces/github/jquery/external/sizzle/dist/sizzle.js====convert: selector-sizzle /Users/leohxj/workspaces/github/jquery/src/selector-sizzle.js====convert: selector /Users/leohxj/workspaces/github/jquery/src/selector.js====convert: traversing/var/rneedsContext /Users/leohxj/workspaces/github/jquery/src/traversing/var/rneedsContext.js====convert: core/var/rsingleTag /Users/leohxj/workspaces/github/jquery/src/core/var/rsingleTag.js====convert: traversing/findFilter /Users/leohxj/workspaces/github/jquery/src/traversing/findFilter.js====convert: core/init /Users/leohxj/workspaces/github/jquery/src/core/init.js====convert: traversing /Users/leohxj/workspaces/github/jquery/src/traversing.js====convert: var/rnotwhite /Users/leohxj/workspaces/github/jquery/src/var/rnotwhite.js====convert: callbacks /Users/leohxj/workspaces/github/jquery/src/callbacks.js====convert: deferred /Users/leohxj/workspaces/github/jquery/src/deferred.js====convert: core/ready /Users/leohxj/workspaces/github/jquery/src/core/ready.js====convert: core/access /Users/leohxj/workspaces/github/jquery/src/core/access.js====convert: data/accepts /Users/leohxj/workspaces/github/jquery/src/data/accepts.js====convert: data/Data /Users/leohxj/workspaces/github/jquery/src/data/Data.js====convert: data/var/dataPriv /Users/leohxj/workspaces/github/jquery/src/data/var/dataPriv.js====convert: data/var/dataUser /Users/leohxj/workspaces/github/jquery/src/data/var/dataUser.js====convert: data /Users/leohxj/workspaces/github/jquery/src/data.js====convert: queue /Users/leohxj/workspaces/github/jquery/src/queue.js====convert: var/pnum /Users/leohxj/workspaces/github/jquery/src/var/pnum.js====convert: var/rcssNum /Users/leohxj/workspaces/github/jquery/src/var/rcssNum.js====convert: css/var/cssExpand /Users/leohxj/workspaces/github/jquery/src/css/var/cssExpand.js====convert: css/var/isHidden /Users/leohxj/workspaces/github/jquery/src/css/var/isHidden.js====convert: css/adjustCSS /Users/leohxj/workspaces/github/jquery/src/css/adjustCSS.js====convert: manipulation/var/rcheckableType /Users/leohxj/workspaces/github/jquery/src/manipulation/var/rcheckableType.js====convert: manipulation/support /Users/leohxj/workspaces/github/jquery/src/manipulation/support.js====convert: event/support /Users/leohxj/workspaces/github/jquery/src/event/support.js====convert: event /Users/leohxj/workspaces/github/jquery/src/event.js====convert: manipulation /Users/leohxj/workspaces/github/jquery/src/manipulation.js====convert: css/defaultDisplay /Users/leohxj/workspaces/github/jquery/src/css/defaultDisplay.js====convert: css/var/rmargin /Users/leohxj/workspaces/github/jquery/src/css/var/rmargin.js====convert: css/var/rnumnonpx /Users/leohxj/workspaces/github/jquery/src/css/var/rnumnonpx.js====convert: css/var/getStyles /Users/leohxj/workspaces/github/jquery/src/css/var/getStyles.js====convert: var/documentElement /Users/leohxj/workspaces/github/jquery/src/var/documentElement.js====convert: css/support /Users/leohxj/workspaces/github/jquery/src/css/support.js====convert: css/curCSS /Users/leohxj/workspaces/github/jquery/src/css/curCSS.js====convert: css/addGetHookIf /Users/leohxj/workspaces/github/jquery/src/css/addGetHookIf.js====convert: css/swap /Users/leohxj/workspaces/github/jquery/src/css/swap.js====convert: css /Users/leohxj/workspaces/github/jquery/src/css.js====convert: effects/Tween /Users/leohxj/workspaces/github/jquery/src/effects/Tween.js====convert: effects /Users/leohxj/workspaces/github/jquery/src/effects.js====convert: queue/delay /Users/leohxj/workspaces/github/jquery/src/queue/delay.js====convert: attributes/support /Users/leohxj/workspaces/github/jquery/src/attributes/support.js====convert: attributes/attr /Users/leohxj/workspaces/github/jquery/src/attributes/attr.js====convert: attributes/prop /Users/leohxj/workspaces/github/jquery/src/attributes/prop.js====convert: attributes/classes /Users/leohxj/workspaces/github/jquery/src/attributes/classes.js====convert: attributes/val /Users/leohxj/workspaces/github/jquery/src/attributes/val.js====convert: attributes /Users/leohxj/workspaces/github/jquery/src/attributes.js====convert: event/alias /Users/leohxj/workspaces/github/jquery/src/event/alias.js====convert: ajax/var/location /Users/leohxj/workspaces/github/jquery/src/ajax/var/location.js====convert: ajax/var/nonce /Users/leohxj/workspaces/github/jquery/src/ajax/var/nonce.js====convert: ajax/var/rquery /Users/leohxj/workspaces/github/jquery/src/ajax/var/rquery.js====convert: ajax/parseJSON /Users/leohxj/workspaces/github/jquery/src/ajax/parseJSON.js====convert: ajax/parseXML /Users/leohxj/workspaces/github/jquery/src/ajax/parseXML.js====convert: ajax /Users/leohxj/workspaces/github/jquery/src/ajax.js====convert: manipulation/_evalUrl /Users/leohxj/workspaces/github/jquery/src/manipulation/_evalUrl.js====convert: wrap /Users/leohxj/workspaces/github/jquery/src/wrap.js====convert: css/hiddenVisibleSelectors /Users/leohxj/workspaces/github/jquery/src/css/hiddenVisibleSelectors.js====convert: serialize /Users/leohxj/workspaces/github/jquery/src/serialize.js====convert: ajax/xhr /Users/leohxj/workspaces/github/jquery/src/ajax/xhr.js====convert: ajax/script /Users/leohxj/workspaces/github/jquery/src/ajax/script.js====convert: ajax/jsonp /Users/leohxj/workspaces/github/jquery/src/ajax/jsonp.js====convert: core/support /Users/leohxj/workspaces/github/jquery/src/core/support.js====convert: core/parseHTML /Users/leohxj/workspaces/github/jquery/src/core/parseHTML.js====convert: ajax/load /Users/leohxj/workspaces/github/jquery/src/ajax/load.js====convert: event/ajax /Users/leohxj/workspaces/github/jquery/src/event/ajax.js====convert: effects/animatedSelector /Users/leohxj/workspaces/github/jquery/src/effects/animatedSelector.js====convert: offset /Users/leohxj/workspaces/github/jquery/src/offset.js====convert: dimensions /Users/leohxj/workspaces/github/jquery/src/dimensions.js====convert: deprecated /Users/leohxj/workspaces/github/jquery/src/deprecated.js====convert: exports/amd /Users/leohxj/workspaces/github/jquery/src/exports/amd.js====convert: jquery /Users/leohxj/workspaces/github/jquery/src/jquery.js
我们也可以指定构建模块,比如使用grunt build:*selector,来确定构建core和selector模块:
====convert: jquery /Users/leohxj/workspaces/github/jquery/src/jquery.js====convert: var/arr /Users/leohxj/workspaces/github/jquery/src/var/arr.js====convert: var/document /Users/leohxj/workspaces/github/jquery/src/var/document.js====convert: var/slice /Users/leohxj/workspaces/github/jquery/src/var/slice.js====convert: var/concat /Users/leohxj/workspaces/github/jquery/src/var/concat.js====convert: var/push /Users/leohxj/workspaces/github/jquery/src/var/push.js====convert: var/indexOf /Users/leohxj/workspaces/github/jquery/src/var/indexOf.js====convert: var/class2type /Users/leohxj/workspaces/github/jquery/src/var/class2type.js====convert: var/toString /Users/leohxj/workspaces/github/jquery/src/var/toString.js====convert: var/hasOwn /Users/leohxj/workspaces/github/jquery/src/var/hasOwn.js====convert: var/support /Users/leohxj/workspaces/github/jquery/src/var/support.js====convert: core /Users/leohxj/workspaces/github/jquery/src/core.js====convert: sizzle /Users/leohxj/workspaces/github/jquery/external/sizzle/dist/sizzle.js====convert: selector-sizzle /Users/leohxj/workspaces/github/jquery/src/selector-sizzle.js====convert: selector /Users/leohxj/workspaces/github/jquery/src/selector.js
参考资料
- How to build your own jQuery
原文: https://leohxj.gitbooks.io/front-end-database/content/jQuery/jQuery-source-code/code-build.html
