lasso-js / lasso

Advanced JavaScript module bundler, asset pipeline and optimizer
582 stars 75 forks source link

Problem using lasso API for dynamic dependency injection on render #66

Open jcc2303 opened 9 years ago

jcc2303 commented 9 years ago

After giving up trying to use browser.json for lasso, we have been trying to use the lasso API directly to inject our dependencies...

Our marko render function

'use strict';
let marko = require('./marko-config');
let lasso = require('lasso');

function findTemplate(template) {
  console.log(template);
  return `../../views/pages/${template}/${template}.marko`
}

function resolveTemplate(templateName) {
  let templatePath = findTemplate(templateName);
  return require.resolve(templatePath);
}

module.exports = function(response, template, data) {
  console.log('render - template', template);
  let resolvedTemplate = resolveTemplate(template);
  console.log(resolvedTemplate);
  //response.body = marko.load(resolvedTemplate).stream(data);
  //response.type = 'text/html';

  let pageDependencyConfig = {
    name: 'registration',
    dependencies: [
      "./public/registration.js"
    ]
  };
  var headHtml, bodyHtml;

  lasso.lassoPage(pageDependencyConfig,
    function(err, lassoPageResult) {
      if (err) {
        console.log(err);
      }

      console.log('lassoPageResult ', lassoPageResult);
      headHtml = lassoPageResult.getHeadHtml();
      // headHtml will contain something similar to the following:
      // <link rel="stylesheet" type="text/css" href="static/my-page-169ab5d9.css">

      bodyHtml = lassoPageResult.getBodyHtml();
      // bodyHtml will contain something similar to the following:
      //  <script type="text/javascript" src="static/my-page-2e3e9936.js"></script>

      marko.load(resolvedTemplate).render({
          name: 'Frank'
        },
        function(err, output) {
          console.log('output ',output);

          response.body = output;
          response.type = 'text/html';
        });

    });

}

in the terminal

output  <!DOCTYPE html> <html lang="en"> <head></head><body><div class="container" id="content"><div id="registration-form" class="container"><p>hello</p></div></div></body></html>
_http_outgoing.js:335
    throw new Error('Can\'t set headers after they are sent.');
          ^
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
    at Object.module.exports.set (/home/javiercabrera/smi-workspace/rapid-render/node_modules/koa/lib/response.js:419:16)
    at Object.length (/home/javiercabrera/smi-workspace/rapid-render/node_modules/koa/lib/response.js:176:10)
    at Object.body (/home/javiercabrera/smi-workspace/rapid-render/node_modules/koa/lib/response.js:140:19)
    at Object.body (/home/javiercabrera/smi-workspace/rapid-render/node_modules/koa/node_modules/delegates/index.js:92:31)
    at /home/javiercabrera/smi-workspace/rapid-render/lib/server/render.js:66:25
    at EventEmitter.<anonymous> (/home/javiercabrera/smi-workspace/rapid-render/node_modules/marko/runtime/marko-runtime.js:113:17)
    at emitNone (events.js:67:13)
    at EventEmitter.emit (events.js:166:7)
    at Object.StringWriter.end (/home/javiercabrera/smi-workspace/rapid-render/node_modules/marko/node_modules/async-writer/lib/AsyncWriter.js:28:25)
    at AsyncWriter._finish (/home/javiercabrera/smi-workspace/rapid-render/node_modules/marko/node_modules/async-writer/lib/AsyncWriter.js:481:26)
    at AsyncWriter.handleEnd (/home/javiercabrera/smi-workspace/rapid-render/node_modules/marko/node_modules/async-writer/lib/AsyncWriter.js:474:22)
    at AsyncWriter.end (/home/javiercabrera/smi-workspace/rapid-render/node_modules/marko/node_modules/async-writer/lib/AsyncWriter.js:437:18)
    at Object.Template.render (/home/javiercabrera/smi-workspace/rapid-render/node_modules/marko/runtime/marko-runtime.js:141:22)
    at /home/javiercabrera/smi-workspace/rapid-render/lib/server/render.js:48:36
    at done (/home/javiercabrera/smi-workspace/rapid-render/node_modules/lasso/lib/Lasso.js:664:17)
patrick-steele-idem commented 9 years ago

I don't use Koa, but maybe try switching the following lines:

Bad:

response.body = output;
response.type = 'text/html';

Good:

response.type = 'text/html';
response.body = output;

I think when you set the body property on the response object it is writing the HTTP body. After you write the HTTP body you can't set any headers. When the response.type = 'text/html'; line runs it is attempting to set the Content-Type header and failing because the body has already been sent due to the response.body = output; line.

patrick-steele-idem commented 9 years ago

Hi @jcc2303, did you have a chance to try my suggestion above?

aversilov commented 6 years ago

@patrick-steele-idem I tried this in my app. The problem still remain: image P.S. I have two .marko-files with <lasso-page package-path="./browser.json" /> (it's two different browser.json of course). But it's absolutly normal - to have in each .marko-file own .json'ed package with bundled JS'es included).

aversilov commented 6 years ago

@patrick-steele-idem Can you help me?

ianvonholt commented 6 years ago

@aversilov Do you have separate names for each lasso-page definition?

Ex: <lasso-page name="unique-name" package-path="./browser.json">

Additionally, could you post more on the specific of the unhandled rejection?