Skip to content
A loader for marko files and a plugin for universal bundling
TypeScript JavaScript
Branch: master
Clone or download
Latest commit c63eca3 Aug 7, 2019

README.md


@marko/webpack
API Stability TypeScript Styled with prettier Build status NPM Version Downloads Browser Bundle Size

A Marko plugin and loader for Webpack.

Details

Loader: @marko/webpack/loader

The loader portion of this module can be used standalone and simply transforms your Marko templates into the appropriate JavaScript depending on your webpack target.

You can override the output by adding a target option to the loader of target: "server" | "browser".

Plugin: @marko/webpack/plugin

The plugin actually creates two separate webpack plugins, the browser plugin and the server plugin.

These are intended to be used in a isomorphic webpack multi compiler where you are bundling both the server and the browser. The way it works is that the server plugin is going to analyze the top level Marko components in your server and automatically communicate with the browser compiler to retrieve the assets for that template.

This plugin also analyzes the top level Marko templates and determines if it is possible for them to rerender (currently the heuristic is simply does the component have an associated class or component.js). The plugin will automatically skip sending down any unnecessary top level templates to the browser.

The end result is that you setup a multi compiler (as shown below) and you can simply import Marko templates, and all assets are automatically generated and inlined into an optimized server response. No need to keep track of a webpack manifest yourself!

Installation

npm install @marko/webpack

Example

import MarkoPlugin from "@marko/webpack/plugin";

const markoPlugin = new MarkoPlugin();

export default [
  {
    entry: "./server.js",
    module: {
      rules: [
        {
          test: /\.marko?$/,
          loader: "@marko/webpack/loader"
        }
      ]
    },
    plugins: [markoPlugin.server]
  },
  {
    rules: [
      {
        test: /\.marko?$/,
        loader: "@marko/webpack/loader"
      }
    ],
    plugins: [markoPlugin.browser]
  }
];

Multiple client side compilers

Sometimes you need to have multiple compilers for your client side bundles. For example with i18n or even shipping dynamic runtime bundles to the browser.

The Marko webpack plugin allows you to pass a function which is inlined into the server bundle and can respond with the name of the compiler whose assets should be sent to the browser. For example with the webpack i18n plugin you might have a config like the following:

import MarkoPlugin from "@marko/webpack/plugin";
import I18nPlugin from "i18n-webpack-plugin";

const languages = {
  en: null,
  de: require("./de.json")
};

const markoPlugin = new MarkoPlugin({
  // $global here is the `out.global` from Marko.
  getClientCompilerName($global) {
    // You must return the name of one of the browser compilers below.
    return `Browser-${language}`;
  }
});

export default [
  {
    name: "Server",
    entry: "./server.js",
    module: {
      rules: [
        {
          test: /\.marko?$/,
          loader: "@marko/webpack/loader"
        }
      ]
    },
    plugins: [markoPlugin.server]
  },
  ...Object.keys(languages).map(language => ({
    name: `Browser-${language}`,
    rules: [
      {
        test: /\.marko?$/,
        loader: "@marko/webpack/loader"
      }
    ],
    plugins: [new I18nPlugin(languages[language]), markoPlugin.browser]
  }))
];

With the above config you can render your top level Marko template server side with a language global, like so:

template.render({ $global: { language: "de" } });

This will automatically send assets for the German language.

Dynamic public paths

When using the plugin, the server will automatically sync the runtime __webpack_public_path__ with the browser. This means that you only need to setup the dynamic public path on the server side.

Code of Conduct

This project adheres to the eBay Code of Conduct. By participating in this project you agree to abide by its terms.

You can’t perform that action at this time.