Skip to content

Additional module types #4321

@Jamesernator

Description

@Jamesernator

This is a followup to the issue on JSON modules (#4315) particularly regarding this comment.

This is just a list of common formats along with some suggestions and examples as to how they could be interpreted and used:

CSS (text/css)

The most logical thing to do when seeing a CSS response would be to construct a constructible stylesheet from it.

This would be useful in the Webcomponents set of technologies for including additional stylesheets on a shadow root without manually downloading and instantiating them:

import styles from './MyElement.css'
import template from './MyElement.html'

class MyElement extends HTMLElement {
  constructor() {
    super()
    this._shadowRoot = this.attachShadow({ mode: 'closed' })
    this._shadowRoot.adoptedStyleSheets = [styles]
    this._shadowRoot.appendChild(template.content.cloneNode(true))
  }
}

Plain Text (text/plain)

This would be useful for loading config files and such that aren't in JSON. However I'm a bit cautious about this one because it might encourage sending arbitrarily files as text/plain even when they have a more narrow type they could be. It might be better to have a special protocol for loading any resource as text (e.g. import config from 'text:./some-file.yaml') so that even if the MIME type is something other than text/plain it is interpreted as a plain text file.

Example:

import configText from './config.yaml'
import yaml from 'yaml'

const config = yaml.load(configText) 

Binary Data (application/octet-stream)

Similar to plain text, it might be desirable to load binary data for further use. However it suffers the same issue that we might want to load binary data from any MIME type, not just application/octet-stream so we can perform our own processing on it.

import historicalSamples from './historicalSamples.bin'

class HistoricalData extends HTMLElement {
  constructor() {
    super()
    this._plotData(historicalSamples)
  }
}

Media (image/*, video/*, audio/*)

I'm not sure these are worth including as the reasons for importing them are likely to be varied, for example for audio, would consumers want an element they can clone? An AudioBuffer for use in web audio? etc. I think settling on what the best thing to give them might be difficult. But it's at least worth considering.

XML (application/xml)

XML is still occasionally used for configuration so exporting an XMLDocument might be useful. Overall I'm not sure how widely used this would be to justify it.

import graph from './network.graphml' // An XML format for graphs
import d3 from 'd3'

class GraphDemo extends HTMLElement {
  constructor() {
    super()
    this._displayGraph(graph)
  }
}

EventSource (text/event-stream)

This could be useful for if multiple modules want to subscribe to a single source of events, e.g.:

import stockChanges from '/api/stockChanges'

class PriceGraph extends HTMLElement {
  constructor() {
    // ...
    stockChanges.on('message', message => this._appendData(message))
  }
}
// Same EventSource as the other file
import stockChanges from '/api/stockChanges'

class AverageOverLastTenMinutes extends HTMLElement {
  constructor() {
    // ...
    stockChanges.on('message', message => this._updateAverage(message))
  }
}

Overall conclusions

Overall I'm not sure how much value would be gained from adding import-ability for all the common MIME types used on the web even if a lot of them save a bit of repetition for things like new Image(new URL('./foo.png', import.meta.url)) or new EventSource('/api/currentlyWatching').

I think the main one of interest is CSS as it's likely to see a lot of use alongside the already proposed HTML modules in the context of webcomponents.

I think it's probably worth looking at other types though to investigate if there are any strong use cases that would justify import-ing them frequently.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions