t2ym / thin-hook

Thin Hook Preprocessor
Other
4 stars 1 forks source link

[demo][acl] Support modules #191

Open t2ym opened 6 years ago

t2ym commented 6 years ago

[demo][acl] Support modules

Tasks (Specs are tentative)

t2ym commented 6 years ago

Note

t2ym commented 6 years ago

Context generator for bundler

Note

context format

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);

t2ym commented 6 years ago

Hook transformer for bundlers

t2ym commented 6 years ago

Gulp tasks for bundlers

CommonJS modules by browserify

// 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'));

});

CommonJs modules by webpack

// 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'));

});

ES6 Modules by webpack

// 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'));
});
t2ym commented 4 years ago

ES Module Policy Patterns (draft 2)

Change Logs

t2ym commented 4 years ago

Extended and Exported Classes must be handled properly

// 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 });

Note: Graphviz source code for 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__" ]
}
t2ym commented 4 years ago

[DIGRESSION]

At the time of this posting, my fatigue has accumulated like this:

I need some time to clear work areas in my mind and find consistent and performant schema for ES module support as my mind is messed like this:

As you have just realized from this digression post, I am steadily recovering from the fatigue

I hope you wait for updates

Notes