-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit c2b146a
Showing
8 changed files
with
295 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
name: Build spec | ||
|
||
on: [pull_request, push] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: ljharb/actions/node/install@main | ||
name: 'nvm install lts/* && npm install' | ||
with: | ||
node-version: lts/* | ||
- run: npm run build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: Deploy gh-pages | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
deploy: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: ljharb/actions/node/install@main | ||
name: 'nvm install lts/* && npm install' | ||
with: | ||
node-version: lts/* | ||
- run: npm run build | ||
- uses: JamesIves/[email protected] | ||
with: | ||
branch: gh-pages | ||
folder: build | ||
clean: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules | ||
jspm_packages | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Only apps should have lockfiles | ||
yarn.lock | ||
package-lock.json | ||
npm-shrinkwrap.json | ||
pnpm-lock.yaml | ||
|
||
# Build directory | ||
build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package-lock=false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2017 ECMA TC39 and contributors | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Import Sync | ||
|
||
## Status | ||
|
||
Champion: Guy Bedford | ||
Stage: -1 | ||
|
||
## Problem Statement | ||
|
||
When modules are already fully loaded into the module registry, it would be useful to support a | ||
synchronous import function to allow loading of dynamic specifier expressions in synchronous function | ||
paths. | ||
|
||
## Background | ||
|
||
As we enter the maturity stage of native ESM being adopted throughout the JS ecosystem, with features | ||
like `require(esm)` in Node.js unlocking upgrade paths for many, some remaining ergonomic issues | ||
remain on the migration path from CommonJS to ES modules. | ||
|
||
In particular CommonJS users in Node.js are used to being able to synchronously dynamically require | ||
modules, without that causing them to have to convert their codepaths to async. | ||
|
||
[Defer Import Eval](https://github.com/tc39/proposal-defer-import-eval) solves one of these issues in | ||
allowing synchronous lazy loading of modules. It does this by effectively separating the async aspects | ||
of the module loading pipeline from the sync aspects to allow a [synchronous evaluation function](https://github.com/tc39/proposal-defer-import-eval?tab=readme-ov-file#semantics) | ||
on the deferred namespace. | ||
|
||
Even with this proposal supported, there still remains a gap for dynamic lazy loading when the specifier | ||
is not known in advance, since a dynamic `import.defer(specifier)` is still an asynchronous function. | ||
|
||
Using the exact same semantics as the synchronous evaluation already defined in the Defer Import Eval | ||
proposal, we can provide an explicit hook for a synchronous import in JavaScript solving this ergonomic | ||
problem for JavaScript developers. | ||
|
||
Previously one of the major blockers in the early stages of the ESM specification to enabling a feature like this was the question of asynchronous resolution. _It has since turned out that all JS environments implement | ||
synchronous module resolution._ As a result, and given this constraint, a synchronous import is possible. | ||
|
||
## Proposal | ||
|
||
We propose to expose an explicit synchronous import function for ES modules, as a direct extension of the synchronous execution behaviour already defined by the [Defer Import Eval][] proposal: | ||
|
||
```js | ||
// synchronously import a module if it is available synchronously | ||
const ns = import.sync('./mod.js'); | ||
``` | ||
|
||
The major design of the proposal is a new `Error` which is thrown when a module is not synchronously | ||
available, or uses top-level await. | ||
|
||
Whether a module is synchronously available would otherwise be a host-determined property. | ||
|
||
## Use Cases | ||
|
||
### Getting an Already-Loaded Module | ||
|
||
On the web, if a module has already been loaded before, it can always be available synchronously. | ||
|
||
In this way `import.sync()` can behave like a registry getter function: | ||
|
||
```js | ||
import 'app'; | ||
|
||
// this will always work if 'app' has been loaded previously | ||
const app = import.sync('app'); | ||
``` | ||
|
||
### Conditional Loading | ||
|
||
Just like with dynamic import, with a synchronous import, it's possible to check if a module or builtin is available, but synchronously. | ||
|
||
For example, checking if host builtins are available: | ||
|
||
```js | ||
try { | ||
let fs = import.sync('node:fs'); | ||
} catch {} | ||
|
||
if (fs) { | ||
// Use node:fs, only if it is available | ||
} | ||
``` | ||
|
||
Or a library that conditionally binds to a framework dependency: | ||
|
||
```js | ||
let react; | ||
try { | ||
react = import.sync('react'); | ||
} catch {} | ||
|
||
if (react) { | ||
// Bind to the React framework, if available | ||
} | ||
``` | ||
|
||
### Synchronous Loading of ModuleExpressions & ModuleDeclarations | ||
|
||
Importing module expressions without TLA and async dependencies can be supported: | ||
|
||
```js | ||
// immediately logs 'hello world' | ||
import.sync(module { | ||
console.log('hello world'); | ||
}) | ||
``` | ||
|
||
Similarly for module declarations: | ||
|
||
```js | ||
module dep { | ||
console.log('hi'); | ||
} | ||
|
||
module x { | ||
import dep; | ||
} | ||
|
||
// logs 'hi', since both modules are synchronously available | ||
const instance = import.sync(x); | ||
``` | ||
|
||
## FAQ | ||
|
||
_Post an [issue](https://github.com/guybedford/proposal-import-sync/issues)._ | ||
|
||
[Defer Import Eval]: https://github.com/tc39/proposal-defer-import-eval | ||
[ESM Phase Imports]: https://github.com/tc39/proposal-esm-phase-imports |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"private": true, | ||
"name": "template-for-proposals", | ||
"description": "A repository template for ECMAScript proposals.", | ||
"scripts": { | ||
"start": "npm run build-loose -- --watch", | ||
"build": "npm run build-loose -- --strict", | ||
"build-loose": "node -e 'fs.mkdirSync(\"build\", { recursive: true })' && ecmarkup --load-biblio @tc39/ecma262-biblio --verbose spec.emu build/index.html --lint-spec" | ||
}, | ||
"homepage": "https://github.com/tc39/template-for-proposals#readme", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/tc39/template-for-proposals.git" | ||
}, | ||
"license": "MIT", | ||
"devDependencies": { | ||
"@tc39/ecma262-biblio": "^2.1.2775", | ||
"ecmarkup": "^20.0.0" | ||
}, | ||
"engines": { | ||
"node": ">= 12" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<!doctype html> | ||
<meta charset="utf8"> | ||
<link rel="stylesheet" href="./spec.css"> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css"> | ||
<script src="./spec.js"></script> | ||
<pre class="metadata"> | ||
title: Import Sync | ||
stage: -1 | ||
contributors: Guy Bedford | ||
</pre> | ||
|
||
<emu-clause id="sec-demo-clause"> | ||
<h1>This is an emu-clause</h1> | ||
<p>This is an algorithm:</p> | ||
<emu-alg> | ||
1. Let _proposal_ be *undefined*. | ||
1. If IsAccepted(_proposal_) is *true*, then | ||
1. Let _stage_ be *0*<sub>ℤ</sub>. | ||
1. Else, | ||
1. Let _stage_ be *-1*<sub>ℤ</sub>. | ||
1. Return ? ToString(_stage_). | ||
</emu-alg> | ||
</emu-clause> | ||
|
||
<emu-clause id="sec-is-accepted" type="abstract operation"> | ||
<h1> | ||
IsAccepted ( | ||
_proposal_: an ECMAScript language value | ||
): a Boolean | ||
</h1> | ||
<dl class="header"> | ||
<dt>description</dt> | ||
<dd>Tells you if the proposal was accepted</dd> | ||
</dl> | ||
<emu-alg> | ||
1. If _proposal_ is not a String, or is not accepted, return *false*. | ||
1. Return *true*. | ||
</emu-alg> | ||
</emu-clause> |