I'd like to start by saying awesome concept, finally a library which puts performance first.
Now, I've just come from an AngularJS/Gulp development background so I'm new to the whole JavaScript bundlers concept.
I'm trying to wrap my head around how the recommended file structure should look like on bigger projects. I've been downloading and testing out the samples (awesome) but I haven't been able to stitch them together. I also had a hard time understanding how client side rendering with marko works, server side wasn't too hard to figure out, coming from Handlebars it really wasn't that much different.
Tbh I think explaining from scratch for beginners who have just come from i.e. jQuery how marko works will draw _a lot_ more attention to it.
After looking at the following repos I've sot of come up with the following file structure.
/project/src/client.js <---
https://github.com/marko-js-samples/marko-widgets-client-rendering
/project
/project/build <--- what is this directory for?
/project/node_modules <--- no brainer, npm modules
/project/src <--- dev files
/project/src/marko.json <--- Haven't understood this file yet
/project/src/client.js <--- Haven't understood why this file is here?
/project/src/common <--- I'm guessing this is for files that all pages or components share
/project/src/common/browser.json <--- lasso needs this to compile correctly (code splitting etc.)
/project/src/common/common.css <--- css styles when a page/component includes the "common" package? (overrides?)
/project/src/common/common.js <--- same as .css but with JS
/project/src/componenets <--- Holds marko-widget reuseable componenets
/project/src/componenets/my-widget <--- Is a marko-widget reuseable componenet
/project/src/componenets/my-widget/index.js <--- [What does this do and what should be in it?](http://markojs.com/docs/marko-widgets/get-started/#split-renderer-and-widget-1)
/project/src/componenets/my-widget/renderer.js <--- [What does this do and what should be in it?](http://markojs.com/docs/marko-widgets/get-started/#split-renderer-and-widget-1)
/project/src/componenets/my-widget/widget.js <--- [What does this do and what should be in it?](http://markojs.com/docs/marko-widgets/get-started/#split-renderer-and-widget-1)
/project/src/componenets/my-widget/style.css <--- Holds the style for the component (overrides?)
/project/src/componenets/my-widget/template.marko <--- Holds the html markup for the component
/project/src/pages <--- Holds marko template pages
/project/src/pages/home <--- Holds the home marko template page
/project/src/pages/home/browser.json <--- lasso needs this to compile correctly (code splitting etc.)
/project/src/pages/home/client.js <--- Whats the difference between this and index.js?
/project/src/pages/home/index.js <--- Whats the difference between this and client.js?
/project/src/pages/home/style.css <--- Holds the style for the component (overrides?)
/project/src/pages/home/template.marko <--- Holds the html markup for the page
/project/src/pages/home/template.marko.js <--- auto-generated
/project/static <--- This is the directory which should be served publicly (lasso bundles end up here)
/project/.cache <--- Used by lasso for quicker bundling?
I am also wondering how does one create a template which nests another template? I would like to pass data as well.
Also tags vs. widgets?
I think being able to explain this structure well for newcomers will increase their chance of using marko. Personally I would like to see an example project which touches all areas so I can see how they could be fit together, right now I'm shooting in the dark!
As stated before client marko rendering (both non widget and widget) is still unclear to me. I tried bundling with webpack etc. however it wasn't until I looked at lasso I realised that lasso is actually needed. I think this should be more clear in the marko & marko-widgets documentation when talking about client side rendering.
Also thumbs up to upgrading to ES6 syntax (import/export). I want to completely stop writing CommonJS and starting writing just offical JS.
I probably have more questions, will take them later! :)
Hey @basickarl, here's what I consider to be a good directory structure:
/
⤷ .cache/ (auto-generated-files)
⤷ config/
⤷ development.json
⤷ production.json
⤷ node_modules/ (installed-modules)
⤷ src/
⤷ components/
⤷ some-component/
⤷ test/
⤷ index.js
⤷ style.css
⤷ template.marko
⤷ template.marko.js
⤷ .../ (additional-components)
⤷ layouts/
⤷ _common/ (files-common-to-all-layouts)
⤷ main/
⤷ fonts/
⤷ sanfrancisco.woff2
⤷ images/
⤷ logo.webp
⤷ style.css
⤷ layout.marko
⤷ layout.marko.js
⤷ .../ (additional-layouts)
⤷ pages/ (directory-of-pages)
⤷ home/ (the-home-page)
⤷ components/ (components-used-by-home-only)
⤷ images/
⤷ hero-image.webp
⤷ index.js (home-route-handler)
⤷ style.css
⤷ home.marko
⤷ home.marko.js
⤷ .../ (additional-pages)
⤷ app.js
⤷ static/ (auto-generated-files)
⤷ test/ (test-related-files)
⤷ package.json
And to touch on some of your other questions:
_template.marko_
<ul for(item in data.items)>
<include('./item.marko') name=item.name />
</ul>
_item.marko_
<li>${data.name}</li>
Typically you'll see widgets implemented as custom tags. A widget's template uses the w-bind attribute to link to a JavaScript file that contains its client-side behavior.
Marko will automatically look for directories under components/ and scan them for custom tags. If you want to define individual tags, use custom transforms, or scan a directory other than components/, you'll need to use this file to provide the configuration. It used to be that you needed this file even if all your components were under a components/ directory, which is why you'll find it in many examples.
A module bundler is needed to use marko client side, webpack should work, but I don't have any experience using it with marko. We're currently working on some improvements (performance and otherwise) to client-side rendering. We should update the docs and give some better examples once that work is complete.
We have an sample project that makes use of Marko, but currently it's internal to eBay. We'd need to remove some eBay specific things from the app, but it would probably be worthwhile to make that generally available.
I agree. This is an area where we could use some help if you're willing. It would be amazing to start seeing some training content provided by people outside the project maintainers. I think when you're just starting to learn something you're in a unique position to help people at the same place, as things become familiar we tend to forget the aspects that used to be difficult for us.
If you have more questions, feel free to join us on gitter and welcome to the community! :tada:
Thanks for this information. But I still have a doubt. All content that are inside src folder, is focussed only in the modularization of client side, right?
@davidenq everything under src/ includes all application source code (both server-side, client-side and isomorphic code). In most cases, whether or not code is client-side or server-side will depend on how the code is used. Do you have any other specific doubts?
I'm going to go ahead and close this issue. If you still have unanswered questions, please feel free to add comments here or open a new Github issue.
@mlrawlings Brilliant example! I have another question. I've been reading and haven't found an answer to it yet. The code below you pass item.name to the tempalte. Is it possible to pass a JSON object instead?
<ul for(item in data.items)>
<include('./item.marko') name=item.name />
</ul>
@basickarl You can pass the data as the second argument for the <include(path[, data])> tag:
<ul for(item in data.items)>
<include('./item.marko', item) />
</ul>
I am having too many components in on folder /project/src/componenets .
Whats the way of grouping components pages wise ?
@Anant-Raj
The components/ directory can exist in multiple places in your project and they are scoped. We recommend the following directory structure:
my-app/
components/ ← top-level UI components shared by all pages/routes
routes/
about-me/
components/ ← UI components scoped to the about-me route
index.marko
index/
components/ ← UI components scoped to the index route
index.marko
You can see this project structure in action as part of our starter app: https://github.com/marko-js-samples/marko-starter-demo
Let me know if you would like more details, but hopefully that answers your question.
error:[ERROR] Error: Render async fragment error (lasso-slot:head). Exception: Error: Failed to walk dependency
[require: C:\marko_nodejssrc\pages\login\template.marko.js.init.js]. Dependency chain: [require: C:\marko_nodejssrc\pages\login\template.marko.js.init.js]. Cause: Error: Module not found: C:marko_nodejssrccomponentslogin-formindex.marko (from "src\pages\login" and referenced in "src\pages\login\template.marko.js.init.js")
Help in resolving the issue
Using marko v4 version;
Because of above error on-click,on-submit events are not calling
@bhoomikatm are you using the latest version of lasso-marko?
yeah using Marko v4 version
package.json:
"marko": "^4"
Hi
Is any sample examples available in Git hub on meta-router?
the following link having explanation- https://github.com/patrick-steele-idem/meta-router
But not sample example
Please help me in getting sample examples
Most helpful comment
Hey @basickarl, here's what I consider to be a good directory structure:
And to touch on some of your other questions:
How does one create a template which nests another template?
_template.marko_
_item.marko_
tags vs. widgets?
Typically you'll see widgets implemented as custom tags. A widget's template uses the
w-bindattribute to link to a JavaScript file that contains its client-side behavior.what is marko.json?
Marko will automatically look for directories under
components/and scan them for custom tags. If you want to define individual tags, use custom transforms, or scan a directory other thancomponents/, you'll need to use this file to provide the configuration. It used to be that you needed this file even if all your components were under acomponents/directory, which is why you'll find it in many examples.client marko rendering (both non widget and widget) is still unclear to me
A module bundler is needed to use marko client side, webpack should work, but I don't have any experience using it with marko. We're currently working on some improvements (performance and otherwise) to client-side rendering. We should update the docs and give some better examples once that work is complete.
I would like to see an example project which touches all areas so I can see how they could be fit together
We have an sample project that makes use of Marko, but currently it's internal to eBay. We'd need to remove some eBay specific things from the app, but it would probably be worthwhile to make that generally available.
I think explaining from scratch for beginners who have just come from i.e. jQuery how marko works will draw a lot more attention to it.
I agree. This is an area where we could use some help if you're willing. It would be amazing to start seeing some training content provided by people outside the project maintainers. I think when you're just starting to learn something you're in a unique position to help people at the same place, as things become familiar we tend to forget the aspects that used to be difficult for us.
If you have more questions, feel free to join us on gitter and welcome to the community! :tada: