From 8dc7a7793401eb538dc1401c7faa90a2ecd84af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=87=E5=A4=A9?= Date: Mon, 28 Jan 2019 15:55:33 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=BD=8E=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=B5=8F=E8=A7=88=E5=99=A8=E7=9A=84=E5=85=BC=E5=AE=B9=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pack.config.js | 305 ++------------------ src/00-generate.js | 52 +++- src/lib/amd.js | 677 --------------------------------------------- 3 files changed, 79 insertions(+), 955 deletions(-) delete mode 100644 src/lib/amd.js diff --git a/pack.config.js b/pack.config.js index 5a36e4b..c2cc050 100644 --- a/pack.config.js +++ b/pack.config.js @@ -13,115 +13,24 @@ const chokidar = require('chokidar') const uglify = require('uglify-es') const chalk = require('chalk') const log = console.log -const VERSION = '1.0.0' -const PACK_QUEUE = [ - 'anot.js', - 'anot.shim.js', - 'anot-touch.js', - 'anot-touch.shim.js' -] +const VERSION = '2.0.0' + const PACK_DIR = path.resolve('./dist') const SOURCE_DIR = path.resolve('./src/') const PAD_START = Buffer.from(` -var _Anot = (function() { +const _Anot = (function() { `) + const PAD_END = Buffer.from(` -/********************************************************************* - * DOMReady * - **********************************************************************/ - - var readyList = [] - var isReady - var fireReady = function(fn) { - isReady = true - while ((fn = readyList.shift())) { - fn(Anot) - } - } - - if (DOC.readyState === 'complete') { - setTimeout(fireReady) //如果在domReady之外加载 - } else { - DOC.addEventListener('DOMContentLoaded', fireReady) - } - window.addEventListener('load', fireReady) - Anot.ready = function(fn) { - if (!isReady) { - readyList.push(fn) - } else { - fn(Anot) - } - } - var _Anot = window.Anot - Anot.noConflict = function(deep) { - if (deep && window.Anot === Anot) { - window.Anot = _Anot - } - return Anot - } - - window.Anot = Anot - return Anot -})() -module.exports = _Anot -`) -const PAD_END_NEXT = Buffer.from(` - -/********************************************************************* - * css import * - **********************************************************************/ - - var CSS_DEPS = {} - function getBaseUrl() { - if(window.LIBS_BASE_URL){ - return - } - var stack - try { - throw new Error() // 强制报错,以便捕获e.stack - } catch (err) { - stack = err.stack - } - stack = stack.trim().split(/[@ ]+/) - if (window.safari) { - stack = stack[1] - } else { - stack = stack.pop() - } - stack = stack.replace(/(:\\d+)?:\d+([\\w\\W]*)?$/i, '') - window.LIBS_BASE_URL = stack.replace(/^([a-z\-]*):\\/\\/([^\\/]+)(\\/.*)?/, '$1://$2') - } - - function importCss(url, baseUrl) { - url = url.replace(/^\\/+/, '/') - if (baseUrl) { - url = baseUrl + url - } else { - if (window.LIBS_BASE_URL) { - url = window.LIBS_BASE_URL + url - } - } - - if (CSS_DEPS[url]) { - return - } - head.insertAdjacentHTML( - 'afterBegin', - '' - ) - CSS_DEPS[url] = 1 - } - getBaseUrl() - /********************************************************************* * DOMReady * **********************************************************************/ - var readyList = [] - var isReady - var fireReady = function(fn) { + let readyList = [] + let isReady + let fireReady = function(fn) { isReady = true while ((fn = readyList.shift())) { fn(Anot) @@ -142,75 +51,18 @@ const PAD_END_NEXT = Buffer.from(` } } window.importCss = importCss - var _Anot = window.Anot - Anot.noConflict = function(deep) { - if (deep && window.Anot === Anot) { - window.Anot = _Anot - } - return Anot - } - window.Anot = Anot return Anot })() export default _Anot `) -const PAD_START_SHIM = Buffer.from(` -;(function() { -`) -const PAD_END_SHIM = Buffer.from(` -/********************************************************************* - * DOMReady * - **********************************************************************/ - var readyList = [] - var isReady - var fireReady = function(fn) { - isReady = true - var require = Anot.require - if (require && require.checkDeps) { - modules['domReady!'].state = 4 - require.checkDeps() - } - while ((fn = readyList.shift())) { - fn(Anot) - } - } - - if (DOC.readyState === 'complete') { - setTimeout(fireReady) //如果在domReady之外加载 - } else { - DOC.addEventListener('DOMContentLoaded', fireReady) - } - window.addEventListener('load', fireReady) - Anot.ready = function(fn) { - if (!isReady) { - readyList.push(fn) - } else { - fn(Anot) - } - } - // Map over Anot in case of overwrite - var _Anot = window.Anot - Anot.noConflict = function(deep) { - if (deep && window.Anot === Anot) { - window.Anot = _Anot - } - return Anot - } - - window.Anot = Anot -})() -`) - -function comment({ amd, touch, next } = {}) { +function comment({ touch } = {}) { return `/*================================================== - * Anot ${touch ? 'touch' : 'normal'} version ${amd ? 'with AMD loader' : ''} ${ - next ? 'for future browsers' : '' - } + * Anot ${touch ? 'touch' : 'normal'} version for future browsers * @authors yutent (yutent@doui.cc) * @date 2017-03-21 21:05:57 - * support IE10+ and modern browsers + * V${VERSION} * ==================================================*/ ` @@ -247,56 +99,25 @@ function packNoCompress(file) { return BUFFER_CACHE[it] }) let touchModule = fs.cat('./src/lib/touch.js') - let amdModule = fs.cat('./src/lib/amd.js') - let nextVer = Buffer.concat(libs) - let touchNext = Buffer.concat([nextVer, touchModule]) - let shim = Buffer.concat([nextVer, amdModule]) - let touchShim = Buffer.concat([shim, touchModule]) + let normalVer = Buffer.concat(libs) + let touchVer = Buffer.concat([normalVer, touchModule]) /** * -------------------------------------------------------- * 打包未来版的 anot * -------------------------------------------------------- */ - fs.echo( - Buffer.concat([PAD_START, nextVer, PAD_END_NEXT]), - './dist/anot.next.js' - ) - log('%s 打包完成...', chalk.green('anot.next.js')) + fs.echo(Buffer.concat([PAD_START, normalVer, PAD_END]), './dist/anot.js') + log('%s 打包完成...', chalk.green('anot.js')) /** * -------------------------------------------------------- * 打包带触摸事件的未来版的 anot * -------------------------------------------------------- */ - fs.echo( - Buffer.concat([PAD_START, touchNext, PAD_END_NEXT]), - './dist/anot-touch.next.js' - ) - log('%s 打包完成...', chalk.green('anot-touch.next.js')) - - /** - * -------------------------------------------------------- - * 打包自带AMD加载器的 anot - * -------------------------------------------------------- - */ - fs.echo( - Buffer.concat([PAD_START_SHIM, shim, PAD_END_SHIM]), - './dist/anot.shim.js' - ) - log('%s 打包完成...', chalk.green('anot.shim.js')) - - /** - * -------------------------------------------------------- - * 打包自带AMD加载器及触摸事件的 anot - * -------------------------------------------------------- - */ - fs.echo( - Buffer.concat([PAD_START_SHIM, touchShim, PAD_END_SHIM]), - './dist/anot-touch.shim.js' - ) - log('%s 打包完成...', chalk.green('anot-touch.shim.js')) + fs.echo(Buffer.concat([PAD_START, touchVer, PAD_END]), './dist/anot-touch.js') + log('%s 打包完成...', chalk.green('anot-touch.js')) } // 打包并压缩 @@ -305,101 +126,33 @@ function packAndCompress() { return BUFFER_CACHE[it] }) let touchModule = fs.cat('./src/lib/touch.js') - let amdModule = fs.cat('./src/lib/amd.js') - let normal = Buffer.concat(libs) - let touchNormal = Buffer.concat([normal, touchModule]) - let shim = Buffer.concat([normal, amdModule]) - let touchShim = Buffer.concat([shim, touchModule]) - - /** - * -------------------------------------------------------- - * 打包普通版 anot - * -------------------------------------------------------- - */ - log('正在打包 anot.js...') - let normalVer = Buffer.concat([PAD_START, normal, PAD_END]).toString() - fs.echo(comment() + uglify.minify(normalVer).code, './dist/anot.js') - log(chalk.green('anot.js 打包压缩完成!')) - - /** - * -------------------------------------------------------- - * 打包带触摸事件的普通版 anot - * -------------------------------------------------------- - */ - log('正在打包 anot-touch.js...') - let touchNormalVer = Buffer.concat([ - PAD_START, - touchNormal, - PAD_END - ]).toString() - - fs.echo( - comment({ touch: true }) + uglify.minify(touchNormalVer).code, - './dist/anot-touch.js' - ) - - log(chalk.green('anot-touch.js 打包压缩完成...')) - - /** - * -------------------------------------------------------- - * 打包自带AMD加载器的 anot - * -------------------------------------------------------- - */ - log('正在打包 anot.shim.js...') - let shimVer = Buffer.concat([PAD_START_SHIM, shim, PAD_END_SHIM]).toString() - fs.echo( - comment({ amd: true }) + uglify.minify(shimVer).code, - './dist/anot.shim.js' - ) - log(chalk.green('anot.shim.js 打包压缩完成!')) - - /** - * -------------------------------------------------------- - * 打包自带AMD加载器及触摸事件的 anot - * -------------------------------------------------------- - */ - log('正在打包 anot-touch.shim.js...') - let touchShimVer = Buffer.concat([ - PAD_START_SHIM, - touchShim, - PAD_END_SHIM - ]).toString() - fs.echo( - comment({ amd: true, touch: true }) + uglify.minify(touchShimVer).code, - './dist/anot-touch.shim.js' - ) - log(chalk.green('anot-touch.shim.js 打包压缩完成...')) + let normalVer = Buffer.concat(libs) + let touchVer = Buffer.concat([normalVer, touchModule]) /** * -------------------------------------------------------- * 打包未来版的 anot * -------------------------------------------------------- */ - log('正在打包 anot.next.js...') - let nextVer = Buffer.concat([PAD_START, normal, PAD_END_NEXT]).toString() - fs.echo( - comment({ next: true }) + uglify.minify(nextVer).code, - './dist/anot.next.js' - ) - log(chalk.green('anot.next.js 打包压缩完成!')) + log('正在打包 anot.js...') + let normalVerPack = Buffer.concat([PAD_START, normalVer, PAD_END]).toString() + fs.echo(comment() + uglify.minify(normalVerPack).code, './dist/anot.js') + log(chalk.green('anot.js 打包压缩完成!')) /** * -------------------------------------------------------- * 打包带触摸事件的未来版的 anot * -------------------------------------------------------- */ - log('正在打包 anot-touch.next.js...') - let touchNextVer = Buffer.concat([ - PAD_START, - touchNormal, - PAD_END_NEXT - ]).toString() + log('正在打包 anot-touch.js...') + let touchVerPack = Buffer.concat([PAD_START, touchVer, PAD_END]).toString() + fs.echo( - comment({ touch: true, next: true }) + uglify.minify(touchNextVer).code, - './dist/anot-touch.next.js' + comment({ touch: true }) + uglify.minify(touchVerPack).code, + './dist/anot-touch.js' ) - log(chalk.green('anot-touch.next.js 打包压缩完成!')) + log(chalk.green('anot-touch.js 打包压缩完成!')) } let args = process.argv.slice(2) @@ -432,7 +185,5 @@ switch (mode) { break default: log(chalk.red('无效编译参数!')) - let buf = Buffer.concat(loadFiles()) - log(buf.toString()) break } diff --git a/src/00-generate.js b/src/00-generate.js index d0c65e9..c68a5b3 100644 --- a/src/00-generate.js +++ b/src/00-generate.js @@ -1,6 +1,7 @@ /********************************************************************* * 全局变量及方法 * **********************************************************************/ +const CSS_DEPS = {} let bindingID = 1024 let IEVersion = 0 if (window.VBArray) { @@ -11,7 +12,7 @@ let expose = generateID() let DOC = window.document let head = DOC.head //HEAD元素 head.insertAdjacentHTML( - 'afterBegin', + 'afterbegin', '' ) let ifGroup = head.firstChild @@ -86,3 +87,52 @@ function generateID(mark) { mark = (mark && mark + '-') || 'anot-' return mark + (++bindingID).toString(16) } + +/********************************************************************* + * css import * + **********************************************************************/ + +function getBaseUrl() { + if (window.LIBS_BASE_URL) { + return + } + let stack + try { + throw new Error() // 强制报错,以便捕获e.stack + } catch (err) { + stack = err.stack + } + stack = stack.trim().split(/[@ ]+/) + if (window.safari) { + stack = stack[1] + } else { + stack = stack.pop() + } + stack = stack.replace(/(:\\d+)?:\d+([\\w\\W]*)?$/i, '') + window.LIBS_BASE_URL = stack.replace( + /^([a-z\-]*):\/\/([^\/]+)(\/.*)?/, + '$1://$2' + ) +} + +function importCss(url, baseUrl) { + url = url.replace(/^\/+/, '/') + if (baseUrl) { + url = baseUrl + url + } else { + if (window.LIBS_BASE_URL) { + url = window.LIBS_BASE_URL + url + } + } + + if (CSS_DEPS[url]) { + return + } + head.insertAdjacentHTML( + 'afterbegin', + '' + ) + CSS_DEPS[url] = 1 +} + +getBaseUrl() diff --git a/src/lib/amd.js b/src/lib/amd.js deleted file mode 100644 index ca2bc69..0000000 --- a/src/lib/amd.js +++ /dev/null @@ -1,677 +0,0 @@ -/********************************************************************* - * AMD加载器 * - **********************************************************************/ - -//https://www.devbridge.com/articles/understanding-amd-requirejs/ -//http://maxogden.com/nested-dependencies.html -var modules = (Anot.modules = { - 'domReady!': { - exports: Anot, - state: 3 - }, - Anot: { - exports: Anot, - state: 4 - } -}) -//Object(modules[id]).state拥有如下值 -// undefined 没有定义 -// 1(send) 已经发出请求 -// 2(loading) 已经被执行但还没有执行完成,在这个阶段define方法会被执行 -// 3(loaded) 执行完毕,通过onload/onreadystatechange回调判定,在这个阶段checkDeps方法会执行 -// 4(execute) 其依赖也执行完毕, 值放到exports对象上,在这个阶段fireFactory方法会执行 -modules.exports = modules.Anot -var otherRequire = window.require -var otherDefine = window.define -var innerRequire -plugins.loader = function(builtin) { - var flag = innerRequire && builtin - window.require = flag ? innerRequire : otherRequire - window.define = flag ? innerRequire.define : otherDefine -} -new function() { - // jshint ignore:line - var loadings = [] //正在加载中的模块列表 - var factorys = [] //放置define方法的factory函数 - var rjsext = /\.js$/i - - function makeRequest(name, config) { - //1. 去掉querystring, hash - var query = '' - name = name.replace(rquery, function(match) { - query = match - return '' - }) - - //2. 去掉扩展名 - var ext = '.js' //默认拓展名 - var res = 'js' // 默认资源类型 - var suffix = ['.js', '.css'] - name = name.replace(/\.[a-z0-9]+$/g, function(match) { - ext = match - res = suffix.indexOf(match) > -1 ? match.slice(1) : 'text' - return '' - }) - - //补上协议, 避免引入依赖时判断不正确 - if (/^\/\//.test(name)) { - name = location.protocol + name - } - var req = Anot.mix( - { - query: query, - ext: ext, - res: res, - name: name, - toUrl: toUrl - }, - config - ) - req.toUrl(name) - return req - } - - function fireRequest(req) { - var name = req.name - var res = req.res - //1. 如果该模块已经发出请求,直接返回 - var module = modules[name] - var urlNoQuery = name && req.urlNoQuery - if (module && module.state >= 1) { - return name - } - module = modules[urlNoQuery] - if (module && module.state >= 3) { - innerRequire(module.deps || [], module.factory, urlNoQuery) - return urlNoQuery - } - if (name && !module) { - module = modules[urlNoQuery] = { - id: urlNoQuery, - state: 1 //send - } - var wrap = function(obj) { - resources[res] = obj - obj.load(name, req, function(a) { - if (arguments.length && a !== void 0) { - module.exports = a - } - module.state = 4 - checkDeps() - }) - } - - if (!resources[res]) { - innerRequire([res], wrap) - } else { - wrap(resources[res]) - } - } - return name ? urlNoQuery : res + '!' - } - - //核心API之一 require - var requireQueue = [] - var isUserFirstRequire = false - innerRequire = Anot.require = function( - array, - factory, - parentUrl, - defineConfig - ) { - if (!isUserFirstRequire) { - requireQueue.push(Anot.slice(arguments)) - if (arguments.length <= 2) { - isUserFirstRequire = true - var queue = requireQueue.splice(0, requireQueue.length), - args - while ((args = queue.shift())) { - innerRequire.apply(null, args) - } - } - return - } - if (!Array.isArray(array)) { - Anot.error('require方法的第一个参数应为数组 ' + array) - } - var deps = [] // 放置所有依赖项的完整路径 - var uniq = createMap() - var id = parentUrl || 'callback' + setTimeout('1') // jshint ignore:line - - defineConfig = defineConfig || createMap() - defineConfig.baseUrl = kernel.baseUrl - var isBuilt = !!defineConfig.built - if (parentUrl) { - defineConfig.parentUrl = parentUrl.substr(0, parentUrl.lastIndexOf('/')) - defineConfig.mapUrl = parentUrl.replace(rjsext, '') - } - if (isBuilt) { - var req = makeRequest(defineConfig.defineName, defineConfig) - id = req.urlNoQuery - } else { - array.forEach(function(name) { - if (!name) { - return - } - var req = makeRequest(name, defineConfig) - var url = fireRequest(req) //加载资源,并返回该资源的完整地址 - - if (url) { - if (!uniq[url]) { - deps.push(url) - uniq[url] = !0 - } - } - }) - } - - var module = modules[id] - if (!module || module.state !== 4) { - modules[id] = { - id: id, - deps: isBuilt ? array.concat() : deps, - factory: factory || noop, - state: 3 - } - } - if (!module) { - //如果此模块是定义在另一个JS文件中, 那必须等该文件加载完毕, 才能放到检测列队中 - loadings.push(id) - } - checkDeps() - } - - //核心API之二 require - innerRequire.define = function(name, deps, factory) { - //模块名,依赖列表,模块本身 - if (typeof name !== 'string') { - factory = deps - deps = name - name = 'anonymous' - } - if (!Array.isArray(deps)) { - factory = deps - deps = [] - } - var config = { - built: !isUserFirstRequire, //用r.js打包后,所有define会放到requirejs之前 - defineName: name - } - var args = [deps, factory, config] - factory.require = function(url) { - args.splice(2, 0, url) - if (modules[url]) { - modules[url].state = 3 //loaded - var isCycle = false - try { - isCycle = checkCycle(modules[url].deps, url) - } catch (e) {} - if (isCycle) { - Anot.error( - url + - '模块与之前的模块存在循环依赖,请不要直接用script标签引入' + - url + - '模块' - ) - } - } - delete factory.require //释放内存 - innerRequire.apply(null, args) //0,1,2 --> 1,2,0 - } - - //根据标准,所有遵循W3C标准的浏览器,script标签会按标签的出现顺序执行。 - //老的浏览器中,加载也是按顺序的:一个文件下载完成后,才开始下载下一个文件。 - //较新的浏览器中(IE8+ 、FireFox3.5+ 、Chrome4+ 、Safari4+),为了减小请求时间以优化体验, - //下载可以是并行的,但是执行顺序还是按照标签出现的顺序。 - //但如果script标签是动态插入的, 就未必按照先请求先执行的原则了,目测只有firefox遵守 - //唯一比较一致的是,IE10+及其他标准浏览器,一旦开始解析脚本, 就会一直堵在那里,直接脚本解析完毕 - //亦即,先进入loading阶段的script标签(模块)必然会先进入loaded阶段 - var url = config.built ? 'unknown' : getCurrentScript() - if (url) { - var module = modules[url] - if (module) { - module.state = 2 - } - factory.require(url) - } else { - //合并前后的safari,合并后的IE6-9走此分支 - factorys.push(factory) - } - } - //核心API之三 require.config(settings) - innerRequire.config = kernel - //核心API之四 define.amd 标识其符合AMD规范 - innerRequire.define.amd = modules - - //==========================对用户配置项进行再加工========================== - var allpaths = (kernel['orig.paths'] = createMap()) - var allmaps = (kernel['orig.map'] = createMap()) - var allpackages = (kernel['packages'] = []) - var allargs = (kernel['orig.args'] = createMap()) - Anot.mix(plugins, { - paths: function(hash) { - Anot.mix(allpaths, hash) - kernel.paths = makeIndexArray(allpaths) - }, - map: function(hash) { - Anot.mix(allmaps, hash) - var list = makeIndexArray(allmaps, 1, 1) - Anot.each(list, function(_, item) { - item.val = makeIndexArray(item.val) - }) - kernel.map = list - }, - packages: function(array) { - array = array.concat(allpackages) - var uniq = createMap() - var ret = [] - for (var i = 0, pkg; (pkg = array[i++]); ) { - pkg = typeof pkg === 'string' ? { name: pkg } : pkg - var name = pkg.name - if (!uniq[name]) { - var url = joinPath(pkg.location || name, pkg.main || 'main') - url = url.replace(rjsext, '') - ret.push(pkg) - uniq[name] = pkg.location = url - pkg.reg = makeMatcher(name) - } - } - kernel.packages = ret.sort() - }, - urlArgs: function(hash) { - if (typeof hash === 'string') { - hash = { '*': hash } - } - Anot.mix(allargs, hash) - kernel.urlArgs = makeIndexArray(allargs, 1) - }, - baseUrl: function(url) { - if (!isAbsUrl(url)) { - var baseElement = head.getElementsByTagName('base')[0] - if (baseElement) { - head.removeChild(baseElement) - } - var node = DOC.createElement('a') - node.href = url - url = node.href - if (baseElement) { - head.insertBefore(baseElement, head.firstChild) - } - } - if (url.length > 3) kernel.baseUrl = url - }, - shim: function(obj) { - for (var i in obj) { - var value = obj[i] - if (Array.isArray(value)) { - value = obj[i] = { - deps: value - } - } - if (!value.exportsFn && (value.exports || value.init)) { - value.exportsFn = makeExports(value) - } - } - kernel.shim = obj - } - }) - - //==============================内部方法================================= - function checkCycle(deps, nick) { - //检测是否存在循环依赖 - for (var i = 0, id; (id = deps[i++]); ) { - if ( - modules[id].state !== 4 && - (id === nick || checkCycle(modules[id].deps, nick)) - ) { - return true - } - } - } - - function checkFail(node, onError) { - var id = trimQuery(node.src) //检测是否死链 - node.onload = node.onerror = null - if (onError) { - setTimeout(function() { - head.removeChild(node) - node = null // 处理旧式IE下的循环引用问题 - }) - log('加载 ' + id + ' 失败') - } else { - return true - } - } - - function checkDeps() { - //检测此JS模块的依赖是否都已安装完毕,是则安装自身 - loop: for (var i = loadings.length, id; (id = loadings[--i]); ) { - var obj = modules[id], - deps = obj.deps - - if (!deps) continue - for (var j = 0, key; (key = deps[j]); j++) { - if (Object(modules[key]).state !== 4) { - continue loop - } - } - //如果deps是空对象或者其依赖的模块的状态都是4 - if (obj.state !== 4) { - loadings.splice(i, 1) //必须先移除再安装,防止在IE下DOM树建完后手动刷新页面,会多次执行它 - fireFactory(obj.id, obj.deps, obj.factory) - checkDeps() //如果成功,则再执行一次,以防有些模块就差本模块没有安装好 - } - } - } - - function loadJS(url, id, callback) { - //通过script节点加载目标模块 - var node = DOC.createElement('script') - node.className = subscribers //让getCurrentScript只处理类名为subscribers的script节点 - node.onload = function() { - var factory = factorys.pop() - factory && factory.require(id) - if (callback) { - callback() - } - id && loadings.push(id) - checkDeps() - } - node.onerror = function() { - checkFail(node, true) - } - - head.insertBefore(node, head.firstChild) //chrome下第二个参数不能为null - node.src = url //插入到head的第一个节点前,防止IE6下head标签没闭合前使用appendChild抛错,更重要的是IE6下可以收窄getCurrentScript的寻找范围 - } - - var resources = (innerRequire.plugins = { - //三大常用资源插件 js!, css!, text!, domReady! - domReady: { - load: noop - }, - js: { - load: function(name, req, onLoad) { - var url = req.url - var id = req.urlNoQuery - var shim = kernel.shim[name.replace(rjsext, '')] - if (shim) { - //shim机制 - innerRequire(shim.deps || [], function() { - var args = Anot.slice(arguments) - loadJS(url, id, function() { - onLoad(shim.exportsFn ? shim.exportsFn.apply(0, args) : void 0) - }) - }) - } else { - loadJS(url, id) - } - } - }, - css: { - load: function(name, req, onLoad) { - var url = req.url - head.insertAdjacentHTML( - 'afterBegin', - '' - ) - onLoad() - } - }, - text: { - load: function(name, req, onLoad) { - var xhr = getXHR() - xhr.onload = function() { - var status = xhr.status - if (status > 399 && status < 600) { - Anot.error(url + ' 对应资源不存在或没有开启 CORS') - } else { - onLoad(xhr.responseText) - } - } - xhr.open('GET', req.url, true) - xhr.send() - } - } - }) - innerRequire.checkDeps = checkDeps - - var rquery = /(\?[^#]*)$/ - function trimQuery(url) { - return (url || '').replace(rquery, '') - } - - function isAbsUrl(path) { - //http://stackoverflow.com/questions/10687099/how-to-test-if-a-url-string-is-absolute-or-relative - return /^(?:[a-z\-]+:)?\/\//i.test(String(path)) - } - - function getCurrentScript() { - // inspireb by https://github.com/samyk/jiagra/blob/master/jiagra.js - var stack - try { - a.b.c() //强制报错,以便捕获e.stack - } catch (e) { - //safari5的sourceURL,firefox的fileName,它们的效果与e.stack不一样 - stack = e.stack - } - if (stack) { - /**e.stack最后一行在所有支持的浏览器大致如下: - *chrome23: - * at http://113.93.50.63/data.js:4:1 - *firefox17: - *@http://113.93.50.63/query.js:4 - *opera12:http://www.oldapps.com/opera.php?system=Windows_XP - *@http://113.93.50.63/data.js:4 - *IE10: - * at Global code (http://113.93.50.63/data.js:4:1) - * //firefox4+ 可以用document.currentScript - */ - stack = stack.split(/[@ ]/g).pop() //取得最后一行,最后一个空格或@之后的部分 - stack = stack[0] === '(' ? stack.slice(1, -1) : stack.replace(/\s/, '') //去掉换行符 - return trimQuery(stack.replace(/(:\d+)?:\d+$/i, '')) //去掉行号与或许存在的出错字符起始位置 - } - var nodes = head.getElementsByTagName('script') //只在head标签中寻找 - for (var i = nodes.length, node; (node = nodes[--i]); ) { - if (node.className === subscribers && node.readyState === 'interactive') { - var url = node.src - return (node.className = trimQuery(url)) - } - } - } - - var rcallback = /^callback\d+$/ - function fireFactory(id, deps, factory) { - var module = Object(modules[id]) - module.state = 4 - for (var i = 0, array = [], d; (d = deps[i++]); ) { - if (d === 'exports') { - var obj = module.exports || (module.exports = createMap()) - array.push(obj) - } else { - array.push(modules[d].exports) - } - } - try { - var ret = factory.apply(window, array) - } catch (e) { - log('执行[' + id + ']模块的factory抛错: ', e) - } - if (ret !== void 0) { - module.exports = ret - } - if (rcallback.test(id)) { - delete modules[id] - } - delete module.factory - return ret - } - function toUrl(id) { - if (id.indexOf(this.res + '!') === 0) { - id = id.slice(this.res.length + 1) //处理define("css!style",[], function(){})的情况 - } - var url = id - //1. 是否命中paths配置项 - var usePath = 0 - var baseUrl = this.baseUrl - var rootUrl = this.parentUrl || baseUrl - eachIndexArray(id, kernel.paths, function(value, key) { - url = url.replace(key, value) - usePath = 1 - }) - //2. 是否命中packages配置项 - if (!usePath) { - eachIndexArray(id, kernel.packages, function(value, key, item) { - url = url.replace(item.name, item.location) - }) - } - //3. 是否命中map配置项 - if (this.mapUrl) { - eachIndexArray(this.mapUrl, kernel.map, function(array) { - eachIndexArray(url, array, function(mdValue, mdKey) { - url = url.replace(mdKey, mdValue) - rootUrl = baseUrl - }) - }) - } - var ext = this.ext - if (ext && usePath && url.slice(-ext.length) === ext) { - url = url.slice(0, -ext.length) - } - //4. 转换为绝对路径 - if (!isAbsUrl(url)) { - rootUrl = this.built || /^\w/.test(url) ? baseUrl : rootUrl - url = joinPath(rootUrl, url) - } - //5. 还原扩展名,query - var urlNoQuery = url + ext - url = urlNoQuery + this.query - urlNoQuery = url.replace(rquery, function(a) { - this.query = a - return '' - }) - //6. 处理urlArgs - eachIndexArray(id, kernel.urlArgs, function(value) { - url += (url.indexOf('?') === -1 ? '?' : '&') + value - }) - this.url = url - return (this.urlNoQuery = urlNoQuery) - } - - function makeIndexArray(hash, useStar, part) { - //创建一个经过特殊算法排好序的数组 - var index = hash2array(hash, useStar, part) - index.sort(descSorterByName) - return index - } - - function makeMatcher(prefix) { - return new RegExp('^' + prefix + '(/|$)') - } - - function makeExports(value) { - return function() { - var ret - if (value.init) { - ret = value.init.apply(window, arguments) - } - return ret || (value.exports && getGlobal(value.exports)) - } - } - - function hash2array(hash, useStar, part) { - var array = [] - for (var key in hash) { - // if (hash.hasOwnProperty(key)) {//hash是由createMap创建没有hasOwnProperty - var item = { - name: key, - val: hash[key] - } - array.push(item) - item.reg = key === '*' && useStar ? /^/ : makeMatcher(key) - if (part && key !== '*') { - item.reg = new RegExp('/' + key.replace(/^\//, '') + '(/|$)') - } - // } - } - return array - } - - function eachIndexArray(moduleID, array, matcher) { - array = array || [] - for (var i = 0, el; (el = array[i++]); ) { - if (el.reg.test(moduleID)) { - matcher(el.val, el.name, el) - return false - } - } - } - // 根据元素的name项进行数组字符数逆序的排序函数 - function descSorterByName(a, b) { - var aaa = a.name - var bbb = b.name - if (bbb === '*') { - return -1 - } - if (aaa === '*') { - return 1 - } - return bbb.length - aaa.length - } - - var rdeuce = /\/\w+\/\.\./ - function joinPath(a, b) { - if (a.charAt(a.length - 1) !== '/') { - a += '/' - } - if (b.slice(0, 2) === './') { - //相对于兄弟路径 - return a + b.slice(2) - } - if (b.slice(0, 2) === '..') { - //相对于父路径 - a += b - while (rdeuce.test(a)) { - a = a.replace(rdeuce, '') - } - return a - } - if (b.slice(0, 1) === '/') { - return a + b.slice(1) - } - return a + b - } - - function getGlobal(value) { - if (!value) { - return value - } - var g = window - value.split('.').forEach(function(part) { - g = g[part] - }) - return g - } - - var mainNode = DOC.scripts[DOC.scripts.length - 1] - var dataMain = mainNode.getAttribute('data-main') - if (dataMain) { - plugins.baseUrl(dataMain) - var href = kernel.baseUrl - kernel.baseUrl = href.slice(0, href.lastIndexOf('/') + 1) - loadJS(href.replace(rjsext, '') + '.js') - } else { - var loaderUrl = trimQuery(mainNode.src) - kernel.baseUrl = loaderUrl.slice(0, loaderUrl.lastIndexOf('/') + 1) - } -}() // jshint ignore:line - -Anot.config({ - loader: true -}) - -if (typeof define === 'function' && define.amd) { - define('Anot', [], function() { - return Anot - }) -}