Load JavaScript and related languages like TypeScript modules from the vault and the Internet.
Repository · Changelog · Community plugin · Related · Features · Installation · Usage · Contributing · Security
For first time users, read the installation section first!
This file is automatically opened on first install. You can reopen it in settings or command palette.
- Load JavaScript and TypeScript modules from the vault and the Internet on all platforms.
- Load modules at startup.
- No configuration needed.
- Resolves relative paths, vault paths, Markdown links, wikilinks, and external links.
- Loads Markdown files as code.
- Supports using other modules inside modules.
- Loads CommonJS (
module.exports
) and ES modules (export
). - Supports circular dependencies for CommonJS modules.
- Configurable require name.
- Adds source maps for debugging.
- Supports popular plugins like Dataview and Templater.
- Install plugin.
- Community plugins
- Install the plugin from community plugins directly.
- Manual
- Create directory
modules
under.obsidian/plugins
of your vault. - Place
manifest.json
,main.js
, andstyles.css
from the latest release into the directory.
- Create directory
- Building (latest)
- Clone this repository, including its submodules.
- Install npm.
- Run
npm install
in the root directory. - Run
npm run obsidian:install <vault directory>
in the root directory.
- Obsidian42 - BRAT (latest)
- See their readme.
- Community plugins
- Enable plugin.
- (optional) Configure plugin settings.
- Enable the plugin.
- To import a module:
// Using `require.import` is recommended.
await self.require.import("obsidian") // builtin modules such as the Obsidian API
await self.require.import("vault/path/to/a module.md") // vault path
// The following three require context and may not be able to infer the current directory. Please file an issue if so. Context inference is only available for top-level code, i.e. not inside functions or classes.
await self.require.import("../relative/path/to/a module.js") // relative path
await self.require.import("[omitted or whatever](markdown/link/to/a%20module.js.md)") // Markdown link
await self.require.import("[[wikilink/to/a module|omitted or whatever]]") // wikilink
// The following one requires enabling external links in settings.
await self.require.import("https://esm.sh/scratchblocks") // external link
// You can workaround the inability to infer the current directory.
await self.require.import("../relative/path/to/a module.js", { cwd: context.currentDirectory })
// If `await` is not supported, use `require` instead. It has less support for loading modules, however.
self.require("obsidian")
self.require("vault/path/to/a module.md")
// The following three require context and may not be able to infer the current directory. Please file an issue if so. Context inference is only available for top-level code, i.e. not inside functions or classes.
self.require("../relative/path/to/a module.js")
// The following three may not work in startup scripts.
self.require("[omitted or whatever](markdown/link/to/a%20module.js.md)")
self.require("[[wikilink/to/a module|omitted or whatever]]")
// The following one requires enabling external links and adding the link to preloaded external links in settings.
self.require("https://esm.sh/scratchblocks") // external link
// You can workaround the inability to infer the current directory.
self.require("../relative/path/to/a module.js", { cwd: context.currentDirectory })
- To use entities in a module:
const { eat, pi } = await self.require.import("[[module]]")
eat(2 * pi)
// OR
const mod = await self.require.import("[[module]]")
mod.eat(2 * mod.pi)
- To create a module, create a JavaScript or related language file or a Markdown file with JavaScript or related language code blocks.
- For
require
(but notrequire.import
), the module file needs to be preloaded, which can be configured in settings. By default, preloaded files have the following extensions:.js
,.js.md
,.mjs
,.mjs.md
,.ts.md
,.mts.md
,.ts
,.ts.md
- Modules should not have global or side effects because they are cached and thus not reloaded on every requiring.
- For Markdown files, code block languages that are loaded can be configured in settings.
- For non-JavaScript languages, ensure the module file has the correct file extension (also applies to
.xxx.md
) or prepend the following metadata:
- For
// { "language": "TypeScript" }
export const variable: string = "string"
---
module:
language: TypeScript
---
```TypeScript
export const variable: string = "string"
```
- Module exports can be CommonJS-style or ES module-style:
// ES module-style, supported by `require.import`.
export function fun() {}
export const variable = "string"
export default 42 // The default export has the name `default`.
// CommonJS-style, supported by both `require` and `require.import`.
module.exports.fun = function() {}
module.exports.variable = "string"
module.exports.default = 42
exports.abbreviatedForm = {}
- To create a startup module, export a function (supports async) to run at startup using
export default
or assigning tomodule.exports
and add the module to plugin settings:
// ES module-style
export default function() {
console.log("Hello world!")
}
// CommonJS-style
module.exports = function() {
console.log("Hello world!")
}
- The full API is available from
src/@types/obsidian-modules.ts
.
Contributions are welcome!
This project uses changesets
to manage the changelog. When creating a pull request, please add a changeset describing the changes. Add multiple changesets if your pull request changes several things. End each changeset with ([PR number](PR link) by [author username](author link))
. For example, the newly created file under the directory .changeset
should look like:
---
"example": patch
---
This is an example change. ([GH#1](https://github.com/ghost/example/pull/1) by [@ghost](https://github.com/ghost))
The todos here, ordered alphabetically, are things planned for the plugin. There are no guarantees that they will be completed. However, we are likely to accept contributions for them.
- User-defined module aliases.
- Add bare module transformation support for more CDNs such as https://cdn.jsdelivr.net.
- Faster import analysis and transformation.
- Autocomplete with JSDoc.
We hope that there will never be any security vulnerabilities, but unfortunately it does happen. Please report them!
Version | Supported |
---|---|
latest | ✅ |
outdated | ❌ |
Please report a vulnerability by opening an new issue. We will get back to you as soon as possible.