Add webpack dependencies tree

This commit is contained in:
Bogdan Lyashenko
2018-05-10 12:37:49 +02:00
parent 2fef514437
commit 37a7901f5d
11 changed files with 225 additions and 93 deletions

View File

@@ -21,6 +21,7 @@
"css-loader": "^0.28.11",
"d3-flextree": "^2.1.1",
"directory-tree": "^2.1.0",
"madge": "^3.0.1",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"style-loader": "^0.21.0",

View File

@@ -29121,12 +29121,17 @@ exports.storage = 'undefined' != typeof chrome
*/
exports.colors = [
'lightseagreen',
'forestgreen',
'goldenrod',
'dodgerblue',
'darkorchid',
'crimson'
'#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC',
'#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF',
'#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC',
'#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF',
'#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC',
'#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033',
'#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366',
'#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933',
'#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC',
'#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF',
'#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'
];
/**
@@ -29145,6 +29150,11 @@ function useColors() {
return true;
}
// Internet Explorer and Edge do not support colors.
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
return false;
}
// is webkit? http://stackoverflow.com/a/16459606/376773
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
@@ -29311,6 +29321,11 @@ exports.enable = enable;
exports.enabled = enabled;
exports.humanize = __webpack_require__(/*! ms */ "../../node_modules/ms/index.js");
/**
* Active `debug` instances.
*/
exports.instances = [];
/**
* The currently active debug mode names, and names to skip.
*/
@@ -29326,12 +29341,6 @@ exports.skips = [];
exports.formatters = {};
/**
* Previous log timestamp.
*/
var prevTime;
/**
* Select a color.
* @param {String} namespace
@@ -29360,6 +29369,8 @@ function selectColor(namespace) {
function createDebug(namespace) {
var prevTime;
function debug() {
// disabled?
if (!debug.enabled) return;
@@ -29416,15 +29427,28 @@ function createDebug(namespace) {
debug.enabled = exports.enabled(namespace);
debug.useColors = exports.useColors();
debug.color = selectColor(namespace);
debug.destroy = destroy;
// env-specific initialization logic for debug instances
if ('function' === typeof exports.init) {
exports.init(debug);
}
exports.instances.push(debug);
return debug;
}
function destroy () {
var index = exports.instances.indexOf(this);
if (index !== -1) {
exports.instances.splice(index, 1);
return true;
} else {
return false;
}
}
/**
* Enables a debug mode by namespaces. This can include modes
* separated by a colon and wildcards.
@@ -29439,10 +29463,11 @@ function enable(namespaces) {
exports.names = [];
exports.skips = [];
var i;
var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
var len = split.length;
for (var i = 0; i < len; i++) {
for (i = 0; i < len; i++) {
if (!split[i]) continue; // ignore empty strings
namespaces = split[i].replace(/\*/g, '.*?');
if (namespaces[0] === '-') {
@@ -29451,6 +29476,11 @@ function enable(namespaces) {
exports.names.push(new RegExp('^' + namespaces + '$'));
}
}
for (i = 0; i < exports.instances.length; i++) {
var instance = exports.instances[i];
instance.enabled = exports.enabled(instance.namespace);
}
}
/**
@@ -29472,6 +29502,9 @@ function disable() {
*/
function enabled(name) {
if (name[name.length - 1] === '*') {
return true;
}
var i, len;
for (i = 0, len = exports.skips.length; i < len; i++) {
if (exports.skips[i].test(name)) {
@@ -66421,6 +66454,26 @@ module.exports = function(module) {
};
/***/ }),
/***/ "../shared/constants.js":
/*!******************************!*\
!*** ../shared/constants.js ***!
\******************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var SOCKET_EVENT_TYPE = {
SYNC_SOURCE_FILES: 'sync-source-files'
};
module.exports = {
SOCKET_EVENT_TYPE: SOCKET_EVENT_TYPE
};
/***/ }),
/***/ "./js/App.css":
@@ -66477,7 +66530,9 @@ var _devTest = __webpack_require__(/*! ./utils/dev-test */ "./js/utils/dev-test.
var _devTest2 = _interopRequireDefault(_devTest);
var _connection = __webpack_require__(/*! ./connection */ "./js/connection.js");
var _connection = __webpack_require__(/*! ./utils/connection */ "./js/utils/connection.js");
var _constants = __webpack_require__(/*! ../../shared/constants */ "../shared/constants.js");
var _ViewsSwitchList = __webpack_require__(/*! ./components/controls/ViewsSwitchList */ "./js/components/controls/ViewsSwitchList.js");
@@ -66506,7 +66561,9 @@ var App = function (_React$Component) {
var _this = _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).call(this, props));
_this.state = {
sourceTreeData: []
filesTree: [],
filesList: [],
dependenciesList: []
};
return _this;
}
@@ -66517,13 +66574,33 @@ var App = function (_React$Component) {
var _this2 = this;
(0, _connection.createConnection)(function (_ref) {
var data = _ref.data;
_this2.setState({
sourceTreeData: data.body
});
var type = _ref.type,
data = _ref.data;
return _this2.onSocketEvent(type, data);
});
}
}, {
key: 'onSocketEvent',
value: function onSocketEvent(type, data) {
switch (type) {
case _constants.SOCKET_EVENT_TYPE.SYNC_SOURCE_FILES:
var _data$body = data.body,
filesTree = _data$body.filesTree,
filesList = _data$body.filesList,
dependenciesList = _data$body.dependenciesList;
this.setState({
filesTree: filesTree,
filesList: filesList,
dependenciesList: dependenciesList
});
break;
default:
break;
}
}
}, {
key: 'render',
value: function render() {
@@ -66539,7 +66616,7 @@ var App = function (_React$Component) {
}
})
),
_react2.default.createElement(_SourceTree2.default, { treeData: this.state.sourceTreeData })
_react2.default.createElement(_SourceTree2.default, { treeData: this.state.filesTree })
);
}
}]);
@@ -66764,38 +66841,6 @@ exports.default = SourceTree;
/***/ }),
/***/ "./js/connection.js":
/*!**************************!*\
!*** ./js/connection.js ***!
\**************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var createConnection = exports.createConnection = function createConnection(onMessage) {
var route = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'ws://127.0.0.1:2018/';
var ws = new WebSocket(route);
ws.onmessage = function (event) {
onMessage(JSON.parse(event.data));
};
return function (msg) {
try {
ws.send(msg);
} catch (e) {
console.log(e);
}
};
};
/***/ }),
/***/ "./js/index.js":
/*!*********************!*\
!*** ./js/index.js ***!
@@ -66825,6 +66870,38 @@ _reactDom2.default.render(_react2.default.createElement(_App2.default, null), do
/***/ }),
/***/ "./js/utils/connection.js":
/*!********************************!*\
!*** ./js/utils/connection.js ***!
\********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var createConnection = exports.createConnection = function createConnection(onMessage) {
var route = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'ws://127.0.0.1:2018/';
var ws = new WebSocket(route);
ws.onmessage = function (event) {
onMessage(JSON.parse(event.data));
};
return function (msg) {
try {
ws.send(msg);
} catch (e) {
console.log(e);
}
};
};
/***/ }),
/***/ "./js/utils/dev-test.js":
/*!******************************!*\
!*** ./js/utils/dev-test.js ***!

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,7 @@
import React from 'react';
import devProcessTesting from './utils/dev-test';
import { createConnection } from './connection';
import { createConnection } from './utils/connection';
import { SOCKET_EVENT_TYPE } from '../../shared/constants';
import ViewsSwitchList from './components/controls/ViewsSwitchList';
import SourceTree from './components/tree-diagram/SourceTree';
import './App.css';
@@ -10,16 +11,31 @@ class App extends React.Component {
super(props);
this.state = {
sourceTreeData: []
filesTree: [],
filesList: [],
dependenciesList: []
};
}
componentDidMount() {
createConnection(({ data }) => {
this.setState({
sourceTreeData: data.body
});
});
createConnection(({ type, data }) => this.onSocketEvent(type, data));
}
onSocketEvent(type, data) {
switch (type) {
case SOCKET_EVENT_TYPE.SYNC_SOURCE_FILES:
const { filesTree, filesList, dependenciesList } = data.body;
this.setState({
filesTree,
filesList,
dependenciesList
});
break;
default:
break;
}
}
render() {
@@ -32,7 +48,7 @@ class App extends React.Component {
}}
/>
</div>
<SourceTree treeData={this.state.sourceTreeData} />
<SourceTree treeData={this.state.filesTree} />
</div>
);
}

View File

@@ -1,16 +1,18 @@
const WebSocketServer = require('websocket').server;
const http = require('http');
const statics = require('./fs/statics');
const statics = require('./statics/statics');
const api = require('./api/api');
const projectSourceWatcher = require('./project-source-watcher');
const SOCKET_EVENT_TYPE = require('../shared/constants').SOCKET_EVENT_TYPE;
const PORT = 2018;
const PROJECT_DIR = 'example-project'; //get as param to server script
const ENTRY = '/app.js'; //get as param to server script
const httpServer = http.createServer((request, response) => {
const url = request.url.substr(1);
if (url.startsWith('api')) {
if (url.startsWith('api/')) {
return api.requestHandler(url, response);
}
@@ -25,10 +27,10 @@ const webSocketServer = new WebSocketServer({ httpServer });
webSocketServer.on('request', request => {
const connection = request.accept(null, request.origin);
projectSourceWatcher.subscribeOnChange(PROJECT_DIR, body =>
projectSourceWatcher.subscribeOnChange(PROJECT_DIR, ENTRY, body =>
connection.sendUTF(
JSON.stringify({
type: 'sync',
type: SOCKET_EVENT_TYPE.SYNC_SOURCE_FILES,
data: { projectDir: PROJECT_DIR, body }
})
)

View File

@@ -1,10 +1,9 @@
const directoryTree = require('directory-tree');
const codecrumbs = require('./codecrumbs');
const fs = require('fs');
const codecrumbs = require('./codecrumbs/codecrumbs');
const file = require('./utils/file');
const madge = require('madge');
let filesTreeCached = null;
const subscribeOnChange = (projectDir, fn) => {
const getDirFiles = projectDir => {
const filesList = [];
const filesTree = directoryTree(
@@ -15,31 +14,38 @@ const subscribeOnChange = (projectDir, fn) => {
}
);
if (filesTreeCached) {
//keep files content
}
return { list: filesList, tree: filesTree };
};
Promise.all(
filesList.map(
item =>
new Promise((
resolve //TODO: move to utils fs read + promise
) =>
fs.readFile(item.path, 'utf8', function(err, code) {
const codecrumbsList = codecrumbs.getCrumbs(code);
const getDependenciesList = (projectDir, entryPoint) => {
return madge(projectDir + entryPoint).then(res => res.obj());
};
item.codecrumbs = codecrumbsList;
item.hasCodecrumbs = !!codecrumbsList.length;
item.fileCode = code;
const getProjectSourceStats = (projectDir, entryPoint) => {
const dirFiles = getDirFiles(projectDir);
resolve();
})
)
return Promise.all([
getDependenciesList(projectDir, entryPoint),
...dirFiles.list.map(item =>
file.read(item.path, 'utf8').then(code => {
const codecrumbsList = codecrumbs.getCrumbs(code);
item.codecrumbs = codecrumbsList;
item.hasCodecrumbs = !!codecrumbsList.length;
})
)
).then(() => fn(filesTree));
]).then(([dependenciesList]) => ({
filesTree: dirFiles.tree,
filesList: dirFiles.list,
dependenciesList
}));
};
//1) read file by file and mark files from tree which are without //crumb(s), so they can be greyed out on ui
//2) add 'display path' (substr example-project which is repeated) and other info for resulting tree - based on passed params to crumbs
const subscribeOnChange = (projectDir, entryPoint, fn) => {
//first response on registration
getProjectSourceStats(projectDir, entryPoint).then(fn);
//watch changes here and trigger fn()
};
module.exports = {

View File

@@ -1,4 +1,4 @@
const fs = require('fs');
const file = require('../utils/file');
const PATH = {
PUBLIC: 'src/public/dist/',
@@ -8,7 +8,7 @@ const PATH = {
const AVAILABLE_RESOURCES = ['bundle.js', 'bundle.js.map'];
const responseWithFile = function(options, response) {
fs.readFile(options.file, function(err, data) {
file.read(options.file).then(data => {
response.writeHead(200, {
'Content-Type': options.contentType,
'Content-Length': data.length

23
src/server/utils/file.js Normal file
View File

@@ -0,0 +1,23 @@
const fs = require('fs');
const read = (file, format) => {
return new Promise((resolve, reject) => {
const params = [
file,
format,
(err, data) => {
if (err) {
return reject(err);
}
return resolve(data);
}
];
fs.readFile.apply(fs, params.filter(p => p));
});
};
module.exports = {
read
};

7
src/shared/constants.js Normal file
View File

@@ -0,0 +1,7 @@
const SOCKET_EVENT_TYPE = {
SYNC_SOURCE_FILES: 'sync-source-files'
};
module.exports = {
SOCKET_EVENT_TYPE
};