Open t2ym opened 6 years ago
webpack/enhanced-resolve
is used for both webpack
and browserify
browserify/resolve
be used for browserify (#200)? /base/context/module1.js,x|/target/virtual/context/module.js
const browserifyBuiltins = require('browserify/lib/builtins.js');
const nodeLibsBrowser = require('node-libs-browser');
const enhancedResolve = require('enhanced-resolve'); const resolveSync = enhancedResolve.create.sync({ // webPackConfig.resolve extensions: ['.js', '.json'] });
const urlForCurrentDir = '/components/thin-hook';
function bundlerContextGeneratorFactory(nodeLibs) { // Note: Not tested on Windows return function requireContextGenerator(astPath) { let ast = astPath[astPath.length - 1][1]; let context = hook.contextGenerators.method(astPath); if (ast.type === 'CallExpression' && ast.callee.type === 'Identifier' && ast.callee.name === 'require' && ast.arguments.length === 1 && ast.arguments[0].type === 'Literal' && typeof ast.arguments[0].value === 'string') { let name = ast.arguments[0].value; let origin = context.split(/,/)[0]; let cwd = process.cwd(); let originUrlDir = path.dirname(origin); let originPhysicalDir = cwd + originUrlDir.substring(urlForCurrentDir.length); let adjustedName = name; let resolved; let componentPath; let componentName; if (name[0] === '.') { resolved = resolveSync({}, originPhysicalDir, name); } else { resolved = nodeLibs[name]; if (!resolved) { resolved = resolveSync({}, cwd, name); } } componentPath = resolved.substring(cwd.length); componentName = urlForCurrentDir + componentPath; console.log('requireContextGenerator: context = ' + context + ' name = ' + name + ' componentName = ' + componentName); context += '|' + componentName; } return context; }; }
hook.contextGenerators.webpack = bundlerContextGeneratorFactory(nodeLibsBrowser); hook.contextGenerators.browserify = bundlerContextGeneratorFactory(browserifyBuiltins);
// Hook transformer - browserify transform
function hookTransformFactory(contextGeneratorName) {
return function hookTransform(file) {
let cwd = process.cwd();
let chunks = [];
function transform(chunk, encoding, callback) {
chunks.push(chunk);
callback();
}
function flush(callback) {
let stream = this;
let code = Buffer.concat(chunks).toString();
let context =
//file.substring(cwd.length); // based on the build path
urlForCurrendDir + file.substring(cwd.length); // based on the polyserve path mapping without --npm option
if (!file.match(/\/node_modules\/webpack\/buildin\/module[.]js$/)) { // TODO: Hooking webpack/buildin/module.js raises an error
code = hook(code,
'__hook__', // hookName = '__hook__',
[ [ context, {} ] ], // initialContext = [],
contextGeneratorName, // contextGeneratorName = 'method',
true, // metaHooking = true,
true, // _hookProperty = getHookProperty(),
null, // _sourceMap = null,
false, // asynchronous = false,
false, // _compact = getCompact(),
true, // _hookGlobal = getHookGlobal(),
'_pp_', // _hookPrefix = getHookPrefix(),
{ require: true, module: true, exports: true } // initialScope = null
);
}
console.log('hook ', file);
stream.push(code);
callback(null);
}
return through(transform, flush);
}
}
// Hook CommonJs modules in browserify
// NOTES:
// - Wrappers are not hooked
gulp.task('browserify-commonjs', () => {
const cwd = process.cwd();
return browserify('./demo/commonjs.js', { standalone: 'commonjs_module', insertGlobals: false, insertGlobalVars: {
__hook__: undefined
} })
.transform({ global: true }, hookTransformFactory('browserify'))
.bundle()
.pipe(source('browserify-commonjs.js'))
.pipe(buffer())
.pipe(gulp.dest('./demo'));
});
// Hook CommonJs modules in webpack
// NOTES:
// - Wrappers like __webpack_require__ are not hooked
gulp.task('webpack-commonjs', () => {
const cwd = process.cwd();
const webpackConfig = {
entry: "./demo/commonjs.js",
output: {
filename: "webpack-commonjs.js"
},
plugins: [
new webpack.LoaderOptionsPlugin({
options: {
transforms: [
hookTransformFactory('webpack')
]
}
})
],
module: {
loaders: [{
test: /\.js$/,
loader: 'transform-loader?0',
}],
},
};
return webpackStream(webpackConfig, webpack)
.pipe(gulp.dest('./demo'));
});
// Hook ES6 modules in webpack
// NOTES:
// - Wrappers like __webpack_require__ are not hooked
gulp.task('webpack-es6-module', () => {
const cwd = process.cwd();
const webpackConfig = {
entry: "./demo/es6-module3.js",
output: {
filename: "webpack-es6-module.js"
},
plugins: [
new webpack.LoaderOptionsPlugin({
options: {
transforms: [
hookTransformFactory('webpack')
]
}
})
],
module: {
loaders: [{
test: /\.js$/,
loader: 'transform-loader?0',
}],
},
};
return webpackStream(webpackConfig, webpack)
.pipe(gulp.dest('./demo'));
});
// module-for-base-class.js
export class C { static sm(){} m(){} }
export const baseObj = { p: v };
// module-for-extended-class.js
import { C, baseObj } from "./module-for-base-class.js";
export class E extends C { static s(){} m(){} }
export const extendedObj = Object.assign(Object.create(baseObj), { p2: v2 });
http://www.webgraphviz.com/
digraph g {
rankdir=UD;
ratio = fill;
node [style=filled fontsize=12];
"Object" [color=lightblue]
"Function" [color=lightblue]
"class C { static sm(){} m(){} }" [color=lightblue]
"class E extends C { static s(){} m(){} }" [color=lightblue]
"Object.prototype" [color=lightgreen]
"Function.prototype" [color=lightgreen]
"C.prototype" [color=lightgreen]
"E.prototype" [color=lightgreen]
"Object" -> "Function.prototype" [label="__proto__"]
"Object" -> "Object.prototype" [color="0.348 0.839 0.839" label = "prototype" ]
"Object.prototype" -> "Object" [label = "constructor" ]
"Object.prototype" -> "Object.prototype.hasOwnProperty()" [label="hasOwnProperty"]
"Object.prototype.hasOwnProperty()" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"Object" -> "Object.create()" [label="create"]
"Object.create()" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"{p:v}" -> "Object.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"{p:v}" -> "v" [label="p"]
"{p2:v2}" -> "{p:v}" [color="0.650 0.700 0.700" label = "__proto__" ]
"{p2:v2}" -> "v2" [label="p2"]
"{p3:v3}" -> "null" [color="0.650 0.700 0.700" label = "__proto__" ]
"{p3:v3}" -> "v3" [label="p3"]
"Function" -> "Function.prototype" [color="0.348 0.839 0.839" label = "prototype" ]
"function f(){}" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"()=>{}" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"class C { static sm(){} m(){} }" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"class C { static sm(){} m(){} }" -> "C.prototype" [color="0.348 0.839 0.839" label = "prototype" ]
"class C { static sm(){} m(){} }" -> "C.sm()" [label = "sm" ]
"C.sm()" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"C.prototype.m()" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"C.prototype" -> "class C { static sm(){} m(){} }" [label = "constructor" ]
"C.prototype" -> "C.prototype.m()" [label = "m" ]
"C.prototype" -> "Object.prototype" [color="0.650 0.700 0.700" label="__proto__"]
"class E extends C { static s(){} m(){} }" -> "class C { static sm(){} m(){} }" [color="0.650 0.700 0.700" label = "__proto__" ]
"class E extends C { static s(){} m(){} }" -> "E.prototype" [color="0.348 0.839 0.839" label = "prototype" ]
"class E extends C { static s(){} m(){} }" -> "E.s()" [label = "s" ]
"E.prototype.m()" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"E.s()" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"E.prototype" -> "E.prototype.m()" [label = "m" ]
"new C()" -> "C.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"new C()" -> "value" [label="instanceProperty"]
"new E()" -> "E.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"new E()" -> "value2" [label="instanceProperty"]
"E.prototype" -> "class E extends C { static s(){} m(){} }" [label = "constructor" ]
"E.prototype" -> "C.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"Function" -> "Function.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
"Function.prototype" -> "Function" [label = "constructor" ]
"Function.prototype" -> "Object.prototype" [color="0.650 0.700 0.700" label = "__proto__" ]
}
[demo][acl] Support modules
Tasks (Specs are tentative)
require('module.js')
.js
extension (#199)import('module.js')
import
import from 'module.js'
export
export * from 'module.js'
require()
context generator for pre-hooked modules/base/context/module1.js,x|/target/virtual/context/module.js
require()
handlingimport()
handlingimport
handlingexport
handling