Commit 72c40ff0 by Иван Кубота

rewrite loader and dependency resolver. work without live reloading

parent 710b7196
......@@ -243,7 +243,12 @@ watch('./public', function(filename){
debounceUpdate(filename);
});
/*watch('./src', function(filename){
if(filename.indexOf('_tmp_')>-1)
return;
debounceUpdate(filename);
});*/
app.listen(APP_PORT);
......
window.__Path = (function(){
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var Path = {
dirname: function( path ){
var result = Path.posixSplitPath( path ),
root = result[ 0 ],
dir = result[ 1 ];
if( !root && !dir ){
// No dirname whatsoever
return '.';
}
if( dir ){
// It has a dirname, strip trailing slash
dir = dir.substr( 0, dir.length - 1 );
}
return root + dir;
},
trim: function(result) {
if( result[ 0 ] === '/' )
return result.substr( 1 );
return result;
},
resolve: function(){
var resolvedPath = '',
resolvedAbsolute = false;
for( var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i-- ){
var path = ( i >= 0 ) ? arguments[ i ] : '/';
// Skip empty and invalid entries
if( typeof path !== 'string' ){
throw new TypeError( 'Arguments to path.resolve must be strings' );
}else if( !path ){
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path[ 0 ] === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = Path.normalizeArray( resolvedPath.split( '/' ),
!resolvedAbsolute ).join( '/' );
return Path.trim(( ( resolvedAbsolute ? '/' : '' ) + resolvedPath ) || '.');
},
normalizeArray: function( parts, allowAboveRoot ){
var res = [];
for( var i = 0; i < parts.length; i++ ){
var p = parts[ i ];
// ignore empty parts
if( !p || p === '.' )
continue;
if( p === '..' ){
if( res.length && res[ res.length - 1 ] !== '..' ){
res.pop();
}else if( allowAboveRoot ){
res.push( '..' );
}
}else{
res.push( p );
}
}
return res;
},
join: function(){
var path = '';
for( var i = 0; i < arguments.length; i++ ){
var segment = arguments[ i ];
if( typeof segment !== 'string' ){
throw new TypeError( 'Arguments to path.join must be strings' );
}
if( segment ){
if( !path ){
path += segment;
}else{
path += '/' + segment;
}
}
}
return Path.normalize( path );
},
basename: function( path, ext ){
var f = Path.posixSplitPath( path )[ 2 ];
// TODO: make this comparison case-insensitive on windows?
if( ext && f.substr( -1 * ext.length ) === ext ){
f = f.substr( 0, f.length - ext.length );
}
return f;
},
posixSplitPath: function( filename ){
return splitPathRe.exec( filename ).slice( 1 );
},
normalize: function( path ){
var isAbsolute = Path.isAbsolute( path ),
trailingSlash = path && path[ path.length - 1 ] === '/';
// Normalize the path
path = Path.normalizeArray( path.split( '/' ), !isAbsolute ).join( '/' );
if( !path && !isAbsolute ){
path = '.';
}
if( path && trailingSlash ){
path += '/';
}
return ( isAbsolute ? '/' : '' ) + path;
},
// posix version
isAbsolute: function( path ){
return path.charAt( 0 ) === '/';
}
};
return Path;
})();
\ No newline at end of file
;(function(Path) {
'use strict';
var log = console.log;
/*var log = function() {
console.log.apply(console, ['Define'].concat([].slice.call(arguments)));
};*/
var head = document.getElementsByTagName('head')[0];
var cssLoader = function(fileName) {
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css');
link.setAttribute('href', fileName);
head.appendChild(link);
return true;
};
var jsLoader = function(fileName) {
fileName = fileName.replace(/src\//,'');
var script = document.createElement('script');
script.setAttribute('type', script.type = 'text/javascript');
script.onload = function(){
};
script.setAttribute('src', script.src = fileName);
head.appendChild(script);
};
var InstantLoaders = [
{name: '.scss', loader: cssLoader},
{name: '.css', loader: cssLoader},
{name: '.jsx', loader: jsLoader},
{name: '.js', loader: jsLoader},
];
var Ready = function() {}; Ready.prototype = {ready: true};
var Wait = function(fileName) {this.fileName = fileName; this.wait = [];};
Wait.prototype = {
fileName: '',
ready: false,
resolving: 0,
checkInstantLoad: function() {
for( var i = 0, _i = InstantLoaders.length; i < _i; i++ ){
const instantLoader = InstantLoaders[ i ];
if(this.fileName.substr(-instantLoader.name.length).toLowerCase()===instantLoader.name){
if(instantLoader.loader(this.fileName)) {
return true;
}
break;
}
}
return false;
}
};
var wait = {
exports: Ready()
};
var defined = {
};
var resolve = function(base, file) {
return Path.resolve(Path.dirname(base), file);
};
var exec = function(def) {
var exports = {};
def.fn.apply(null, def.deps.map(function(dep) {
if(dep === 'exports'){
return exports;
}
return defined[resolve(def.fileName, dep)];
}));
defined[def.fileName] = exports;
var waiters = wait[def.fileName].wait;
if(wait[def.fileName] instanceof Wait){
wait[ def.fileName ] = new Ready();
for( var i = 0, _i = waiters.length; i < _i; i++ ){
var waitElement = waiters[ i ];
if( waitElement instanceof Wait ){
waitElement.resolving--;
}
}
for( var i = 0, _i = waiters.length; i < _i; i++ ){
var waitElement = waiters[ i ];
if( waitElement.resolving === 0 ){
exec( waitElement.def )
}
}
}
};
window.define = function(fileName, deps, fn) {
fileName = Path.trim(fileName);
defined[fileName] = {fileName:fileName, deps: deps, fn:fn};
deps = deps.map(function(dep) {
return dep === 'exports' ? 'exports': resolve(fileName, dep);
});
var unresolved = deps.filter(function(dep) {
if(dep === 'exports'){
return false;
}
var resolvedName = dep;
var waiter = wait[resolvedName];
if(!wait[resolvedName]){
waiter = wait[resolvedName] = new Wait(resolvedName)
}
if(!waiter.ready){
waiter.wait.push( fileName );
if( waiter.checkInstantLoad() ){
wait[ resolvedName ] = new Ready();
}
}
return !wait[resolvedName].ready;
});
if(!(fileName in wait)){
wait[fileName] = new Wait(fileName);
}
var waiter = wait[fileName];
if(unresolved.length === 0){
log(fileName, 'deps fullfilled');
exec(defined[fileName])
}else{
log(fileName, 'is waiting for', unresolved);
for( var i = 0, _i = unresolved.length; i < _i; i++ ){
var unresolvedElement = unresolved[ i ];
waiter.wait.push(resolve(fileName, unresolvedElement));
waiter.resolving++;
}
}
};
window.define.wait = wait;
window.define.defined = defined;
})(window.__Path);
\ No newline at end of file
;(function() {
;(function(Path){
'use strict';
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var Path = {
dirname: function(path) {
var result = Path.posixSplitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
// No dirname whatsoever
return '.';
}
if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substr(0, dir.length - 1);
}
return root + dir;
},
resolve: function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0) ? arguments[i] : '/';
// Skip empty and invalid entries
if (typeof path !== 'string') {
throw new TypeError('Arguments to path.resolve must be strings');
} else if (!path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path[0] === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = Path.normalizeArray(resolvedPath.split('/'),
!resolvedAbsolute).join('/');
var result = ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
if(result[0]==='/')
return result.substr(1);
return result;
},
normalizeArray: function(parts, allowAboveRoot) {
var res = [];
for (var i = 0; i < parts.length; i++) {
var p = parts[i];
// ignore empty parts
if (!p || p === '.')
continue;
if (p === '..') {
if (res.length && res[res.length - 1] !== '..') {
res.pop();
} else if (allowAboveRoot) {
res.push('..');
}
} else {
res.push(p);
}
}
return res;
},
join: function(){
var path = '';
for( var i = 0; i < arguments.length; i++ ){
var segment = arguments[ i ];
if( typeof segment !== 'string' ){
throw new TypeError( 'Arguments to path.join must be strings' );
}
if( segment ){
if( !path ){
path += segment;
}else{
path += '/' + segment;
}
}
}
return Path.normalize( path );
},
basename: function(path, ext) {
var f = Path.posixSplitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
},
posixSplitPath: function(filename) {
return splitPathRe.exec(filename).slice(1);
},
normalize: function( path ){
var isAbsolute = Path.isAbsolute( path ),
trailingSlash = path && path[ path.length - 1 ] === '/';
// Normalize the path
path = Path.normalizeArray( path.split( '/' ), !isAbsolute ).join( '/' );
if( !path && !isAbsolute ){
path = '.';
}
if( path && trailingSlash ){
path += '/';
}
return ( isAbsolute ? '/' : '' ) + path;
},
// posix version
isAbsolute: function( path ){
return path.charAt( 0 ) === '/';
}
};
var log = console.log;
var log = console.log;
/*var log = function() {
console.log.apply(console, ['Define'].concat([].slice.call(arguments)));
};*/
var head = document.getElementsByTagName('head')[0];
var cssLoader = function(fileName) {
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css');
link.setAttribute('href', fileName);
head.appendChild(link);
var head = document.getElementsByTagName( 'head' )[ 0 ];
var cssLoader = function( fileName ){
var link = document.createElement( 'link' );
link.setAttribute( 'rel', 'stylesheet' );
link.setAttribute( 'type', 'text/css' );
link.setAttribute( 'href', fileName );
head.appendChild( link );
return true;
};
var jsLoader = function(fileName) {
fileName = fileName.replace(/src\//,'');
var script = document.createElement('script');
script.setAttribute('type', script.type = 'text/javascript');
var jsLoader = function( fileName ){
var script = document.createElement( 'script' );
script.setAttribute( 'type', script.type = 'text/javascript' );
script.onload = function(){
};
script.setAttribute('src', script.src = fileName);
head.appendChild(script);
script.setAttribute( 'src', script.src = fileName );
head.appendChild( script );
};
var InstantLoaders = [
{name: '.scss', loader: cssLoader},
{name: '.css', loader: cssLoader},
{name: '.jsx', loader: jsLoader},
{name: '.js', loader: jsLoader},
{ name: '.scss', loader: cssLoader },
{ name: '.css', loader: cssLoader },
{ name: '.jsx', loader: jsLoader },
{ name: '.js', loader: jsLoader },
];
var Ready = function() {}; Ready.prototype = {ready: true};
var Wait = function(fileName) {this.fileName = fileName; this.wait = [];};
Wait.prototype = {
fileName: '',
ready: false,
resolving: 0,
checkInstantLoad: function() {
for( var i = 0, _i = InstantLoaders.length; i < _i; i++ ){
const instantLoader = InstantLoaders[ i ];
if(this.fileName.substr(-instantLoader.name.length).toLowerCase()===instantLoader.name){
if(instantLoader.loader(this.fileName)) {
return true;
}
break;
}
}
return false;
}
};
var wait = {
exports: Ready()
};
var defined = {
var definitions = {};
var waiting = {};
};
var resolve = function(base, file) {
return Path.resolve(Path.dirname(base), file);
};
var exec = function(def) {
var exports = {};
def.fn.apply(null, def.deps.map(function(dep) {
if(dep === 'exports'){
return exports;
}
return defined[resolve(def.fileName, dep)];
}));
defined[def.fileName] = exports;
wait[def.fileName] = new Ready();
for( var i = 0, _i = wait.length; i < _i; i++ ){
var waitElement = wait[ i ];
waitElement.resolving--;
}
for( var i = 0, _i = wait.length; i < _i; i++ ){
if(waitElement.resolving === 0){
exec(waitElement.def)
}
var _define = function(name) {
var definition = definitions[name];
if(definition.notResolved === 0){
console.log(name,'execute')
definition.fn.apply(null, definition.deps.map(function(dep) {
return dep === 'exports' ? definition.exports : definitions[dep].exports
}));
(waiting[definition.fileName] || []).forEach(function(name) {
definitions[name].notResolved--;
_define(name)
});
}
};
window.define = function(fileName, deps, fn) {
defined[fileName] = {fileName:fileName, deps: deps, fn:fn};
var unresolved = deps.filter(function(dep) {
if(dep === 'exports'){
return false;
}
var resolvedName = resolve(fileName, dep);
var waiter = wait[resolvedName];
fileName = Path.trim(fileName);
deps = deps.map(function(dep) {
return dep === 'exports' ? 'exports': resolve(fileName, dep);
});
if(!wait[resolvedName]){
waiter = wait[resolvedName] = new Wait(resolvedName)
}
if(!waiter.ready){
waiter.wait.push( fileName );
if( waiter.checkInstantLoad() ){
wait[ resolvedName ] = new Ready();
definitions[fileName] = {fileName:fileName, deps: deps, fn:fn, exports: {}};
var notResolved = 0;
for( var i = 0, _i = deps.length; i < _i; i++ ){
const dep = deps[ i ];
if(dep === 'exports')
continue;
var skip = false;
if(!(dep in definitions)){
for( var j = 0, _j = InstantLoaders.length; j < _j; j++ ){
const instantLoader = InstantLoaders[ j ];
if(dep.substr(-instantLoader.name.length).toLowerCase()===instantLoader.name){
if(!(dep in definitions)){
if( instantLoader.loader( dep ) ){
definitions[dep] = {exports: {}}
skip = true;
}
}
break;
}
}
}
return !wait[resolvedName].ready;
});
if(unresolved.length === 0){
log(fileName, 'deps fullfilled');
exec(defined[fileName])
}else{
log(fileName, 'is waiting for', unresolved);
var waiter = wait[fileName] = new Wait(fileName);
for( var i = 0, _i = unresolved.length; i < _i; i++ ){
var unresolvedElement = unresolved[ i ];
waiter.wait.push(resolve(fileName, unresolvedElement));
waiter.resolving++;
}else{
skip = definitions[dep].notResolved === 0;
}
if(!skip){
( waiting[ dep ] || ( waiting[ dep ] = [] ) ).push( fileName );
notResolved++;
}
}
definitions[fileName].notResolved = notResolved;
_define(fileName)
};
})();
\ No newline at end of file
window.define.definitions = definitions;
window.define.waiting = waiting;
})(window.__Path);
\ No newline at end of file
......@@ -3,6 +3,7 @@
<head>
<title>Category mapper</title>
<meta charset="utf-8" />
<script src="controller/path.js"></script>
<script src="controller/require.js"></script>
<script src="livest-reloading.js"></script>
......@@ -59,7 +60,7 @@
<script>
initDataProvider($DATA$);
define('begin', ['src/main.jsx'], function(main) {
define('begin', ['main.jsx'], function(main) {
main.default();
});
</script>
......
data = null;
import './main.scss';
import {Button} from '/view/cmp/button.jsx'
export default function() {
......@@ -8,7 +7,6 @@ export default function() {
renderTo: document.body,
cls: 'content'
},
<Button value={22}/>,
div({
cls: 'main-menu'
},
......
import './button.scss';
export const Button = D.declare('cmp.Button', function(cfg) {
return <input type='button' {...cfg} cls='button'/>
return <input type='text' {...cfg} cls='button'/>
});
\ No newline at end of file
.button {
color: red
color: green
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment