123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- const defaults = require('./defaults');
- const md5 = require('./md5');
- const safeGet = require('./safeGet');
- const FileStore = require('./FileStore');
- const FileBlobStore = require('./FileBlobStore');
- const mkdir = require('./mkdir');
- let isEnabled = false;
- exports = function(options = {}) {
- if (isEnabled) {
- return;
- }
- isEnabled = true;
- defaults(options, defOptions);
- const Module = require('module');
- const fs = require('fs');
- const path = require('path');
- const vm = require('vm');
- const cacheDir = options.dir || getCacheDir();
- if (!fs.existsSync(cacheDir)) {
- mkdir.sync(cacheDir);
- }
- if (options.requirePath) {
- const _resolveFilename = Module._resolveFilename;
- const requirePathMapStore = new FileStore(
- path.resolve(cacheDir, 'require-path.json')
- );
- Module._resolveFilename = function(request, parent, isMain, options) {
- let currentModuleCache = requirePathMapStore.get(parent.filename);
- if (!currentModuleCache) {
- currentModuleCache = {};
- requirePathMapStore.set(parent.filename, currentModuleCache);
- }
- if (currentModuleCache[request]) {
- return currentModuleCache[request];
- }
- const pathToLoad = _resolveFilename(
- request,
- parent,
- isMain,
- options
- );
- currentModuleCache[request] = pathToLoad;
- return pathToLoad;
- };
- }
- if (options.code) {
- const fileMapStore = new FileStore(
- path.resolve(cacheDir, 'require-file.json')
- );
- Module._extensions['.js'] = function(module, filename) {
- let content;
- if (fileMapStore.get(filename)) {
- content = fileMapStore.get(filename);
- } else {
- content = fs.readFileSync(filename, 'utf8');
- fileMapStore.set(filename, content);
- }
- return module._compile(content, filename);
- };
- }
- if (options.compileCache) {
- const compileCacheBlobStore = new FileBlobStore(
- path.resolve(cacheDir, 'compile-cache')
- );
- process.once('exit', () => compileCacheBlobStore.save());
- Module.prototype._compile = function(content, filename) {
- const mod = this;
- function require(id) {
- return mod.require(id);
- }
- function resolve(request, options) {
- return Module._resolveFilename(request, mod, false, options);
- }
- require.resolve = resolve;
- resolve.paths = function paths(request) {
- return Module._resolveLookupPaths(request, mod, true);
- };
- require.main = process.mainModule;
- require.extensions = Module._extensions;
- require.cache = Module._cache;
- const dirname = path.dirname(filename);
- const compiledWrapper = moduleCompile(filename, content);
- const args = [
- mod.exports,
- require,
- mod,
- filename,
- dirname,
- process,
- global,
- Buffer
- ];
- return compiledWrapper.apply(mod.exports, args);
- };
- function moduleCompile(filename, content) {
- const wrapper = Module.wrap(content);
- const buffer = compileCacheBlobStore.get(filename);
- const script = new vm.Script(wrapper, {
- filename,
- lineOffset: 0,
- displayErrors: true,
- cachedData: buffer,
- produceCachedData: true
- });
- if (script.cachedDataProduced) {
- compileCacheBlobStore.set(filename, script.cachedData);
- } else if (script.cachedDataRejected) {
- compileCacheBlobStore.delete(filename);
- }
- const compiledWrapper = script.runInThisContext({
- filename,
- lineOffset: 0,
- columnOffset: 0,
- displayErrors: true
- });
- return compiledWrapper;
- }
- }
- };
- const defOptions = {
- requirePath: true,
- code: false,
- compileCache: true
- };
- function getCacheDir() {
- const os = require('os');
- return (
- os.tmpdir() +
- '/' +
- md5(
- `${get(process, 'versions.v8')}${get(require, 'main.filename') ||
- get(module, 'parent.filename')}`
- )
- );
- }
- function get(obj, path) {
- return safeGet(obj, path) || '';
- }
- module.exports = exports;
|