From ee13626904626b3a317cbb2a3c8787fd01acef4a Mon Sep 17 00:00:00 2001 From: liaoxuezhi Date: Mon, 5 Aug 2019 16:54:39 +0800 Subject: [PATCH] =?UTF-8?q?amis=20sdk=20=E7=94=9F=E6=88=90=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + build/embed-packager.js | 200 +++---------- examples/{utils => }/loader.ts | 9 +- examples/mod.js | 5 - examples/sdk-mod.js | 292 +++++++++++++++++++ examples/{embed.tpl => sdk-placeholder.html} | 5 +- examples/static/mod.js | 260 ----------------- examples/utils/amis.ts | 3 - examples/utils/openUtils.ts | 40 --- fis-conf.js | 215 +++++++++++--- package.json | 12 +- publish.sh | 3 + 12 files changed, 520 insertions(+), 525 deletions(-) rename examples/{utils => }/loader.ts (86%) create mode 100644 examples/sdk-mod.js rename examples/{embed.tpl => sdk-placeholder.html} (88%) delete mode 100644 examples/static/mod.js delete mode 100644 examples/utils/amis.ts delete mode 100644 examples/utils/openUtils.ts diff --git a/.gitignore b/.gitignore index 5aeb92b3..994d30b1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ _site node_modules /dist /lib +/sdk /public /gh-pages /.vscode diff --git a/build/embed-packager.js b/build/embed-packager.js index 0c7776bd..02df631f 100644 --- a/build/embed-packager.js +++ b/build/embed-packager.js @@ -37,33 +37,6 @@ function prefixCss(code, prefix) { } } -function replaceSrc(code) { - var cssAst = css.parse(code); - let count = 0; - replaceNode(cssAst); - return css.stringify(cssAst); - - function replaceDeclaration(sel) { - if (sel.property == 'src' && ~sel.value.indexOf('url')) { - sel.value = sel.value.replace(/\/sdk/g, '.'); - } - return sel; - } - - function replaceNode(node) { - // font-awesome的在 1 个 declarations中, bootstrap 的字体路径在 58 declarations中,后续的就不再遍历了,直接返回 - if (count >= 58) return node; - if (node.declarations) { - count++; - node.declarations = node.declarations.map(replaceDeclaration); - } else if (node.stylesheet) { - node.stylesheet.rules.forEach(replaceNode); - } else if (node.rules) { - node.rules.forEach(replaceNode); - } - } -} - function unicodeJs(str) { return str.replace(/([\u4E00-\u9FA5]|[\uFE30-\uFFA0]|[\u2019])/g, function(_, value){ return '\\u' + value.charCodeAt(0).toString(16); @@ -73,7 +46,8 @@ function unicodeJs(str) { module.exports = function (ret, pack, settings, opt) { var root = fis.project.getProjectPath(); - var tpl = ret.pkg['/examples/embed.tpl']; + var tpl = ret.pkg['/examples/sdk-placeholder.html']; + tpl.skiped = true; if (tpl && tpl._fromCache && caches[tpl.id]) { tpl.setContent(caches[tpl.id]); @@ -104,6 +78,38 @@ module.exports = function (ret, pack, settings, opt) { if (script && !body.trim() && rSrcHref.test(attrs)) { all = ''; + let src = RegExp.$2; + let file = resource.getFileByUrl(src); + + if (!file) { + file = resource.getFileByUrl(fis.util(path.join(path.dirname(tpl.release), src))); + } + + if (!file) { + file = mapping[src]; + } + + if (file) { + file.skiped = true; + let contents = file.getContent(); + + if (/_map\.js$/.test(file.subpath)) { + contents = `(function() { + var d = ''; + try { + throw new Error() + } catch (e) { + d = (/((?:https?|file)\:.*)$/.test(e.stack) && RegExp.$1).replace(/\\/[^\\/]*$/, ''); + } + ${contents.replace(/\"url\"\s*\:\s*('|")(\.\/.*)\1/g, function(_, quote, value) { + return `"url": d + ${quote}${value.substring(1)}${quote}`; + })} + })()`; + } + + jsContents += contents + ';\n'; + } + } else if (script && !rScriptType.test(attrs) || rScriptType.test(attrs) && ~['text/javascript', 'application/javascript'].indexOf(RegExp.$2.toLowerCase())) { entryJs += ';' + body; all = ''; @@ -120,11 +126,9 @@ module.exports = function (ret, pack, settings, opt) { } - if (file && (file.filename === 'font-awesome' || file.filename === 'bootstrap')) { - let content = replaceSrc(file.getContent()) - cssContents += '\n' + content; - } else { - file && (cssContents += '\n' + file.getContent()); + if (file) { + cssContents += '\n' + file.getContent(); + file.skiped = true; } all = ''; } else if (style && sbody.trim()) { @@ -135,142 +139,18 @@ module.exports = function (ret, pack, settings, opt) { return all; }); - (function (file, ret) { // tpl ret - var resource = createResource(ret, file, {}); - var asyncJsContents = ''; - - file.requires.forEach(function(id) { - resource.add(id); - }); - - file.asyncs.forEach(function(id) { - resource.add(id, true); - }); - - var loaded = resource.loaded; - var res = {}; - var pkg = {}; - - Object.keys(loaded).forEach(function (id) { - if (!/\.(jsx|tsx|js|ts)?$/.test(id)) { - return; - } - var file = resource.getFileById(id); - var isAsync = loaded[id]; - - if (file) { - if (isAsync) { - asyncJsContents += ';/*!' +id+ '*/\n' + file.getContent(); - - var node = resource.getNode(id); - if (node.type !== 'js') { - return; - } - - var item = { - type: node.type - }; - - if (node.deps) { - - // 过滤掉不是 js 的文件依赖。 - var deps = node.deps.filter(function(id) { - if (resource.loaded[id] !== false) { - var dep = resource.getFileById(id); - - if (dep) { - return dep.isJsLike; - } - } - - return false; - }); - - if (deps.length) { - deps.forEach(function(v, k) { - var dep = resource.getFileById(v); - - if (dep && dep.moduleId) { - deps[k] = dep.moduleId; - } else { - deps[k] = v.replace(/\.(es6|jsx|tsx|ts|coffee)$/g, '.js'); - } - - }); - item.deps = deps; - } - } - - var moduleId = node.extras && node.extras.moduleId || file && file.moduleId || id.replace(/\.js$/i, ''); - res[moduleId] = item; - - } else { - jsContents += ';/*!' +id+ '*/\n' + file.getContent(); - } - } - }); - - var modjs = resource.getFileByUrl('/examples/mod.js'); - var resouceMap = ''; - var asyncPkgs = {}; - - if (asyncJsContents) { - asyncJsContents = asyncJsContents.replace(rSourceMap, ''); - asyncJsContents = unicodeJs(asyncJsContents); - - let asyncJsFile = fis.file(root + '/sdk/', tpl.filename + '_aio_async.js'); - asyncJsFile.setContent(asyncJsContents); - ret.pkg[asyncJsFile.subpath] = asyncJsFile; - - Object.keys(res).forEach(function (moduleId) { - res[moduleId].pkg = 'paio'; - }); - - pkg['paio'] = { - uri: asyncJsFile.filename + '.js', - type: 'js' - }; - - asyncPkgs = {res: res, pkg: pkg}; - } - - resouceMap = `(function(){ - var dirname = ''; - try { - throw new Error() - } catch (e) { - const stackPath = e.stack.substring(0, e.stack.indexOf('embed')); - const rgx = /(?<=.)(http|https|file).*/; - dirname = (rgx.exec(stackPath)||[])[0] || ''; - } - var config = ${JSON.stringify(asyncPkgs)}; - var pkg = config.pkg; - Object.keys(pkg).forEach(function(key){ - if (pkg[key].uri) { - pkg[key].uri = dirname + pkg[key].uri; - } - }); - amis.require.resourceMap(config); - })();`; - jsContents = modjs.getContent() + '\n' + resouceMap + '\n' + jsContents; - })(tpl, ret); - jsContents = jsContents.replace(rSourceMap, ''); jsContents = unicodeJs(jsContents); - let jsFile = fis.file(root + '/sdk/', tpl.filename + '_aio.js'); + let jsFile = fis.file(root, 'sdk.js'); jsFile.setContent(jsContents); ret.pkg[jsFile.subpath] = jsFile; cssContents = prefixCss(cssContents, '.amis-scope'); - let cssFile = fis.file(root + '/sdk/', tpl.filename + '_aio.css'); + let cssFile = fis.file(root, 'sdk.css'); cssFile.setContent(cssContents); ret.pkg[cssFile.subpath] = cssFile; - entryJs = entryJs.replace(/[\r\n]/g, '').replace(/"/g, '\\"'); - contents = "(function(css, js) {"+entryJs+"})('" + cssFile.getUrl() +"', '" + jsFile.getUrl() + "')"; - contents += '\n// jsurl=' + jsFile.getUrl(); - contents += '\n// cssurl=' + cssFile.getUrl(); - tpl.setContent(contents); + // tpl.setContent(contents); caches[tpl.id] = contents; }; diff --git a/examples/utils/loader.ts b/examples/loader.ts similarity index 86% rename from examples/utils/loader.ts rename to examples/loader.ts index 0b243ce6..9f746290 100644 --- a/examples/utils/loader.ts +++ b/examples/loader.ts @@ -1,6 +1,5 @@ const __moduleId = (str: string) => ''; -import './openUtils'; const mapping: { [propName: string]: any; @@ -14,7 +13,6 @@ const mapping: { 'react-select': __moduleId('react-select'), 'react-cropper': __moduleId('react-cropper'), 'react-dropzone': __moduleId('react-dropzone'), - 'aui': __moduleId('amis'), 'react-bootstrap': __moduleId('react-bootstrap'), 'classnames': __moduleId('classnames'), 'axios': __moduleId('axios'), @@ -26,11 +24,8 @@ const mapping: { 'zrender': __moduleId('zrender'), 'sortablejs': __moduleId('sortablejs'), 'history': __moduleId('history'), - '@fex/aui': __moduleId('amis'), - '@fex/amis-renderer': __moduleId('amis'), - 'amis/utils': __moduleId('./openUtils'), - 'amis/util': __moduleId('./openUtils'), - 'amis/embed': __moduleId('../embed.tsx'), + 'amis': __moduleId('../src'), + 'amis/embed': __moduleId('./embed.tsx'), 'prop-types': __moduleId('prop-types'), 'async': __moduleId('async'), 'qs': __moduleId('qs'), diff --git a/examples/mod.js b/examples/mod.js index b60daea2..033c6fa8 100644 --- a/examples/mod.js +++ b/examples/mod.js @@ -12,7 +12,6 @@ var define; (function (global) { - var amis = window.amis || {}; // 避免重复加载而导致已定义模块丢失 if (require) { return; @@ -285,8 +284,4 @@ var define; require.timeout = 5000; - amis.require = require; - amis.define = define; - window.amis = amis; - })(this); diff --git a/examples/sdk-mod.js b/examples/sdk-mod.js new file mode 100644 index 00000000..b60daea2 --- /dev/null +++ b/examples/sdk-mod.js @@ -0,0 +1,292 @@ +/** + * @file: mod.js + * @author fis + * ver: 1.0.13 + * update: 2016/01/27 + * https://github.com/fex-team/mod + */ +var require; + +/* eslint-disable no-unused-vars */ +var define; + +(function (global) { + + var amis = window.amis || {}; + // 避免重复加载而导致已定义模块丢失 + if (require) { + return; + } + + var head = document.getElementsByTagName('head')[0]; + var loadingMap = {}; + var factoryMap = {}; + var modulesMap = {}; + var scriptsMap = {}; + var resMap = {}; + var pkgMap = {}; + + var createScripts = function (queues, onerror) { + + var docFrag = document.createDocumentFragment(); + + for (var i = 0, len = queues.length; i < len; i++) { + var id = queues[i].id; + var url = queues[i].url; + + if (url in scriptsMap) { + continue; + } + + scriptsMap[url] = true; + + var script = document.createElement('script'); + if (onerror) { + (function (script, id) { + var tid = setTimeout(function () { + onerror(id); + }, require.timeout); + + script.onerror = function () { + clearTimeout(tid); + onerror(id); + }; + + var onload = function () { + clearTimeout(tid); + }; + + if ('onload' in script) { + script.onload = onload; + } + else { + script.onreadystatechange = function () { + if (this.readyState === 'loaded' || this.readyState === 'complete') { + onload(); + } + }; + } + })(script, id); + } + script.type = 'text/javascript'; + script.src = url; + + docFrag.appendChild(script); + } + + head.appendChild(docFrag); + }; + + var loadScripts = function (ids, callback, onerror) { + var queues = []; + for (var i = 0, len = ids.length; i < len; i++) { + var id = ids[i]; + var queue = loadingMap[id] || (loadingMap[id] = []); + queue.push(callback); + + // + // resource map query + // + var res = resMap[id] || resMap[id + '.js'] || {}; + var pkg = res.pkg; + var url; + + if (pkg) { + url = pkgMap[pkg].url || pkgMap[pkg].uri; + } + else { + url = res.url || res.uri || id; + } + + queues.push({ + id: id, + url: url + }); + } + + createScripts(queues, onerror); + }; + + define = function (id, factory) { + id = id.replace(/\.js$/i, ''); + factoryMap[id] = factory; + + var queue = loadingMap[id]; + if (queue) { + for (var i = 0, n = queue.length; i < n; i++) { + queue[i](); + } + delete loadingMap[id]; + } + }; + + require = function (id) { + + // compatible with require([dep, dep2...]) syntax. + if (id && id.splice) { + return require.async.apply(this, arguments); + } + + id = require.alias(id); + + var mod = modulesMap[id]; + if (mod) { + return mod.exports; + } + + // + // init module + // + var factory = factoryMap[id]; + if (!factory) { + throw '[ModJS] Cannot find module `' + id + '`'; + } + + mod = modulesMap[id] = { + exports: {} + }; + + // + // factory: function OR value + // + var ret = (typeof factory === 'function') ? factory.apply(mod, [require, mod.exports, mod]) : factory; + + if (ret) { + mod.exports = ret; + } + + return mod.exports; + }; + + require.async = function (names, onload, onerror) { + if (typeof names === 'string') { + names = [names]; + } + + var needMap = {}; + var needNum = 0; + var needLoad = []; + + function findNeed(depArr) { + var child; + + for (var i = 0, n = depArr.length; i < n; i++) { + // + // skip loading or loaded + // + var dep = require.alias(depArr[i]); + + if (dep in needMap) { + continue; + } + + needMap[dep] = true; + + if (dep in factoryMap) { + // check whether loaded resource's deps is loaded or not + child = resMap[dep] || resMap[dep + '.js']; + if (child && 'deps' in child) { + findNeed(child.deps); + } + continue; + } + + needLoad.push(dep); + needNum++; + + child = resMap[dep] || resMap[dep + '.js']; + if (child && 'deps' in child) { + findNeed(child.deps); + } + } + } + + function updateNeed() { + if (0 === needNum--) { + var args = []; + for (var i = 0, n = names.length; i < n; i++) { + args[i] = require(names[i]); + } + + onload && onload.apply(global, args); + } + } + + findNeed(names); + loadScripts(needLoad, updateNeed, onerror); + updateNeed(); + }; + + require.ensure = function (names, callback) { + require.async(names, function () { + callback && callback.call(this, require); + }); + }; + + require.resourceMap = function (obj) { + var k; + var col; + + // merge `res` & `pkg` fields + col = obj.res; + for (k in col) { + if (col.hasOwnProperty(k)) { + resMap[k] = col[k]; + } + } + + col = obj.pkg; + for (k in col) { + if (col.hasOwnProperty(k)) { + pkgMap[k] = col[k]; + } + } + }; + + require.loadJs = function (url) { + if (url in scriptsMap) { + return; + } + + scriptsMap[url] = true; + + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = url; + head.appendChild(script); + }; + + require.loadCss = function (cfg) { + if (cfg.content) { + var sty = document.createElement('style'); + sty.type = 'text/css'; + + if (sty.styleSheet) { // IE + sty.styleSheet.cssText = cfg.content; + } + else { + sty.innerHTML = cfg.content; + } + head.appendChild(sty); + } + else if (cfg.url) { + var link = document.createElement('link'); + link.href = cfg.url; + link.rel = 'stylesheet'; + link.type = 'text/css'; + head.appendChild(link); + } + }; + + + require.alias = function (id) { + return id.replace(/\.js$/i, ''); + }; + + require.timeout = 5000; + + amis.require = require; + amis.define = define; + window.amis = amis; + +})(this); diff --git a/examples/embed.tpl b/examples/sdk-placeholder.html similarity index 88% rename from examples/embed.tpl rename to examples/sdk-placeholder.html index 822ac681..ebf678ae 100644 --- a/examples/embed.tpl +++ b/examples/sdk-placeholder.html @@ -15,11 +15,10 @@ - +