Skip to content

Add web template to asinit #1996

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

Merged
merged 10 commits into from
Aug 16, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 99 additions & 40 deletions bin/asinit
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,28 @@ const asinitOptions = {
"description": "Answers all questions with their default option for non-interactive usage.",
"type": "b",
"alias": "y"
},
"web": {
"category": "General",
"description": "Adds an index.html file that can load your module. (Disables node without --node/-n flag)",
"type": "b",
"alias": "w"
},
"node": {
"category": "General",
"description": "Re-enables node files when using the --web/-w flag",
"type": "b",
"alias": "n"
}
};

const cliOptions = options.parse(process.argv.slice(2), asinitOptions);

if (cliOptions.options.help || cliOptions.arguments.length === 0) printHelp();

const useWeb = cliOptions.options.web;
const useNode = cliOptions.options.node || !useWeb;

function printHelp() {
console.log([
"Sets up a new AssemblyScript project or updates an existing one.",
Expand All @@ -80,43 +95,44 @@ const buildDir = path.join(projectDir, "build");
const testsDir = path.join(projectDir, "tests");
const gitignoreFile = path.join(buildDir, ".gitignore");
const packageFile = path.join(projectDir, "package.json");

const indexHtml = path.join(projectDir, "index.html");
const indexFile = path.join(projectDir, "index.js");
const testsIndexFile = path.join(testsDir, "index.js");

const basePaths = [
[assemblyDir, "Directory holding the AssemblyScript sources being compiled to WebAssembly."],
[tsconfigFile, "TypeScript configuration inheriting recommended AssemblyScript settings."],
[entryFile, "Example entry file being compiled to WebAssembly to get you started."],
[buildDir, "Build artifact directory where compiled WebAssembly files are stored."],
[gitignoreFile, "Git configuration that excludes compiled binaries from source control."],
[asconfigFile, "Configuration file defining both a 'debug' and a 'release' target."],
[packageFile, "Package info containing the necessary commands to compile to WebAssembly."]
];

const nodePaths = [
[indexFile, "Main file loading the WebAssembly module and exporting its exports."],
[testsIndexFile, "Example test to check that your module is indeed working."]
];

const webPaths = [
[indexHtml, "Starter HTML file that loads your module."]
];

const paths = basePaths;
if (useNode) Array.prototype.push.apply(paths, nodePaths);
if (useWeb) Array.prototype.push.apply(paths, webPaths);

const formatPath = filePath => "./" + path.relative(projectDir, filePath).replace(/\\/g, "/");

console.log([
"Version: " + version,
"",
colors.white([
"This command will make sure that the following files exist in the project",
"directory '" + projectDir + "':"
].join("\n")),
"",
colors.cyan(" ./assembly"),
" Directory holding the AssemblyScript sources being compiled to WebAssembly.",
"",
colors.cyan(" ./assembly/tsconfig.json"),
" TypeScript configuration inheriting recommended AssemblyScript settings.",
"",
colors.cyan(" ./assembly/index.ts"),
" Example entry file being compiled to WebAssembly to get you started.",
"",
colors.cyan(" ./build"),
" Build artifact directory where compiled WebAssembly files are stored.",
"",
colors.cyan(" ./build/.gitignore"),
" Git configuration that excludes compiled binaries from source control.",
"",
colors.cyan(" ./index.js"),
" Main file loading the WebAssembly module and exporting its exports.",
"",
colors.cyan(" ./tests/index.js"),
" Example test to check that your module is indeed working.",
"",
colors.cyan(" ./asconfig.json"),
" Configuration file defining both a 'debug' and a 'release' target.",
"",
colors.cyan(" ./package.json"),
" Package info containing the necessary commands to compile to WebAssembly.",
...paths.map(([filePath, description]) => "\n " + colors.cyan(formatPath(filePath)) + "\n " + description),
"",
"The command will try to update existing files to match the correct settings",
"for this instance of the compiler in '" + compilerDir + "'.",
Expand All @@ -136,10 +152,18 @@ function createProject(answer) {
ensureBuildDirectory();
ensureGitignore();
ensurePackageJson();
ensureIndexJs();
ensureTestsDirectory();
ensureTestsIndexJs();
ensureAsconfigJson();

if (useNode) {
ensureIndexJs();
ensureTestsDirectory();
ensureTestsIndexJs();
}

if (useWeb) {
ensureIndexHtml();
}

console.log([
colors.green("Done!"),
"",
Expand Down Expand Up @@ -171,10 +195,12 @@ function createProject(answer) {
" ^ The optimized WebAssembly module using default optimization settings.",
" You can change the optimization settings in '" + colors.cyan("package.json")+ "'.",
"",
"To run the tests, do:",
"",
colors.white(" " + commands[pm].test),
"",
...(useNode ? [
"To run the tests, do:",
"",
colors.white(" " + commands[pm].test),
""
] : []),
"The AssemblyScript documentation covers all the details:",
"",
" https://docs.assemblyscript.org",
Expand Down Expand Up @@ -326,11 +352,13 @@ function ensurePackageJson() {
"asbuild:untouched": buildUntouched,
"asbuild:optimized": buildOptimized,
"asbuild": buildAll,
"test": "node tests"
},
"dependencies": {
"@assemblyscript/loader": "^" + compilerVersion
...(useNode && {"test": "node tests"})
},
...(useNode && {
"dependencies": {
"@assemblyscript/loader": "^" + compilerVersion
}
}),
"devDependencies": {
"assemblyscript": "^" + compilerVersion
}
Expand All @@ -347,13 +375,13 @@ function ensurePackageJson() {
pkg["scripts"] = scripts;
updated = true;
}
if (!scripts["test"] || scripts["test"] == npmDefaultTest) {
if (!scripts["test"] || scripts["test"] == npmDefaultTest && useNode) {
scripts["test"] = "node tests";
pkg["scripts"] = scripts;
updated = true;
}
let dependencies = pkg["dependencies"] || {};
if (!dependencies["@assemblyscript/loader"]) {
if (!dependencies["@assemblyscript/loader"] && useNode) {
dependencies["@assemblyscript/loader"] = "^" + compilerVersion;
pkg["dependencies"] = dependencies;
updated = true;
Expand Down Expand Up @@ -422,3 +450,34 @@ function ensureTestsIndexJs() {
}
console.log();
}

function ensureIndexHtml() {
console.log("- Making sure that 'index.html' exists...");
if (!fs.existsSync(indexHtml)) {
fs.writeFileSync(indexHtml, [
"<!DOCTYPE html>",
"<html lang=\"en\">",
" <head>",
" <script src=\"https://cdn.jsdelivr.net/npm/@assemblyscript/loader/umd/index.js\"></script>",
" <script>",
" const imports = {",
" /* imports go here */",
" };",
"",
" loader",
" .instantiateStreaming(fetch(\"build/optimized.wasm\"), imports)",
" .then(wasmModule => {",
" const { add } = wasmModule.exports;",
" document.body.innerText = add(1, 2);",
" });",
" </script>",
" </head>",
" <body></body>",
"</html>",
].join("\n") + "\n");
console.log(colors.green(" Created: ") + indexHtml);
} else {
console.log(colors.yellow(" Exists: ") + indexHtml);
}
console.log();
}