npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

marko-starter

v2.1.0

Published

Simplify building and running a marko project

Downloads

2,392

Readme

marko-starter

marko-starter is a project for building and running Marko.js applications. It provides a toolset that includes a build pipeline and a generic HTTP server with routing that makes building Marko applications easy! If you're looking to build a project from scratch quickly, check out marko-devtools, which includes a command for creating Marko projects with marko-starter!

Getting Started

Requires Node 6+

To get started, marko-starter may be installed locally to your project or globally:

npm install marko-starter --save

Or installed globally:

npm install marko-starter -g

Adding pages

Adding a page to your application simply requires adding a new directory under the routes/ directory. Inside this directory, you can put either an index.marko template and/or a route.js file that exports a handler method.

Given a directory structure like this:

⤷ routes/
  ⤷ my-page/
    ⤷ index.marko

Hitting /my-page will render index.marko.

Custom routes and params

By default, the route for a page is determined by the page's directory name, but you can also define a custom route for your page. This route can include custom express-style url parameters. You do this by exporting a path from a route.js file in your page's directory:

exports.path = '/people/:name';

If using an index.marko template for the route, the input will contain the following properties:

| Property | Type | Description | Example | |------------|----------|--------------------------------------------------------------------------------------|--------------------| | path | String | The path from the request | "/people/frank" | | params | Object | An object that contains String properties populated from the path placeholders | {name: "frank"} | | query | Object | An object that contains String query parameters properties from the query string | {age: "27"} | | metadata | Object | The route metadata | {secure: false} |

Given a route:

/people/:name

And a template:

<ul>
    <li>${input.params.name}</li>
    <li>${input.query.age}</li>
</ul>

When you hit the following url:

/people/frank?age=27

The rendered output would be:

<ul>
    <li>frank</li>
    <li>27</li>
</ul>

Routes may also be added to the projectConfig:

my-project/project.js

const template = require('./template.marko');

module.exports = require('marko-starter').projectConfig({
  ...
  routes: [
    {
      path: '/foo/:name',
      handler(input, out) {
        const name = input.params.name;
        template.render({ name }, out);
      }
    }
  ]
});

Custom handler entry

If you need more control over the data passed to the template or don't even want to render a template, you can define a custom handler function in your route.js file:

const template = require('./index.marko');

exports.path = '/people/:name';

exports.handler = (input, out) => {
    const name = input.params.name;
    template.render({ name }, out);
};

Adding components

To add a component, simply create a new directory under the components/ directory. The directory name will be used as the component name. Inside the directory you should put an index.marko file.

⤷ components/
  ⤷ my-component/
     ⤷ index.marko

Given the above structure, you will be able to use <my-component> in any other component template or page template.

Client-side behavior

Adding client-side behavior to a component is as simple as defining methods in your index.marko in a class tag and exporting them within the template, or defining a component.js file next to your index.marko file that exports the methods.

index.marko

class {
    onInput(input) {
        this.state = {
            count: input.count
        }
        this.initialCount = input.count
    }
    incrementCount() {
        this.state.count++
    }
    resetCount() {
        this.state.count = this.initialCount
    }
}

<div>${state.count}</div>
<button on-click('incrementCount')>+</button>
<button on-click('resetCount')>reset</button>

index.marko

<div>${state.count}</div>
<button on-click('incrementCount')>+</button>
<button on-click('resetCount')>reset</button>

component.js

module.exports = {
    onInput(input) {
        this.state = {
            count: input.count
        }
        this.initialCount = input.count
    },
    incrementCount() {
        this.state.count++
    },
    resetCount() {
        this.state.count = this.initialCount
    }
};

Styles

To add styles to your components, either add a top-level <style> tag in your index.marko file or define a style.css file next to your index.marko file.

Subcomponents

You can also create a components directory under another component and those components will only be available to the parent component.

Given a directory structure like this:

⤷ components/
  ⤷ my-component/
    ⤷ components/
      ⤷ my-subcomponent/
        ⤷ index.marko
    ⤷ index.marko

You will only be able to use my-subcomponent from the my-component/index.marko template or other subcomponents defined under my-component/components.

Building a static site

Generating a static site is simple:

marko-starter build

The build tool will hit all your page routes and generate the resulting html files and assets in a build directory at your project root. You can then take this build directory and host it on any provider that provides static hosting.

Dynamic routes

If you have routes that have custom parameters, the build tool needs to know which parameters can be passed. You can export a params array from the route.js file for a page.

exports.path = '/people/:name';

exports.params = [
    { name:'reyna' },
    { name:'dakota' },
    { name:'jordan' },
];

params may be programmatically generated and may also be a Promise.

Overriding Project Configuration

marko-starter configuration options, including the lasso build config can be overriden by creating a project.js file in the route of the project. For example:

const isProduction = process.env.NODE_ENV === 'production';

module.exports = require('marko-starter').projectConfig({
    routePathPrefix: '/',
    lassoConfig: {
        bundlingEnabled: isProduction,
        fingerprintsEnabled: isProduction,
        require: {
          // ...
        },
        minifyJS: false,
        plugins: [
            'lasso-marko'
        ]
    }
});

marko-starter also provides useful hooks for executing code before and after running a build or starting the server:

  • beforeBuild: Runs before the build runs
  • beforeStartServer: Runs before the server is started
  • afterBuild: Runs after the build is complete
  • afterServerStarted: Runs after the server has successfully started

Hooks can be registered by providing the hook as a property calling projectConfig, and may return a Promise:

module.exports = require('marko-starter').projectConfig({
  ...
  beforeBuild() {
    console.log('Executing before the build starts!');
    return Promise.resolve();
  }
  ...
});

Serving a static site over HTTP

You can easily serve the directory that contains the statically built version of your application with marko-starter.

marko-starter serve-static

Now you can navigate to localhost:8080 to view the application!

marko-starter uses http-server to serve static files. You can pass command line arguments that http-server supports:

marko-starter serve-static -p 9001 # Serve on port 9001

Project Plugins

External project plugins can be installed into marko-starter. The projectConfig can take a plugins option with an array of plugins. A plugins can be a string representing an installed node module or a plugin object:

my-project/project.js

module.exports = require('marko-starter').projectConfig({
  plugins: ['marko-starter-babel']
});

Publishing to GitHub Pages (or other remote repo)

Simply add a static-repo entry to your package.json which is a git url. When running npm run build, a new commit will be created and pushed to the remote repository.

{
  ...
  "static-repo": "[email protected]:user/repo.git#branch"
}

If you're publishing a project site at a subdirectory, you'll also want to set a baseurl entry which will be prepended to any root-relative urls.

{
  ...
  "static-repo": "[email protected]:user/repo.git#branch",
  "baseurl": "/repo"
}

Example project

For an example of a project that is using marko-starter check out markojs-website