Improve _req() resolution by writing a .js file and then using node.js require()...
authorNick Downing <downing.nick@gmail.com>
Sun, 21 Oct 2018 23:58:52 +0000 (10:58 +1100)
committerNick Downing <nick@ndcode.org>
Tue, 30 Oct 2018 07:54:35 +0000 (18:54 +1100)
js_template.js
package.json
visitors.js

index 4fd5244..1fb8a9d 100644 (file)
@@ -1,44 +1,71 @@
-let _BuildCache = require('BuildCache')
-let _acorn = require('./dist/acorn')
-let _astring = require('astring')
-let _fs = require('fs')
-let _html_escape = require('html-escape')
-let _path = require('path')
-let _transform = require('./transform')
-let _visitors = require('./visitors')
-let _util = require('util')
+let BuildCache = require('BuildCache')
+let acorn = require('./dist/acorn')
+let astring = require('astring')
+let fs = require('fs')
+let html_escape = require('html-escape')
+let path = require('path')
+let transform = require('./transform')
+let visitors = require('./visitors')
+let util = require('util')
 
-let _fs_readFile = _util.promisify(_fs.readFile)
+let fs_readFile = util.promisify(fs.readFile)
+let fs_stat = util.promisify(fs.stat)
+let fs_writeFile = util.promisify(fs.writeFile)
 
-let _build_cache = new _BuildCache()
-let _js_template = async (_root, _dir, _name) => {
-  while (_name.charAt(0) === '/') {
-    _dir = _root
-    _name = _name.slice(1)
+let build_cache = new BuildCache()
+let js_template = async (root, dirname, pathname) => {
+  while (pathname.charAt(0) === '/') {
+    dir = root
+    pathname = pathname.slice(1)
   }
-  _name = _path.posix.resolve(_dir, _name)
-  return _build_cache.get(
-    _name,
-    async _result => {
-      _text = await _fs_readFile(_name, {encoding: 'utf-8'})
-      console.log('compiling', _name)
-      let _dir = _path.posix.dirname(_name)
-      let _req = async _name => _js_template(_root, _dir, _name)
-      _result.value = await (
-         eval(
-          _astring.generate(
-            _transform.transform(
-              _visitors,
-              _acorn.parse(
-                '(async function() {' + _text + '})'
-              )
+  pathname = path.posix.resolve(dirname, pathname)
+  dirname = path.posix.dirname(pathname)
+  return build_cache.get(
+    pathname,
+    async result => {
+      let stats = await fs_stat(pathname)
+
+      let js_pathname = path.posix.resolve(
+        dirname,
+        `.${path.posix.basename(pathname)}.js`
+      )
+
+      let js_stats
+      try {
+        js_stats = await fs_stat(js_pathname)
+      }
+      catch (err) {
+        if (err.code !== 'ENOENT') // err type???
+          throw err
+        //js_stats = undefined
+      }
+      if (js_stats === undefined || stats.mtimeMs > js_stats.mtimeMs) {
+        text = await fs_readFile(pathname, {encoding: 'utf-8'})
+        console.log('compiling', pathname)
+        await fs_writeFile(
+          js_pathname,
+          astring.generate(
+            transform.transform(
+              visitors,
+              acorn.parse(
+                'module.exports = async (_req, _html_escape) => {' +
+                text +
+                '}')
             ),
-            {indent: ''}
-          )
+            {} //indent: ''}
+          ),
+          {encoding: 'utf-8'}
         )
-      )()
+      }
+      else
+        console.log('reloading', js_pathname)
+
+      result.value = await (require(js_pathname))(
+        async pathname => js_template(root, dirname, pathname),
+        html_escape
+      )
     }
   )
 }
 
-module.exports = _js_template
+module.exports = js_template
index 99f2863..abfe977 100644 (file)
@@ -32,7 +32,6 @@
     "prepare": "cd ..; npm run build:main && npm run build:bin"
   },
   "dependencies": {
-    "BuildCache": "file:/home/nick/src/build_cache.git/BuildCache-1.0.0.tgz",
     "astring": "^1.3.1",
     "html-escape": "^2.0.0"
   }
index de605db..cdeca89 100644 (file)
@@ -242,8 +242,32 @@ let html_body = (context, st, c) => {
 let visitors = Object.assign({}, transform.visitors)
 let visitors_ExpressionStatement = visitors.ExpressionStatement
 visitors.ExpressionStatement = (node, st, c) => {
+  if (node.expression.type === 'Literal')
+    return {
+      type: 'ExpressionStatement',
+      expression: {
+        type: 'CallExpression',
+        callee: {
+          type: 'MemberExpression',
+          object: {
+            type: 'Identifier',
+            name: '_out'
+          },
+          property: {
+            type: 'Identifier',
+            name: 'push'
+          },
+          computed: false
+        },
+        arguments: [
+          {
+            type: 'Literal',
+            value: html_escape(node.expression.value.toString())
+          }
+        ]
+      }
+    }
   if (
-    node.expression.type === 'Literal' ||
     node.expression.type === 'TemplateLiteral' ||
     node.expression.type === 'TaggedTemplateLiteral'
   )