Code Monkey home page Code Monkey logo

Comments (2)

caseyWebb avatar caseyWebb commented on June 15, 2024

First a drop-in solution...

Because you're only registering one route, you can actually just use a single middleware function for this.

NOTE: The middleware is the function being returned by the plugin in the example. Since the component name is dynamic, you don't need to curry it w/ a plugin.

NOTE: What is not shown in the original example is that the first argument to the middleware is a the route context. This is relevant because we can get various path information, including just the parsed bits with ctx.params

const dynamicComponentMiddleware: SimpleMiddleware = async (ctx: Context) => {
  // You *really* want to have some hardcoded prefix OR use the much more complicated require.context
  // otherwise webpack will include a manifest that contains EVERY file in the project which bloats the
  // bundle significantly
  //
  // For example, using import(someVariable) means webpack has to assume that "someVariable" can be ANYTHING.
  // By including the './components' directory prefix, we can at least limit the manifist to only contain files
  // in that directory.
  //
  // Using require.context will result in the best bundle size, but your project must follow strict conventions.
  // In our case, we use it to register any file matching `./components/*/index.ts` and it looks something like...
  //
  // const context = require.context('./', true, /\.\/[^/_]+\/index\.ts$/)
  // context.keys().forEach((c) => {
  //   const name = c.match(/\.\/([^/_]+)\/index\.ts$/)[1]
  //   ko.components.register(name, { ...context(c) })
  // })
  const componentName = ctx.params.component
  const componentDir = ctx.params.location
  const componentConfig = await import(`./components/${componentDir}/${componentName}`)

  // register the component if this is the first time it's being hit
  if (!ko.components.isRegistered(componentName)) {
    ko.components.register(componentName, componentConfig)
  }

  // tell the router which component to use
  ctx.route.component = componentName
}

Router.use(dynamicComponentMiddleware)

...then the caveats...

If possible though, I'd recommend against this pattern because you lose a lot of flexibility, a major one being nested routing. This pattern pretty much precludes you from using any of the more powerful features in the router.

...finally, an alternative.

Something else you may consider is using the component plugin in place of where you'd normally do ko.components.register. This is the idiomatic usage (and the pattern we use internally with very large SPAs), an example of which you can find here (parts of this repo are outdated, but everything in the views directory is the current recommended usage).

from knockout-contrib.

caseyWebb avatar caseyWebb commented on June 15, 2024

Feel free to re-open if you need additional help. I'm also available in the gitter channel.

from knockout-contrib.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.