Skip to content

Make loader ESM by default, with UMD fallback #1513

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 7 commits into from
Oct 22, 2020
Merged
Show file tree
Hide file tree
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
6 changes: 4 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,12 @@ module.exports = {
"bin/*"
],
rules: {
// Node's support for ESM is still not great, but this rule is likely
// to become activated once compatibility doesn't suck anymore.
// We are testing both ESM and UMD, so don't limit us.
"@typescript-eslint/no-var-requires": "off",

// This rule does not behave well in JS files.
"@typescript-eslint/explicit-module-boundary-types": "off",

// Enforcing to remove function parameters on stubs makes code less
// maintainable, so we instead allow unused function parameters.
"no-unused-vars": [
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
node node_modules/semantic-release/bin/semantic-release.js --unstable
cd lib/loader
if [ $(node -pe "require('./package.json').version") != "0.0.0" ]; then
npm run build
npm config set "//registry.npmjs.org/:_authToken=${NPM_TOKEN}"
npm publish --access public
fi
Expand Down
14 changes: 2 additions & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,11 @@ jobs:
- name: Check sources
run: npm run check
- name: Test sources
run: |
if [[ `node bin/asc --version` != *"-dev" ]]; then
echo "ERROR: Not testing sources"
exit 1
fi
npm test
run: npm test
- name: Build distribution files
run: npm run build
- name: Test distribution
run: |
if [[ `node bin/asc --version` == *"-dev" ]]; then
echo "ERROR: Not testing distribution"
exit 1
fi
npm test
run: npm test
- name: Test browser build
run: node tests/browser-asc
test-windows:
Expand Down
15 changes: 6 additions & 9 deletions cli/asc.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*
* Uses the low-level API exported from src/index.ts so it works with the compiler compiled to
* JavaScript as well as the compiler compiled to WebAssembly (eventually). Runs the sources
* directly through ts-node if distribution files are not present (indicated by a `-dev` version).
* directly through ts-node if distribution files are not present.
*
* Can also be packaged as a bundle suitable for in-browser use with the standard library injected
* in the build step. See dist/asc.js for the bundle and webpack.config.js for building details.
Expand Down Expand Up @@ -75,23 +75,23 @@ if (process.removeAllListeners) process.removeAllListeners("uncaughtException");

// Use distribution files if present, otherwise run the sources directly.
var assemblyscript;
var isDev = false;
(function loadAssemblyScript() {
try {
// note that this case will always trigger in recent node.js versions for typical installs
// see: https://nodejs.org/api/packages.html#packages_self_referencing_a_package_using_its_name
assemblyscript = require("assemblyscript");
} catch (e) {
try { // `asc` on the command line
try { // `asc` on the command line (unnecessary in recent node)
assemblyscript = dynrequire("../dist/assemblyscript.js");
} catch (e) {
try { // `asc` on the command line without dist files
try { // `asc` on the command line without dist files (unnecessary in recent node)
dynrequire("ts-node").register({
project: path.join(__dirname, "..", "src", "tsconfig.json"),
skipIgnore: true,
compilerOptions: { target: "ES2016" }
});
dynrequire("../src/glue/js");
assemblyscript = dynrequire("../src");
isDev = true;
} catch (e_ts) {
try { // `require("dist/asc.js")` in explicit browser tests
assemblyscript = dynrequire("./assemblyscript");
Expand All @@ -106,9 +106,6 @@ var isDev = false;
/** Whether this is a webpack bundle or not. */
exports.isBundle = typeof BUNDLE_VERSION === "string";

/** Whether asc runs the sources directly or not. */
exports.isDev = isDev;

/** AssemblyScript version. */
exports.version = exports.isBundle ? BUNDLE_VERSION : dynrequire("../package.json").version;

Expand Down Expand Up @@ -241,7 +238,7 @@ exports.main = function main(argv, options, callback) {

// Just print the version if requested
if (opts.version) {
stdout.write("Version " + exports.version + (isDev ? "-dev" : "") + EOL);
stdout.write("Version " + exports.version + EOL);
return callback(null);
}

Expand Down
23 changes: 10 additions & 13 deletions lib/loader/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"use strict";

// Runtime header offsets
const ID_OFFSET = -8;
const SIZE_OFFSET = -4;
Expand Down Expand Up @@ -297,7 +295,7 @@ function isModule(src) {
}

/** Asynchronously instantiates an AssemblyScript module from anything that can be instantiated. */
async function instantiate(source, imports = {}) {
export async function instantiate(source, imports = {}) {
if (isResponse(source = await source)) return instantiateStreaming(source, imports);
const module = isModule(source) ? source : await WebAssembly.compile(source);
const extended = preInstantiate(imports);
Expand All @@ -306,21 +304,17 @@ async function instantiate(source, imports = {}) {
return { module, instance, exports };
}

exports.instantiate = instantiate;

/** Synchronously instantiates an AssemblyScript module from a WebAssembly.Module or binary buffer. */
function instantiateSync(source, imports = {}) {
export function instantiateSync(source, imports = {}) {
const module = isModule(source) ? source : new WebAssembly.Module(source);
const extended = preInstantiate(imports);
const instance = new WebAssembly.Instance(module, imports);
const exports = postInstantiate(extended, instance);
return { module, instance, exports };
}

exports.instantiateSync = instantiateSync;

/** Asynchronously instantiates an AssemblyScript module from a response, i.e. as obtained by `fetch`. */
async function instantiateStreaming(source, imports = {}) {
export async function instantiateStreaming(source, imports = {}) {
if (!WebAssembly.instantiateStreaming) {
return instantiate(
isResponse(source = await source)
Expand All @@ -335,10 +329,8 @@ async function instantiateStreaming(source, imports = {}) {
return { ...result, exports };
}

exports.instantiateStreaming = instantiateStreaming;

/** Demangles an AssemblyScript module's exports to a friendly object structure. */
function demangle(exports, extendedExports = {}) {
export function demangle(exports, extendedExports = {}) {
extendedExports = Object.create(extendedExports);
const setArgumentsLength = exports["__argumentsLength"]
? length => { exports["__argumentsLength"].value = length; }
Expand Down Expand Up @@ -420,4 +412,9 @@ function demangle(exports, extendedExports = {}) {
return extendedExports;
}

exports.demangle = demangle;
export default {
instantiate,
instantiateSync,
instantiateStreaming,
demangle
};
11 changes: 10 additions & 1 deletion lib/loader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,27 @@
"bugs": {
"url": "https://github.com/AssemblyScript/assemblyscript/issues"
},
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"exports": {
"import": "./index.js",
"require": "./umd/index.js"
},
"scripts": {
"asbuild": "npm run asbuild:default && npm run asbuild:legacy",
"asbuild:default": "node ../../bin/asc tests/assembly/index.ts -b tests/build/default.wasm",
"asbuild:legacy": "node ../../bin/asc tests/assembly/index.ts --disable mutable-globals -b tests/build/legacy.wasm",
"test": "node tests"
"build": "npx esm2umd loader index.js > umd/index.js",
"test": "node tests && node tests/umd"
},
"files": [
"index.d.ts",
"index.js",
"package.json",
"umd/index.d.ts",
"umd/index.js",
"umd/package.json",
"README.md"
]
}
14 changes: 9 additions & 5 deletions lib/loader/tests/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
var fs = require("fs");
var assert = require("assert");
var inspect = require("util").inspect;

var loader = require("..");
import fs from "fs";
import assert from "assert";
import { inspect } from "util";
import loader from "../index.js";
import { dirname } from "path";
import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

test("default.wasm");
test("legacy.wasm");
Expand Down
4 changes: 4 additions & 0 deletions lib/loader/tests/umd/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const assert = require("assert");
const loader = require("../../umd");

assert(typeof loader.instantiate === "function");
3 changes: 3 additions & 0 deletions lib/loader/tests/umd/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "commonjs"
}
1 change: 1 addition & 0 deletions lib/loader/umd/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "..";
Loading