Skip to content

Instantly share code, notes, and snippets.

@rpf5573
Last active September 19, 2018 05:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rpf5573/f495b6ee2fd908b0c0aa7940650fd492 to your computer and use it in GitHub Desktop.
Save rpf5573/f495b6ee2fd908b0c0aa7940650fd492 to your computer and use it in GitHub Desktop.
// loader.js를 실행하고 나서, node.js를 실행하는데, node.js안에서는 이렇게 함수가 호출되어있다.
// 즉, loader.js에서 load에 필요한 함수들을 정의한 뒤에, node.js에서 그걸 사용하면서 실제로 load를 진행한다.
startup();
// lib/internal/bootstrap/node.js : 31
function startup() {
// Make process.argv[1] into a full path.
const path = NativeModule.require('path');
process.argv[1] = path.resolve(process.argv[1]);
// loader.js를 먼저 실행했기 때문에 node.js에서 가져와 쓸 수 있다
const CJSModule = NativeModule.require('internal/modules/cjs/loader.js/loader');
preloadModules();
const fs = NativeModule.require('fs');
const filename = CJSModule._resolveFilename(process.argv[1]);
const source = fs.readFileSync(filename, 'utf-8'); // 나의 index.js파일을 읽어들인다
checkScriptSyntax(source, filename); // 문법 체크
CJSModule.runMain();
}
// lib/internal/modules/cjs/loader.js : 733
Module.runMain = function() {
// argv[1] 안에 index.js가 들어있다.(아마도...)
Module._load(process.argv[1], null, true);
// Handle any nextTicks added in the first tick of the program
process._tickCallback();
};
// lib/internal/modules/cjs/loader.js : 506
Module._load = function(request, parent, isMain) {
// Don't call updateChildren(), Module constructor already does.
var module = new Module(filename, parent);
tryModuleLoad(module, filename);
return module.exports;
};
// lib/internal/modules/cjs/loader.js : 539
function tryModuleLoad(module, filename) {
module.load(filename);
}
// lib/internal/modules/cjs/loader.js : 593
Module.prototype.load = function(filename) {
Module._extensions[extension](this, filename); // == Module._extensions['.js'](this, filename)
};
// lib/internal/modules/cjs/loader.js : 702
Module._extensions['.js'] = function(module, filename) {
var content = fs.readFileSync(filename, 'utf8'); // 파일을 HardDisk에서 읽어 들여서
module._compile(stripBOM(content), filename); // 컴파일!
};
// lib/internal/modules/cjs/loader.js : 654
Module.prototype._compile = function(content, filename) {
// create wrapper function
var wrapper = Module.wrap(content);
var compiledWrapper = vm.runInThisContext(wrapper, {
filename: filename,
lineOffset: 0,
displayErrors: true
});
};
// lib/internal/modules/cjs/loader.js : 125
Module.wrap = function(script) {
return Module.wrapper[0] + script + Module.wrapper[1];
};
// lib/internal/modules/cjs/loader.js : 129
Module.wrapper = [
'(function (exports, require, module, __filename, __dirname) { ',
'\n});'
];
// wrapper가 실행되면 이렇게 된다.
(function (exports, require, module, __filename, __dirname) {
// 내 index.js code가 여기에 들어간다
// 이런 연유로 exports()나 require()을 내 코드에서 쓸 수 있다
});
// lib/vm.js : 287
function runInThisContext(code, options) {
return createScript(code, options).runInThisContext(options);
}
// lib/vm.js : 89
// Script의 public 함수
runInThisContext(options) {
return super.runInThisContext(...args);
}
// lib/vm.js : 40
// ContextifyScript가 super다
class Script extends ContextifyScript { ~~ }
// lib/vm.js : 25
const {
ContextifyScript,
makeContext,
isContext: _isContext,
compileFunction: _compileFunction
} = internalBinding('contextify');
// src/node_contextify.cc
// 이렇게 등록했기 때문에 아까, javascript 단에서 super.runInThisContext()를 쓸 수 있게된것이다.( c++ 함수를 javascript에서도 쓸수있도록 연결 )
env->SetProtoMethod(script_tmpl, "runInThisContext", RunInThisContext);
// src/node_contextify.cc
static void RunInThisContext(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
// Javascript가상머신이 javascript코드를 실행한다
EvalMachine(env, timeout, display_errors, break_on_sigint, args);
}
// src/node_contextify.cc
static bool EvalMachine(Environment* env,
const int64_t timeout,
const bool display_errors,
const bool break_on_sigint,
const FunctionCallbackInfo<Value>& args) {
Local<Script> script = unbound_script->BindToCurrentContext();
result = script->Run(env->context());
}
// 여기까지가 LoadEnvirenment !
// 이 모든 과정이 끝난 다음에, node.cc로 다시 돌아간다. 그리고 event-loop를 돌린다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment