v0.0.8
Pre-releaseThis release brings several exciting features, but the star of the show is definitely npm support!
Highlights
NPM support
You can now import packages directly from npm without needing to run npm install by importing using the npm: protocol:
import * as Preact from "npm:preact@^10.5.0";Or, if you want to work with local npm packages in a node_modules directory, you can install them as usual and then load them with either require or import:
$ npm install --save preact@^10.5.0const Preact = require("preact");Please be aware that although many npm packages will work, packages which use Node.js-specific builtins like fs, path, or vm will not function unless you shim those builtin modules via Module.define. I may include partial shims for common Node.js builtins like these in the future.
Import from http/https
You can now import modules from http/https URLs:
import * as Something from "https://something.example.com/something.js";As always, please consult the typedefs by running yavascript --print-types in order to see the documentation and type signatures of all APIs included in yavascript.
Details
Additions
- You can now import modules directly from http/https URLs. They will be fetched each time the script is evaluated. I will probably add caching options in the future.
import * as Something from "https://something.example.com/something.js";
- You can now import any npm package without installing it first, using the
npm:prefix in an import URL. For example:This feature relies on Skypack, which converts CJS into ESM in the npm packages it serves.import * as Preact from "npm:preact@^10.5.0";
- npm packages will be fetched from the Skypack cdn each time your script is evaluated. I will probably add caching options in the future.
- You can now construct Path objects with template literals by using
Path.tagand/orPath.tagUsingBase - You can now pass
{ binary: true }toreadFileto get an ArrayBuffer instead of a string - There is now preliminary support for ESM <-> CJS interop
- If code appears to assign to
exportsormodule.exports(static code analysis heuristic), then the value ofmodule.exportswill be made available as a named export named__cjsExports, and a named export named__isCjsModulewill be present which is a boolean indicating whethermodule.exportsorexportswere modified when the module was loaded. requiredetects the above situation and returnsmodule.exports.__cjsExportsinstead ofmodule.exports, when appropriate.- Import statements and dynamic import do not handle
__cjsExportsspecially. You may have to read off of__cjsExportsmanually to get the values you want, when importing CommonJS files. Or you can userequireto load them instead.
- If code appears to assign to
- The
node_modulesmodule lookup resolution algorithm is now partially supported.- The "exports" field of package.json is not yet supported. However, the "main" field is supported.
- If the package you want to import from only has an
exportsfield, you can manually reach into the package to get the file it would export, ieimport * as something from "some-package/dist/index.mjs"
- A new
yavascriptglobal is available which can be used to detect whether code is running in yavascript. This global is an object which holds information about the running yavascript binary, including version, processor architecture, etc. - The transpilation functions yavascript uses when loading coffeescript/typescript/etc are now available as
yavascript.compilers, eg. the functionyavascript.compilers.jsx. - Several functions which accept string paths now also support Path objects in those places. Not all functions have support for this yet, though. Consult
yavascript --print-typesto understand which do and which don't.
Changes
- The
isandassertAPIs have been changed significantly. Instead of various type-checking functions living as properties on bothisandassert, they are now on a newtypesglobal, and should be passed to eitheris(which is now a function instead of an object) orassert.type(which is a new function). This is a breaking change.- This new
typesglobal also has functions for making compound types, like "and", "or", etc. It's based on pheno.
- This new
- The QuickJS builtin modules
stdandosare now namespaced, and as such have been renamed toquickjs:stdandquickjs:os. You should update your imports and requires accordingly. This is a breaking change. - Several APIs will now do runtime type checks on the values they receive to ensure that you're passing, for example, a string when you need to be passing a string. This allows us to have nicer error messages when an incorrect type is passed through.
Fixes
- When running files specified via relative paths at the CLI, is no longer necessary to prefix the paths with
./or../. An unprefixed path will search in the current working directory. - The Node.js-compatibility API
process.execPathwas mistakenly usingreadlinkon the result of the QuickJSos.execPath(), when it should have been usingrealpath. This has been fixed.
Caveats
http:,https:, andnpm:imports rely oncurlbeing available in your PATH. We (safely!) shell out tocurlinstead of including network fetching code in theyavascriptbinary to keep it lean and also to ensure you can get security updates for OpenSSL and stuff without having to wait for a new version ofyavascript. If you don't havecurlinstalled on your system,http:,https:, andnpm:imports will fail.- In order to support using
importandrequireinterchangeably in any file without having to differentiate between scripts and modules, yavascript assumes all code is targeting the "module" goal. As such, strict mode is always on, and the toplevelthisvalue is alwaysundefined. This may cause some issues in some npm packages which expect to be run in non-strict mode. - Many npm packages depend on Node.js builtins like
fs,path,util, orchild_process. Those packages will not work in yavascript unless you shim those builtins by usingModule.define. At some point in the future, I may add some small shims for the most common functionality of these builtins, but full Node.js compatibility is a non-goal. - The code to support Skypack relies on the fact that Skypack's sub-dependency files all have paths prefixed with
/-/. The module loader will treat any path starting with/-/as being from Skypack. This may cause problems in the unlikely event that you have a folder named-in the root of your filesystem, because its contents will be "shadowed" by Skypack. I hope to remove this hack in the future by changing the module loader to be aware of the "current origin", like web browsers are.