Skip to content

Allow importing page resources directly with js.Build #13840

Open
@mrled

Description

@mrled

It would be useful to be able to build JavaScript from page bundle resources via js.Build.

Currently, I can use js.Build on a single file in page bundles, but it doesn't work for files that import other files in the page bundle.

This proposal differs from #7944. This proposal suggests resolving imports from page bundles the same way that we can resolve imports from the assets directory. That earlier proposal suggests passing the page as context and using special @page tokens to reference imports, which is unique to Hugo and will break in IDEs and linters that don't understand the convention.

Thanks for your consideration.

Failing example I'm proposing to make work

For instance, in this content file:

+++
# content/blog/example/index.md
title = "Example post"
+++
<script type="module">
  import { test1 } from '{{< jsbPage "test1.ts" >}}';
  test1();
</script>

Referencing these TypeScript files as page bundle resources:

// content/blog/example/test1.js
import { test2val } from "./test2.ts";
export function test1() {
  console.log("test1.ts importing from test2:" + test2val);
}
// content/blog/example/test2.ts
export const test2val = "This is the test2 value";

With this shortcode:

{{/* layouts/shortcodes/jsbPage */}}
{{- $ts := .Page.Resources.Get (.Get 0) | js.Build (dict "format" "esm" "sourceMap" "inline") | fingerprint -}}
{{- $ts.RelPermalink -}}

I get an error:

ERROR Rebuild failed: JSBUILD: failed to transform "/blog/example/test1.ts" (text/typescript): Could not resolve "./test2.ts"

If test1.ts doesn't do any importing, it works fine.

Current workaround by using site assets instead of page assets

By contrast, if I instead place the TypeScript files under /assets, and use a shortcode to get them from there:

+++
# content/blog/example/index.md
title = "Example post"
+++
<script type="module">
  import { test1 } from '{{< jsbSite "example/test1.ts" >}}';
  test1();
</script>

Referencing these TypeScript files as page resources:

// assets/example/test1.js
import { test2val } from "./test2.ts";
export function test1() {
  console.log("test1.ts importing from test2:" + test2val);
}
// assets/example/test2.ts
export const test2val = "This is the test2 value";

With this shortcode:

{{/* layouts/shortcodes/jsbSite */}}
{{- $ts := resources.Get (.Get 0) | js.Build (dict "format" "esm" "sourceMap" "inline") | fingerprint -}}
{{- $ts.RelPermalink -}}

This works fine. The downside is that the code is not located together.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions