Component's <content /> not rendered after bundled

I have a fairly simple dropdown component that shows/hides content when a button is clicked. https://github.com/roemhildtg/spectre-canjs/tree/master/dropdown-menu

It works well in dev mode, but in production mode, when bundled with steal-tools, it only works in some of the bundles. In others, the toggling still shows the content wrapper div, but the content inside the tags does not appear.

Its difficult to reproduce since this issue works when bundling the component by itself, but when using this component in multiple bundles, the issue is occuring.

I have an example of the issue in a bundle here: https://roemhildtg.github.io/spectre-canjs/docs/dropdown-menu.html

I also have an example of the same component working correctly, but it is being used inside a parent component:
https://roemhildtg.github.io/spectre-canjs/docs/data-admin.html

It works well in dev mode, but in production mode, when bundled with steal-tools, it only works in some of the bundles.

What do you mean by “some of the bundles”? Why would the dropdown-menu be in multiple bundles?

I meant, the dropdown-menu is used in several bundles. So I think steal puts the dropdown-menu in a “shared” bundle that is used by several bundles.

Are there steps we can follow to see this locally? Thanks!

With my package spectre-canjs, yes. I don’t know of a simpler way to reproduce it though, unfortunately.

git clone https://github.com/roemhildtg/spectre-canjs.git
npm install
npm run docs

Then browse to the /spectre-canjs/data-admin/demo/demo.html for the working demo (screenshot above)

and /spectre-canjs/docs/dropdown-menu.html for the not working demo

I tried starting http-server to run your demos, but when I visit for example

http://10.0.1.38:8080/data-admin/demo/demo.html

It renders a blank page. I did do npm install. The browser console reports:

Failed to load resource: the server responded with a status of 404 (Not Found)

And in the terminal:

“GET /docs/spectre/steal.production.js” Error (404): “Not found”

I see that missing file is a script src here:

data-admin/demo/demo.html
16:<script src="../../docs/spectre/steal.production.js" main="docs-main" id="demo-source">

So, I ran npm run docs and now the demo page loads.

Clicking on the dropdown, the contents are there:

Clicking around tabs or reloading and the clicking back on the dropdown does not result in missing contents.

So, at this point I don’t think I can replicate your issue (assuming I have understood it correctly).

Hi @leoj3n, thanks for taking a look. I might not have explained well, but the example you tested is the working example.

There is another example that uses the same component that doesn’t work. spectre-canjs/dropdown-menu/demo/demo.html

Those dropdowns in the second example are similar to the first, but their <content /> block is not rendered correctly. What’s odd about the second example, is the wrapper div’s do appear, but the elements contained in what should be the <content /> blocks do not appear.

I can confirm the literal <content /> tag is inserted into the DOM on the http://10.0.1.38:8080/dropdown-menu/demo/demo.html just like you said, so yes now I am able to replicate the issue on that page. There are stache errors in the browser console:

Can you explain why it is necessary to build the docs before the demo will work? I have a hunch that the problem may be in your app’s build process.

I’m hosting the docs on github pages, and I need to build the docs to push them to gh-pages.

The demos still work though, if you switch the script tag to steal dev mode.


<script src="../../node_modules/steal.js" main="docs-main" id="demo-source">
  steal.import('spectre-canjs/dropdown-menu/demo/dropdown');
</script>

And oddly enough, in dev mode, the issue does not occur. It only happens when the items are bundled. It would make sense that the problem is in how I am building the bundles, but I have followed the correct steps as far as I know:

var stealTools = require('steal-tools');
var path = require('path');

stealTools.build({
    main: 'docs-main',
    config: path.join(__dirname, 'package.json!npm'),
    bundle: [
        'spectre-canjs/data-admin/demo/admin',
        'spectre-canjs/dropdown-menu/demo/dropdown',
        'spectre-canjs/filter-widget/demo/filter',
        'spectre-canjs/form-widget/demo/form',
        'spectre-canjs/list-table/demo/listTable',
        'spectre-canjs/modal-dialog/demo/dialog',
        'spectre-canjs/nav-container/demo/nav',
        'spectre-canjs/paginate-widget/demo/paginate',
        'spectre-canjs/property-table/demo/propertyTable',
        'spectre-canjs/toast-container/demo/toast'
    ]
}, {
    removeDevelopmentCode: false,
    bundleSteal: false,
    bundleAssets: true,
    sourceMaps: true,
    dest: 'docs/spectre'
});

Unrelated: the “main” and “id” attributes are running together on this tag:

<script src="../../docs/spectre/steal.production.js" main="docs-main"id="demo-source">

I’m still combing through your app to figure out why the dropdown isn’t working.

Working flow:

data-admin/demo/demo.html (<data-admin />) 
  '-> data-admin/template.stache (<nav-page label="List" page-id="list" />)
    '-> data-admin/templates/list.stache
      '-> list-table/list-table.stache
        '-> Working <dropdown-menu />

Script tag for steal in data-admin/demo/demo.html:

<script src="../../docs/spectre/steal.production.js" main="docs-main" id="demo-source">
    steal.import('spectre-canjs/data-admin/demo/admin');
</script>

Not working flow:

dropdown-menu/demo/demo.html
  '-> <dropdown-menu />

Script tag for StealJS in dropdown-menu/demo/demo.html:

<script src="../../docs/spectre/steal.production.js" main="docs-main" id="demo-source">
  steal.import('spectre-canjs/dropdown-menu/demo/dropdown');
</script>

Could it have something to do with the fact that in the working flow the custom element is within a stache template, while in the not working flow the custom element is directly within an html file?

Maybe the problem is in the files referenced by the script tags for StealJS?


EDIT:

In the working flow, data-admin/demo/admin.js is like:

const frag = stache.from('demo-html')(viewModel);

document.body.appendChild(frag);

In the not working flow, dropdown-menu/demo/dropdown.js is like:

document.body.appendChild(render(viewModel));

Honestly, I don’t know enough about bundling to solve this one. Perhaps @matthewp can help?

@leoj3n thanks for the suggestions. I’ll definitely look into those ideas and see if I can find anything to add.

We’ve been looking into it. There’s a bug … my guess is that <content/> isn’t registered early enough. I should have a fix out today.

1 Like

Here’s the issue:

can-stache 3.0.20 should fix this:

1 Like

Thanks @justinbmeyer; looks like you were spot-on about the <content/> element not being registered early enough. Also, thanks @roemhildtg; caused me to learn something new :smiley:

@justinbmeyer, @leoj3n Thanks to you guys! I really wasn’t sure where to start with this one, but it all makes sense now.

Edit: the fix worked, the dropdown menu is working in its bundle now.