-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable browser / cross-platform support #18
Changes from all commits
2ebc973
597bdac
3239bc8
1f4719b
113ed72
a997b4a
f008c33
d691bab
641448b
c15f7e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
pkg/ | ||
/target | ||
/node_modules | ||
/node_modules |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/bin/bash | ||
|
||
# we need npm packages for the post-wasm phase | ||
npm install | ||
|
||
rm -rf pkg | ||
|
||
# wasm-pack knows to use wasm-opt, when present | ||
# NOTE: wasm-pack does not support multi-target building | ||
# so we'll build twice, and then tweak package.json | ||
# "exports" to point at the correct build depending on node or browser | ||
wasm-pack build --target web --out-dir pkg/standalone --weak-refs --no-pack --release | ||
wasm-pack build --target nodejs --out-dir pkg/node --weak-refs --no-pack --release | ||
|
||
# Rename the node js file to cjs, because we emit type=module | ||
mv pkg/node/content_tag.js pkg/node/content_tag.cjs | ||
|
||
# generate the rest of the package for npm, since | ||
# we disabled package.json generation above with --no-pack. | ||
# this needs to be done because we're targeting | ||
# both browser and node, which wasm-packg doesn't natively support. | ||
node ./build/post-wasm-build.mjs | ||
|
||
# --------- | ||
cp LICENSE pkg/LICENSE | ||
cp README.md pkg/README.md |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// This post-wasm-build.js script is called from build.sh | ||
import fs from "node:fs/promises"; | ||
import path from "node:path"; | ||
import url from "node:url"; | ||
import toml from "toml"; | ||
|
||
let cargo = await fs.readFile("Cargo.toml", "utf8"); | ||
let config = toml.parse(cargo); | ||
|
||
const manifest = { | ||
name: config.package.name, | ||
description: config.package.description, | ||
version: config.package.version, | ||
license: config.package.license, | ||
repository: { | ||
type: "git", | ||
url: "https://github.com/embroider-build/content-tag", | ||
}, | ||
files: ["standalone", "node"], | ||
type: "module", | ||
exports: { | ||
".": { | ||
types: "./node/content_tag.d.ts", | ||
default: "./node/content_tag.cjs", | ||
}, | ||
"./standalone": { | ||
types: "./standalone/standalone.d.ts", | ||
import: "./standalone/standalone.js", | ||
}, | ||
}, | ||
}; | ||
|
||
const content = JSON.stringify(manifest, null, 2); | ||
|
||
const here = url.fileURLToPath(new URL(".", import.meta.url)); | ||
const root = path.join(here, ".."); | ||
const output = path.join(root, "pkg"); | ||
|
||
await fs.writeFile(path.join(output, "package.json"), content); | ||
await fs.copyFile( | ||
path.join(here, "src/standalone.js"), | ||
path.join(output, "standalone/standalone.js") | ||
); | ||
await fs.copyFile( | ||
path.join(here, "src/standalone.d.ts"), | ||
path.join(output, "standalone/standalone.d.ts") | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import type { Preprocessor } from './content_tag'; | ||
|
||
export * from "./content_tag"; | ||
|
||
export function createPreprocessor(): Promise<Preprocessor>; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export * from "./content_tag.js"; | ||
|
||
import init, { Preprocessor } from "./content_tag.js"; | ||
|
||
export async function createPreprocessor() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just a tiny wrapper function since the default way rust wants us to build a wasm thing is ... goofy. Like, I get it, two things need to happen, load the wasm file and then instantiate the stuff. |
||
// This no-ops if it's already ran | ||
await init(); | ||
|
||
let processor = new Preprocessor(); | ||
|
||
return processor; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<html> | ||
|
||
<!-- View this file with `npm run web` --> | ||
|
||
<head> | ||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type" /> | ||
<script type="module"> | ||
import {createPreprocessor} from './pkg/standalone/standalone.js'; | ||
|
||
async function run() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is how I'll be using it in my REPL, tho it'll be |
||
const p = await createPreprocessor(); | ||
const output = p.process('<template>Hi from createPreprocessor</template>'); | ||
|
||
document.querySelector('#output').innerHTML = output; | ||
} | ||
|
||
run(); | ||
</script> | ||
</head> | ||
|
||
<body> | ||
<pre id="output"></pre> | ||
</body> | ||
|
||
</html> |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import chai from "chai"; | ||
import { codeEquality } from "code-equality-assertions/chai"; | ||
|
||
chai.use(codeEquality); | ||
|
||
const { expect } = chai; | ||
|
||
import { Preprocessor } from "content-tag"; | ||
const p = new Preprocessor(); | ||
|
||
describe("Node ESM", function () { | ||
it("works for a basic example", function () { | ||
let output = p.process("<template>Hi</template>"); | ||
|
||
expect(output).to | ||
.equalCode(`import { template } from "@ember/template-compiler"; | ||
export default template(\`Hi\`, { | ||
eval () { | ||
return eval(arguments[0]); | ||
} | ||
});`); | ||
}); | ||
|
||
it("Emits parse errors with anonymous file", function () { | ||
expect(function () { | ||
p.process(`const thing = "face"; | ||
<template>Hi`); | ||
}).to.throw(`Parse Error at <anon>:2:15: 2:15`); | ||
}); | ||
|
||
it("Emits parse errors with real file", function () { | ||
expect(function () { | ||
p.process( | ||
`const thing = "face"; | ||
<template>Hi`, | ||
"path/to/my/component.gjs" | ||
); | ||
}).to.throw(`Parse Error at path/to/my/component.gjs:2:15: 2:15`); | ||
}); | ||
|
||
it("Offers source_code snippet on parse errors", function () { | ||
let parseError; | ||
try { | ||
p.process(`class {`); | ||
} catch (err) { | ||
parseError = err; | ||
} | ||
expect(parseError) | ||
.to.have.property("source_code") | ||
.matches(/Expected ident.*class \{/s); | ||
}); | ||
|
||
it("Offers source_code_color snippet on parse errors", function () { | ||
let parseError; | ||
try { | ||
p.process(`class {`); | ||
} catch (err) { | ||
parseError = err; | ||
} | ||
// eslint-disable-next-line no-control-regex | ||
expect(parseError) | ||
.to.have.property("source_code_color") | ||
.matches(/Expected ident.*[\u001b].*class \{/s); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the browser wasm module:
lto = true
: 1MBopt-level = 'z'
: 741Kwee_alloc
: 741Klol_alloc
'sLockedAllocator<FreeListAllocator>
: 741Klol_alloc
'sAssumeSingleThreaded<FreeListAllocator>
: 741Klol_alloc
'sFailAllocator
: 374K (but also doesn't work 🙈 )There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a separate machine now, it seems I'm getting different results.
I had thought that the current version of the optimization settings would give
741K
, but on this machine:the browser wasm is 1.2MB...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ended up being about 1.35MB today:
Hopefully it can shrink in the future (or I can ditch more and more babel stuff / not use
@babel/standalone
, perhaps)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GH says less:
🤷 could be MiB vs MB or something.
but, 487kB isn't terrible since accuracy is what we're doing here. I can finally divide numbers before
<template>
, which is good.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note that I opted out of all the different allocators -- seemed too risky, the more I read about them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Today, tho:
with:
codegen-units = 1